summaryrefslogtreecommitdiffstats
path: root/qtctl.c
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2011-04-25 04:38:19 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2011-04-25 04:38:19 +0200
commit50f98aec98d066129b932e53bf33eef64896938f (patch)
treed4dcf5577ad982b08a65a9c9f3115a2cb0342e1a /qtctl.c
parent814e3c10474fd28840d5fcbbb9224b396807cbb2 (diff)
downloadmodquicktun-50f98aec98d066129b932e53bf33eef64896938f.tar
modquicktun-50f98aec98d066129b932e53bf33eef64896938f.zip
Implemented tunnel list command
Diffstat (limited to 'qtctl.c')
-rw-r--r--qtctl.c120
1 files changed, 107 insertions, 13 deletions
diff --git a/qtctl.c b/qtctl.c
index 2468846..9a0708d 100644
--- a/qtctl.c
+++ b/qtctl.c
@@ -10,9 +10,10 @@
#include "quicktun.h"
-void usage()
+static void usage()
{
- fputs("Usage: qtctl add [ dev NAME ] [ mode { ethernet | ip } ]\n"
+ fputs("Usage: qtctl show [dev NAME]\n"
+ " qtctl add [ dev NAME ] [ mode { ethernet | ip } ]\n"
" [ local_address ADDRESS ] [ local_port PORT ]\n"
" [ remote_address ADDRESS ] [ remote_port PORT ]\n"
" [ remote_float ]\n"
@@ -21,12 +22,18 @@ void usage()
exit(2);
}
-void add(int argc, char *argv[], struct nl_handle *sock, int family)
+static int print_error(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg)
+{
+ fprintf(stderr, "Error received: %s\n", strerror(-nlerr->error));
+ exit(1);
+}
+
+static void add(int argc, char *argv[], struct nl_handle *sock, int family)
{
struct nl_msg *msg;
struct nl_cb *cb;
- int p = 1;
+ int p = 0;
uint16_t mode = QUICKTUN_MODE_ETHERNET;
char *tmp_charp;
@@ -111,17 +118,17 @@ void add(int argc, char *argv[], struct nl_handle *sock, int family)
nlmsg_free(msg);
cb = nl_cb_alloc(NL_CB_DEFAULT);
- nl_cb_err(cb, NL_CB_DEBUG, NULL, NULL);
+ nl_cb_err(cb, NL_CB_CUSTOM, print_error, NULL);
nl_recvmsgs(sock, cb);
}
-void del(int argc, char *argv[], struct nl_handle *sock, int family)
+static void del(int argc, char *argv[], struct nl_handle *sock, int family)
{
struct nl_msg *msg;
struct nl_cb *cb;
- int p = 1;
+ int p = 0;
char *tmp_charp;
int has_dev = 0;
@@ -154,7 +161,87 @@ void del(int argc, char *argv[], struct nl_handle *sock, int family)
nlmsg_free(msg);
cb = nl_cb_alloc(NL_CB_DEFAULT);
- nl_cb_err(cb, NL_CB_DEBUG, NULL, NULL);
+ nl_cb_err(cb, NL_CB_CUSTOM, print_error, NULL);
+
+ nl_recvmsgs(sock, cb);
+}
+
+static int show_callback(struct nl_msg *msg, void *arg)
+{
+ struct nlmsghdr *nlh = nlmsg_hdr(msg);
+ struct genlmsghdr *ghdr;
+ struct nlattr *pos, *pos2;
+ struct nlattr *nested[__QUICKTUN_A_MAX];
+ struct in_addr addr;
+ int rem;
+
+ if (!genlmsg_valid_hdr(nlh, 0)) {
+ fputs("Received invalid data from kernel.", stderr);
+ exit(1);
+ }
+
+ ghdr = nlmsg_data(nlh);
+
+ if (ghdr->cmd != QUICKTUN_CMD_GET_DEVICE)
+ return NL_OK;
+
+ nla_for_each_attr(pos, genlmsg_attrdata(ghdr, 0), genlmsg_len(ghdr), rem) {
+ nla_parse_nested(nested, QUICKTUN_A_MAX, pos, NULL);
+
+ if(!nested[QUICKTUN_A_IFNAME] || !nested[QUICKTUN_A_MODE] || !nested[QUICKTUN_A_LOCAL_ADDRESS] || !nested[QUICKTUN_A_LOCAL_PORT]
+ || !nested[QUICKTUN_A_REMOTE_ADDRESS] || !nested[QUICKTUN_A_REMOTE_PORT])
+ continue;
+
+ printf("%s: %s ", nla_get_string(nested[QUICKTUN_A_IFNAME]), (nla_get_u16(nested[QUICKTUN_A_MODE]) == QUICKTUN_MODE_ETHERNET) ? "ethernet" : (nla_get_u16(nested[QUICKTUN_A_MODE]) == QUICKTUN_MODE_IP) ? "ip" : "unknown" );
+
+ addr.s_addr = nla_get_u32(nested[QUICKTUN_A_LOCAL_ADDRESS]);
+ printf("local %s:%u ", inet_ntoa(addr), ntohs(nla_get_u16(nested[QUICKTUN_A_LOCAL_PORT])));
+
+ addr.s_addr = nla_get_u32(nested[QUICKTUN_A_REMOTE_ADDRESS]);
+ printf("remote %s:%u ", inet_ntoa(addr), ntohs(nla_get_u16(nested[QUICKTUN_A_REMOTE_PORT])));
+
+ printf("remote_float %s\n", nla_get_flag(nested[QUICKTUN_A_REMOTE_FLOAT]) ? "on" : "off");
+ }
+
+ return NL_STOP;
+}
+
+static void show(int argc, char *argv[], struct nl_handle *sock, int family)
+{
+ struct nl_msg *msg;
+ struct nl_cb *cb;
+
+ int p = 0;
+ char *tmp_charp;
+
+ int has_dev = 0;
+
+ msg = nlmsg_alloc();
+ genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_ECHO, QUICKTUN_CMD_GET_DEVICE, 1);
+
+ while ((++p) < argc) {
+ if (!strcmp(argv[p], "dev")) {
+ if ((++p) >= argc)
+ usage();
+
+ if (has_dev)
+ usage();
+
+ tmp_charp = strndup(argv[p], IFNAMSIZ - 1);
+ nla_put_string(msg, QUICKTUN_A_IFNAME, tmp_charp);
+ free(tmp_charp);
+
+ has_dev = 1;
+ }
+ }
+
+ nl_send_auto_complete(sock, msg);
+
+ nlmsg_free(msg);
+
+ cb = nl_cb_alloc(NL_CB_DEFAULT);
+ nl_cb_set (cb, NL_CB_VALID, NL_CB_CUSTOM, show_callback, NULL);
+ nl_cb_err(cb, NL_CB_CUSTOM, print_error, NULL);
nl_recvmsgs(sock, cb);
}
@@ -166,15 +253,22 @@ int main(int argc, char *argv[])
sock = nl_handle_alloc();
genl_connect(sock);
+
family = genl_ctrl_resolve(sock, "quicktun");
+ if (family < 0) {
+ fputs("Your kernel doesn't support Quicktun.\n", stderr);
+ exit(1);
+ }
- if (argc < 2)
- usage();
- if (!strcmp(argv[1], "add"))
- add(argc, argv, sock, family);
+ if (argc < 2)
+ show(argc, argv, sock, family);
+ else if (!strcmp(argv[1], "add"))
+ add(argc-1, argv+1, sock, family);
else if (!strcmp(argv[1], "del"))
- del(argc, argv, sock, family);
+ del(argc-1, argv+1, sock, family);
+ else if (!strcmp(argv[1], "show"))
+ show(argc-1, argv+1, sock, family);
else
usage();