aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/contrib
diff options
context:
space:
mode:
authorJason A. Donenfeld <Jason@zx2c4.com>2018-02-21 02:53:06 +0100
committerJason A. Donenfeld <Jason@zx2c4.com>2018-02-21 02:53:06 +0100
commit295c9ff274f489b3eaec8c4e342938eef864f769 (patch)
tree64aa843d406282d8dfa567e593105a4c8d071a2e /contrib
parentwg: fixup errno handling (diff)
downloadwireguard-tools-295c9ff274f489b3eaec8c4e342938eef864f769.tar.xz
wireguard-tools-295c9ff274f489b3eaec8c4e342938eef864f769.zip
contrib: embedded-wg-library: add ability to add and del interfaces
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'contrib')
-rw-r--r--contrib/embeddable-wg-library/test.c39
-rw-r--r--contrib/embeddable-wg-library/wireguard.c71
-rw-r--r--contrib/embeddable-wg-library/wireguard.h2
3 files changed, 109 insertions, 3 deletions
diff --git a/contrib/embeddable-wg-library/test.c b/contrib/embeddable-wg-library/test.c
index b738481..aad24de 100644
--- a/contrib/embeddable-wg-library/test.c
+++ b/contrib/embeddable-wg-library/test.c
@@ -8,7 +8,7 @@
#include <string.h>
#include <stdlib.h>
-int main(int argc, char *argv[])
+void list_devices(void)
{
char *device_names, *device_name;
size_t len;
@@ -16,7 +16,7 @@ int main(int argc, char *argv[])
device_names = wg_list_device_names();
if (!device_names) {
perror("Unable to get device names");
- return 1;
+ exit(1);
}
wg_for_each_device_name(device_names, device_name, len) {
wg_device *device;
@@ -36,5 +36,40 @@ int main(int argc, char *argv[])
wg_free_device(device);
}
free(device_names);
+}
+
+int main(int argc, char *argv[])
+{
+ wg_peer new_peer = {
+ .flags = WGPEER_HAS_PUBLIC_KEY | WGPEER_REPLACE_ALLOWEDIPS
+ };
+ wg_device new_device = {
+ .name = "wgtest0",
+ .listen_port = 1234,
+ .flags = WGDEVICE_HAS_PRIVATE_KEY | WGDEVICE_HAS_LISTEN_PORT,
+ .first_peer = &new_peer,
+ .last_peer = &new_peer
+ };
+
+ wg_key_from_base64(new_device.private_key, "SFLKy56SOiFoAvQDSCBRrH/nyYonuAQnyr/JTQRPDlU=");
+ wg_key_from_base64(new_peer.public_key, "aNoLvvCfgbtTf4f2Eb/CWVNvIc5AJt/4C4pKrxMUZlM=");
+
+ if (wg_add_device(new_device.name) < 0) {
+ perror("Unable to add device");
+ exit(1);
+ }
+
+ if (wg_set_device(&new_device) < 0) {
+ perror("Unable to set device");
+ exit(1);
+ }
+
+ list_devices();
+
+ if (wg_del_device(new_device.name) < 0) {
+ perror("Unable to delete device");
+ exit(1);
+ }
+
return 0;
}
diff --git a/contrib/embeddable-wg-library/wireguard.c b/contrib/embeddable-wg-library/wireguard.c
index a7b25de..692d285 100644
--- a/contrib/embeddable-wg-library/wireguard.c
+++ b/contrib/embeddable-wg-library/wireguard.c
@@ -910,7 +910,7 @@ static int parse_linkinfo(const struct nlattr *attr, void *data)
{
struct inflatable_buffer *buffer = data;
- if (mnl_attr_get_type(attr) == IFLA_INFO_KIND && !strcmp("wireguard", mnl_attr_get_str(attr)))
+ if (mnl_attr_get_type(attr) == IFLA_INFO_KIND && !strcmp(WG_GENL_NAME, mnl_attr_get_str(attr)))
buffer->good = true;
return MNL_CB_OK;
}
@@ -1006,6 +1006,65 @@ cleanup:
return ret;
}
+static int add_del_iface(const char *ifname, bool add)
+{
+ struct mnl_socket *nl = NULL;
+ char *rtnl_buffer;
+ ssize_t len;
+ int ret;
+ struct nlmsghdr *nlh;
+ struct ifinfomsg *ifm;
+ struct nlattr *nest;
+
+ rtnl_buffer = calloc(MNL_SOCKET_BUFFER_SIZE, 1);
+ if (!rtnl_buffer) {
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+
+ nl = mnl_socket_open(NETLINK_ROUTE);
+ if (!nl) {
+ ret = -errno;
+ goto cleanup;
+ }
+
+ if (mnl_socket_bind(nl, 0, MNL_SOCKET_AUTOPID) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+
+ nlh = mnl_nlmsg_put_header(rtnl_buffer);
+ nlh->nlmsg_type = add ? RTM_NEWLINK : RTM_DELLINK;
+ nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | (add ? NLM_F_CREATE | NLM_F_EXCL : 0);
+ nlh->nlmsg_seq = time(NULL);
+ ifm = mnl_nlmsg_put_extra_header(nlh, sizeof(*ifm));
+ ifm->ifi_family = AF_UNSPEC;
+ mnl_attr_put_strz(nlh, IFLA_IFNAME, ifname);
+ nest = mnl_attr_nest_start(nlh, IFLA_LINKINFO);
+ mnl_attr_put_strz(nlh, IFLA_INFO_KIND, WG_GENL_NAME);
+ mnl_attr_nest_end(nlh, nest);
+
+ if (mnl_socket_sendto(nl, rtnl_buffer, nlh->nlmsg_len) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+ if ((len = mnl_socket_recvfrom(nl, rtnl_buffer, MNL_SOCKET_BUFFER_SIZE)) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+ if (mnl_cb_run(rtnl_buffer, len, nlh->nlmsg_seq, mnl_socket_get_portid(nl), NULL, NULL) < 0) {
+ ret = -errno;
+ goto cleanup;
+ }
+ ret = 0;
+
+cleanup:
+ free(rtnl_buffer);
+ if (nl)
+ mnl_socket_close(nl);
+ return ret;
+}
+
int wg_set_device(wg_device *dev)
{
int ret = 0;
@@ -1424,6 +1483,16 @@ err:
return buffer.buffer;
}
+int wg_add_device(const char *device_name)
+{
+ return add_del_iface(device_name, true);
+}
+
+int wg_del_device(const char *device_name)
+{
+ return add_del_iface(device_name, false);
+}
+
void wg_free_device(wg_device *dev)
{
wg_peer *peer, *np;
diff --git a/contrib/embeddable-wg-library/wireguard.h b/contrib/embeddable-wg-library/wireguard.h
index 514ede1..350de7d 100644
--- a/contrib/embeddable-wg-library/wireguard.h
+++ b/contrib/embeddable-wg-library/wireguard.h
@@ -83,6 +83,8 @@ typedef struct wg_device {
int wg_set_device(wg_device *dev);
int wg_get_device(wg_device **dev, const char *device_name);
+int wg_add_device(const char *device_name);
+int wg_del_device(const char *device_name);
void wg_free_device(wg_device *dev);
char *wg_list_device_names(void); /* first\0second\0third\0forth\0last\0\0 */
void wg_key_to_base64(wg_key_b64_string base64, const wg_key key);