summaryrefslogtreecommitdiffstats
path: root/qtctl.c
diff options
context:
space:
mode:
authorMatthias Schiffer <mschiffer@universe-factory.net>2011-04-14 22:50:55 +0200
committerMatthias Schiffer <mschiffer@universe-factory.net>2011-04-14 22:50:55 +0200
commit45f7bf0ddba8e1b81db65fab30eca50da83e6be5 (patch)
tree3ad123b8177cb6e9ce2ff93ff612766a8ecba360 /qtctl.c
parentb476556d447c07244e71ff15d832efb19109ae29 (diff)
downloadmodquicktun-45f7bf0ddba8e1b81db65fab30eca50da83e6be5.tar
modquicktun-45f7bf0ddba8e1b81db65fab30eca50da83e6be5.zip
Implement interface configuration and deletion
Diffstat (limited to 'qtctl.c')
-rw-r--r--qtctl.c162
1 files changed, 154 insertions, 8 deletions
diff --git a/qtctl.c b/qtctl.c
index 7c3f2cf..2468846 100644
--- a/qtctl.c
+++ b/qtctl.c
@@ -1,3 +1,6 @@
+#include <stdio.h>
+#include <string.h>
+
#include <netlink/netlink.h>
#include <netlink/genl/genl.h>
#include <netlink/genl/ctrl.h>
@@ -7,21 +10,101 @@
#include "quicktun.h"
-int main()
+void usage()
+{
+ fputs("Usage: 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"
+ " qtctl del dev NAME\n", stderr);
+
+ exit(2);
+}
+
+void add(int argc, char *argv[], struct nl_handle *sock, int family)
{
- struct nl_handle *sock;
struct nl_msg *msg;
struct nl_cb *cb;
- int family;
- sock = nl_handle_alloc();
- genl_connect(sock);
- family = genl_ctrl_resolve(sock, "quicktun");
+ int p = 1;
+ uint16_t mode = QUICKTUN_MODE_ETHERNET;
+
+ char *tmp_charp;
+ struct in_addr tmp_addr;
+ unsigned long tmp_ul;
+
msg = nlmsg_alloc();
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_ECHO, QUICKTUN_CMD_CREATE_DEVICE, 1);
- nla_put_u16(msg, QUICKTUN_A_MODE, QUICKTUN_MODE_IP);
- nla_put_u32(msg, QUICKTUN_A_REMOTE_ADDRESS, inet_addr("192.168.0.2"));
+
+ while ((++p) < argc) {
+ if (!strcmp(argv[p], "dev")) {
+ if ((++p) >= argc)
+ usage();
+
+ tmp_charp = strndup(argv[p], IFNAMSIZ - 1);
+ nla_put_string(msg, QUICKTUN_A_IFNAME, tmp_charp);
+ free(tmp_charp);
+ }
+ else if (!strcmp(argv[p], "mode")) {
+ if ((++p) >= argc)
+ usage();
+
+ if (!strcmp(argv[p], "ethernet"))
+ mode = QUICKTUN_MODE_ETHERNET;
+ else if (!strcmp(argv[p], "ip"))
+ mode = QUICKTUN_MODE_IP;
+ else
+ usage();
+ }
+ else if (!strcmp(argv[p], "local_address")) {
+ if ((++p) >= argc)
+ usage();
+
+ if (!(inet_aton(argv[p], &tmp_addr)))
+ usage();
+
+ nla_put_u32(msg, QUICKTUN_A_LOCAL_ADDRESS, tmp_addr.s_addr);
+ }
+ else if (!strcmp(argv[p], "local_port")) {
+ if ((++p) >= argc)
+ usage();
+
+ tmp_ul = strtoul(argv[p], &tmp_charp, 10);
+
+ if (*tmp_charp)
+ usage();
+
+ nla_put_u16(msg, QUICKTUN_A_LOCAL_PORT, htons((short)tmp_ul));
+ }
+ else if (!strcmp(argv[p], "remote_address")) {
+ if ((++p) >= argc)
+ usage();
+
+ if (!(inet_aton(argv[p], &tmp_addr)))
+ usage();
+
+ nla_put_u32(msg, QUICKTUN_A_REMOTE_ADDRESS, tmp_addr.s_addr);
+ }
+ else if (!strcmp(argv[p], "remote_port")) {
+ if ((++p) >= argc)
+ usage();
+
+ tmp_ul = strtoul(argv[p], &tmp_charp, 10);
+
+ if (*tmp_charp)
+ usage();
+
+ nla_put_u16(msg, QUICKTUN_A_REMOTE_PORT, htons((short)tmp_ul));
+ }
+ else if (!strcmp(argv[p], "remote_float")) {
+ nla_put_flag(msg, QUICKTUN_A_REMOTE_FLOAT);
+ }
+ else
+ usage();
+ }
+
+ nla_put_u16(msg, QUICKTUN_A_MODE, mode);
nl_send_auto_complete(sock, msg);
@@ -31,6 +114,69 @@ int main()
nl_cb_err(cb, NL_CB_DEBUG, NULL, NULL);
nl_recvmsgs(sock, cb);
+}
+
+void del(int argc, char *argv[], struct nl_handle *sock, int family)
+{
+ struct nl_msg *msg;
+ struct nl_cb *cb;
+
+ int p = 1;
+ 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_DELETE_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;
+ }
+ }
+
+ if (!has_dev)
+ usage();
+
+ nl_send_auto_complete(sock, msg);
+
+ nlmsg_free(msg);
+
+ cb = nl_cb_alloc(NL_CB_DEFAULT);
+ nl_cb_err(cb, NL_CB_DEBUG, NULL, NULL);
+
+ nl_recvmsgs(sock, cb);
+}
+
+int main(int argc, char *argv[])
+{
+ struct nl_handle *sock;
+ int family;
+
+ sock = nl_handle_alloc();
+ genl_connect(sock);
+ family = genl_ctrl_resolve(sock, "quicktun");
+
+ if (argc < 2)
+ usage();
+
+ if (!strcmp(argv[1], "add"))
+ add(argc, argv, sock, family);
+ else if (!strcmp(argv[1], "del"))
+ del(argc, argv, sock, family);
+ else
+ usage();
return 0;
}