Page MenuHomeFreeBSD

D7529.id19687.diff
No OneTemporary

D7529.id19687.diff

Index: lib/Makefile
===================================================================
--- lib/Makefile
+++ lib/Makefile
@@ -60,6 +60,7 @@
${_libgssapi} \
${_librpcsec_gss} \
${_libiconv_modules} \
+ libifc \
libipsec \
libjail \
libkiconv \
Index: lib/libifc/Makefile
===================================================================
--- lib/libifc/Makefile
+++ lib/libifc/Makefile
@@ -0,0 +1,20 @@
+# $FreeBSD$
+
+PACKAGE= lib${LIB}
+LIB= ifc
+# Don't build shared library, for now.
+NO_PIC=
+
+SHLIBDIR?= /lib
+SHLIB_MAJOR= 1
+SRCS= libifc.c libifc_internal.c
+
+INCSDIR= ${INCLUDEDIR}
+INCS= libifc.h
+
+#MAN= libifco.3
+
+CFLAGS+= -I${.CURDIR}
+WARNS?=6
+
+.include <bsd.lib.mk>
Index: lib/libifc/libifc.h
===================================================================
--- lib/libifc/libifc.h
+++ lib/libifc/libifc.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016, Marie Helene Kvello-Aune
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * thislist of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#pragma once
+
+typedef enum {
+ OTHER, IOCTL, SOCKET
+} libifc_errtype;
+
+/*
+ * Opaque definition so calling application can just pass a
+ * pointer to it for library use.
+ */
+struct libifc_handle;
+typedef struct libifc_handle libifc_handle_t;
+
+struct libifc_capabilities {
+ /** Current capabilities (ifconfig prints this as 'options')*/
+ int curcap;
+ /** Requested capabilities (ifconfig prints this as 'capabilities')*/
+ int reqcap;
+};
+
+
+/** Retrieves a new state object for use in other API calls.
+ * Example usage:
+ *{@code
+ * // Create state object
+ * libifc_handle_t *lifh = libifc_open();
+ *
+ * // Do stuff with it
+ *
+ * // Dispose of the state object
+ * libifc_close(lifh);
+ * lifh = NULL;
+ *}
+ */
+libifc_handle_t *libifc_open(void);
+
+/** Frees resources held in the provided state object.
+ * @param h The state object to close.
+ * @see #libifc_open(void)
+ */
+void libifc_close(libifc_handle_t *h);
+
+/** Identifies what kind of error occured. */
+libifc_errtype libifc_err_errtype(libifc_handle_t *h);
+
+/** Retrieves the errno associated with the error, if any. */
+int libifc_err_errno(libifc_handle_t *h);
+
+/** If error type was IOCTL, this identifies which request failed. */
+unsigned long libifc_err_ioctlreq(libifc_handle_t *h);
+
+int libifc_get_description(libifc_handle_t *h, const char *name,
+ char **description);
+int libifc_set_description(libifc_handle_t *h, const char *name,
+ const char *newdescription);
+int libifc_unset_description(libifc_handle_t *h, const char *name);
+int libifc_set_name(libifc_handle_t *h, const char *name, const char *newname);
+int libifc_set_mtu(libifc_handle_t *h, const char *name, const int mtu);
+int libifc_get_mtu(libifc_handle_t *h, const char *name, int *mtu);
+
+int libifc_set_metric(libifc_handle_t *h, const char *name, const int metric);
+int libifc_get_metric(libifc_handle_t *h, const char *name, int *metric);
+
+int libifc_set_capability(libifc_handle_t *h, const char *name,
+ const int capability);
+int libifc_get_capability(libifc_handle_t *h, const char *name,
+ struct libifc_capabilities *capability);
+
+/** Destroy a virtual interface
+ * @param name Interface to destroy
+ */
+int libifc_destroy_interface(libifc_handle_t *h, const char *name);
+
+/** Creates a (virtual) interface
+ * @param name Name of interface to create. Example: bridge or bridge42
+ * @param name ifname Is set to actual name of created interface
+ */
+int libifc_create_interface(libifc_handle_t *h, const char *name,
+ char **ifname);
Index: lib/libifc/libifc.c
===================================================================
--- lib/libifc/libifc.c
+++ lib/libifc/libifc.c
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 2016, Marie Helene Kvello-Aune
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * thislist of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "libifc.h"
+#include "libifc_internal.h"
+
+
+libifc_handle_t *
+libifc_open(void)
+{
+ struct libifc_handle *h;
+
+ h = calloc(1, sizeof(struct libifc_handle));
+
+ for (int i = 0; i <= AF_MAX; i++) {
+ h->sockets[i] = -1;
+ }
+
+ return (h);
+}
+
+
+void
+libifc_close(libifc_handle_t *h)
+{
+ for (int i = 0; i <= AF_MAX; i++) {
+ if (h->sockets[i] != -1) {
+ (void)close(h->sockets[i]);
+ }
+ }
+ free(h);
+}
+
+
+libifc_errtype
+libifc_err_errtype(libifc_handle_t *h)
+{
+ return (h->error.errtype);
+}
+
+
+int
+libifc_err_errno(libifc_handle_t *h)
+{
+ return (h->error.errcode);
+}
+
+
+unsigned long
+libifc_err_ioctlreq(libifc_handle_t *h)
+{
+ return (h->error.ioctl_request);
+}
+
+
+int
+libifc_get_description(libifc_handle_t *h, const char *name, char **description)
+{
+ struct ifreq ifr;
+ char *descr = NULL;
+ size_t descrlen = 64;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ for (;;) {
+ if ((descr = reallocf(descr, descrlen)) == NULL) {
+ h->error.errtype = OTHER;
+ h->error.errcode = ENOMEM;
+ return (-1);
+ }
+
+ ifr.ifr_buffer.buffer = descr;
+ ifr.ifr_buffer.length = descrlen;
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCGIFDESCR,
+ &ifr) != 0) {
+ return (-1);
+ }
+
+ if (ifr.ifr_buffer.buffer == descr) {
+ if (strlen(descr) > 0) {
+ *description = strdup(descr);
+ free(descr);
+ return (0);
+ }
+ } else if (ifr.ifr_buffer.length > descrlen) {
+ descrlen = ifr.ifr_buffer.length;
+ continue;
+ }
+ break;
+ }
+ free(descr);
+ h->error.errtype = OTHER;
+ h->error.errcode = 0;
+ return (-1);
+}
+
+
+int
+libifc_set_description(libifc_handle_t *h, const char *name,
+ const char *newdescription)
+{
+ struct ifreq ifr;
+ int desclen;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ desclen = strlen(newdescription);
+
+ /*
+ * Unset description if the new description is 0 characters long.
+ * TODO: Decide whether this should be an error condition instead.
+ */
+ if (desclen == 0) {
+ return (libifc_unset_description(h, name));
+ }
+
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+
+ ifr.ifr_buffer.length = desclen + 1;
+ ifr.ifr_buffer.buffer = strdup(newdescription);
+ if (ifr.ifr_buffer.buffer == NULL) {
+ h->error.errtype = OTHER;
+ h->error.errcode = ENOMEM;
+ return (-1);
+ }
+
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR, &ifr) != 0) {
+ free(ifr.ifr_buffer.buffer);
+ return (-1);
+ }
+ free(ifr.ifr_buffer.buffer);
+ return (0);
+}
+
+
+int libifc_unset_description(libifc_handle_t *h, const char *name)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ ifr.ifr_buffer.length = 0;
+ ifr.ifr_buffer.buffer = NULL;
+
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR, &ifr) < 0) {
+ return (-1);
+ }
+ return (0);
+}
+
+
+int libifc_set_name(libifc_handle_t *h, const char *name, const char *newname)
+{
+ struct ifreq ifr;
+ char *tmpname;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ tmpname = strdup(newname);
+ if (tmpname == NULL) {
+ h->error.errtype = OTHER;
+ h->error.errcode = ENOMEM;
+ return (-1);
+ }
+
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ ifr.ifr_data = tmpname;
+
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCSIFNAME, &ifr) != 0) {
+ free(tmpname);
+ return (-1);
+ }
+ free(tmpname);
+ return (0);
+}
+
+
+int libifc_set_mtu(libifc_handle_t *h, const char *name, const int mtu)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ ifr.ifr_mtu = mtu;
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCSIFMTU, &ifr) < 0) {
+ return (-1);
+ }
+ return (0);
+}
+
+
+int libifc_get_mtu(libifc_handle_t *h, const char *name, int *mtu)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCGIFMTU, &ifr) == -1) {
+ return (-1);
+ }
+ *mtu = ifr.ifr_mtu;
+ return (0);
+}
+
+
+int libifc_set_metric(libifc_handle_t *h, const char *name, const int mtu)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ ifr.ifr_mtu = mtu;
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCSIFMETRIC, &ifr) < 0) {
+ return (-1);
+ }
+ return (0);
+}
+
+
+int libifc_get_metric(libifc_handle_t *h, const char *name, int *metric)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCGIFMETRIC, &ifr) == -1) {
+ return (-1);
+ }
+ *metric = ifr.ifr_metric;
+ return (0);
+}
+
+
+int libifc_set_capability(libifc_handle_t *h, const char *name,
+ const int capability)
+{
+ struct ifreq ifr;
+ struct libifc_capabilities ifcap;
+ int flags;
+ int value;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ if (libifc_get_capability(h, name, &ifcap) != 0) {
+ return (-1);
+ }
+
+ value = capability;
+ flags = ifcap.curcap;
+ if (value < 0) {
+ value = -value;
+ flags &= ~value;
+ } else {
+ flags |= value;
+ }
+ flags &= ifcap.reqcap;
+
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+
+ /*
+ * TODO: Verify that it's safe to not have ifr.ifr_curcap
+ * set for this request.
+ */
+ ifr.ifr_reqcap = flags;
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCSIFCAP, &ifr) < 0) {
+ return (-1);
+ }
+ return (0);
+}
+
+
+int libifc_get_capability(libifc_handle_t *h, const char *name,
+ struct libifc_capabilities *capability)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCGIFCAP, &ifr) < 0) {
+ return (-1);
+ }
+ capability->curcap = ifr.ifr_curcap;
+ capability->reqcap = ifr.ifr_reqcap;
+ return (0);
+}
+
+
+int libifc_destroy_interface(libifc_handle_t *h, const char *name)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCIFDESTROY, &ifr) < 0) {
+ return (-1);
+ }
+ return (0);
+}
+
+
+int libifc_create_interface(libifc_handle_t *h, const char *name, char **ifname)
+{
+ struct ifreq ifr;
+
+ memset(&ifr, 0, sizeof(struct ifreq));
+ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
+
+ /*
+ * TODO:
+ * Insert special snowflake handling here. See GitHub issue #12 for details.
+ * In the meantime, hard-nosupport interfaces that need special handling.
+ */
+ if ((strncmp(name, "wlan", strlen("wlan")) == 0) ||
+ (strncmp(name, "vlan", strlen("vlan")) == 0) ||
+ (strncmp(name, "vxlan", strlen("vxlan")) == 0)) {
+ h->error.errtype = OTHER;
+ h->error.errcode = ENOSYS;
+ return (-1);
+ }
+
+ /* No special handling for this interface type. */
+
+ if (libifc_ioctlwrap(h, AF_LOCAL, SIOCIFCREATE2, &ifr) < 0) {
+ return (-1);
+ }
+ *ifname = strdup(ifr.ifr_name);
+ return (0);
+}
Index: lib/libifc/libifc_internal.h
===================================================================
--- lib/libifc/libifc_internal.h
+++ lib/libifc/libifc_internal.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2016, Marie Helene Kvello-Aune
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * thislist of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#pragma once
+
+#include "libifc.h"
+
+
+struct errstate {
+ /**
+ * Type of error.
+ */
+ libifc_errtype errtype;
+
+ /**
+ * The error occured in this ioctl() request.
+ * Populated if errtype = IOCTL
+ */
+ unsigned long ioctl_request;
+
+ /**
+ * The value of the global errno variable when the error occured.
+ */
+ int errcode;
+};
+
+struct libifc_handle {
+ struct errstate error;
+ int sockets[AF_MAX + 1];
+};
+
+/**
+ * Retrieves socket for address family <paramref name="addressfamily"> from
+ * cache, or creates it if it doesn't already exist.
+ * @param addressfamily The address family of the socket to retrieve
+ * @param s The retrieved socket.
+ * @return 0 on success, -1 on failure.
+ * {@example
+ * This example shows how to retrieve a socket from the cache.
+ * {@code
+ * static void myfunc() \{
+ * int s;
+ * if (libifc_socket(AF_LOCAL, &s) != 0) \{
+ * // Handle error state here
+ * \}
+ * // user code here
+ * \}
+ * }
+ * }
+ */
+int libifc_socket(libifc_handle_t *h, const int addressfamily, int *s);
+
+/** Function used by other wrapper functions to populate _errstate when appropriate.*/
+int libifc_ioctlwrap_ret(libifc_handle_t *h, unsigned long request, int rcode);
+
+/** Function to wrap ioctl() and automatically populate libifc_errstate when appropriate.*/
+int libifc_ioctlwrap(libifc_handle_t *h, const int addressfamily,
+ unsigned long request, struct ifreq *ifr);
Index: lib/libifc/libifc_internal.c
===================================================================
--- lib/libifc/libifc_internal.c
+++ lib/libifc/libifc_internal.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2016, Marie Helene Kvello-Aune
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * thislist of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+
+#include <net/if.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+
+
+#include "libifc.h" // Needed for libifc_errstate
+#include "libifc_internal.h"
+
+int
+libifc_ioctlwrap_ret(libifc_handle_t *h, unsigned long request, int rcode)
+{
+ if (rcode != 0) {
+ h->error.errtype = IOCTL;
+ h->error.ioctl_request = request;
+ h->error.errcode = errno;
+ }
+ return (rcode);
+}
+
+
+int
+libifc_ioctlwrap(libifc_handle_t *h, const int addressfamily,
+ unsigned long request, struct ifreq *ifr)
+{
+ int s;
+
+ if (libifc_socket(h, addressfamily, &s) != 0) {
+ return (-1);
+ }
+
+ int rcode = ioctl(s, request, ifr);
+ return (libifc_ioctlwrap_ret(h, request, rcode));
+}
+
+
+/*
+ * Function to get socket for the specified address family.
+ * If the socket doesn't already exist, attempt to create it.
+ */
+int libifc_socket(libifc_handle_t *h, const int addressfamily, int *s)
+{
+ if (addressfamily > AF_MAX) {
+ h->error.errtype = SOCKET;
+ h->error.errcode = EINVAL;
+ return (-1);
+ }
+
+ if (h->sockets[addressfamily] != -1) {
+ *s = h->sockets[addressfamily];
+ return (0);
+ }
+
+ /* We don't have a socket of that type available. Create one. */
+ h->sockets[addressfamily] = socket(addressfamily, SOCK_DGRAM, 0);
+ if (h->sockets[addressfamily] == -1) {
+ h->error.errtype = SOCKET;
+ h->error.errcode = errno;
+ return (-1);
+ }
+
+ *s = h->sockets[addressfamily];
+ return (0);
+}
Index: share/examples/libifc/Makefile
===================================================================
--- share/examples/libifc/Makefile
+++ share/examples/libifc/Makefile
@@ -0,0 +1,7 @@
+default:
+ $(CC) -Wall -fPIC -lifc -g -o example_setdescription setdescription.c
+ $(CC) -Wall -fPIC -lifc -g -o example_setmtu setmtu.c
+ $(CC) -Wall -fPIC -lifc -g -o example_ifdestroy ifdestroy.c
+ $(CC) -Wall -fPIC -lifc -g -o example_ifcreate ifcreate.c
+clean:
+ rm -f example_*
Index: share/examples/libifc/ifcreate.c
===================================================================
--- share/examples/libifc/ifcreate.c
+++ share/examples/libifc/ifcreate.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2016, Marie Helene Kvello-Aune
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * thislist of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libifc.h>
+
+
+int main(int argc, char *argv[])
+{
+ if (argc != 2) {
+ errx(EINVAL, "Invalid number of arguments."
+ " Only one argument is accepted, and it should be the name"
+ " of the interface to be created.");
+ }
+
+ char *ifname, *ifactualname;
+
+ /* We have a static number of arguments. Therefore we can do it simple. */
+ ifname = strdup(argv[1]);
+
+ printf("Requested interface name: %s\n", ifname);
+
+ libifc_handle_t *lifh = libifc_open();
+ if (libifc_create_interface(lifh, ifname, &ifactualname) == 0) {
+ printf("Successfully created interface '%s'\n", ifactualname);
+ libifc_close(lifh);
+ lifh = NULL;
+ free(ifname);
+ free(ifactualname);
+ return (0);
+ } else {
+ switch (libifc_err_errtype(lifh)) {
+ case SOCKET:
+ warnx("couldn't create socket. This shouldn't happen.\n");
+ break;
+ case IOCTL:
+ if (libifc_err_ioctlreq(lifh) == SIOCIFCREATE2) {
+ warnx(
+ "Failed to create interface (SIOCIFCREATE2)\n");
+ }
+ break;
+ default:
+ warnx(
+ "This is a thorough example accommodating for temporary"
+ " 'not implemented yet' errors. That's likely what happened"
+ " now. If not, your guess is as good as mine. ;)"
+ " Error code: %d\n", libifc_err_errno(
+ lifh));
+ break;
+ }
+
+ libifc_close(lifh);
+ lifh = NULL;
+ free(ifname);
+ free(ifactualname);
+ return (-1);
+ }
+}
Index: share/examples/libifc/ifdestroy.c
===================================================================
--- share/examples/libifc/ifdestroy.c
+++ share/examples/libifc/ifdestroy.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2016, Marie Helene Kvello-Aune
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * thislist of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libifc.h>
+
+
+int main(int argc, char *argv[])
+{
+ if (argc != 2) {
+ errx(EINVAL, "Invalid number of arguments."
+ " Only one argument is accepted, and it should be the name"
+ " of the interface to be destroyed.");
+ }
+
+ char *ifname;
+
+ /* We have a static number of arguments. Therefore we can do it simple. */
+ ifname = strdup(argv[1]);
+
+ printf("Interface name: %s\n", ifname);
+
+ libifc_handle_t *lifh = libifc_open();
+ if (libifc_destroy_interface(lifh, ifname) == 0) {
+ printf("Successfully destroyed interface '%s'.", ifname);
+ libifc_close(lifh);
+ lifh = NULL;
+ free(ifname);
+ return (0);
+ } else {
+ switch (libifc_err_errtype(lifh)) {
+ case SOCKET:
+ warnx("couldn't create socket. This shouldn't happen.\n");
+ break;
+ case IOCTL:
+ if (libifc_err_ioctlreq(lifh) == SIOCIFDESTROY) {
+ warnx(
+ "Failed to destroy interface (SIOCIFDESTROY)\n");
+ }
+ break;
+ default:
+ warnx(
+ "Should basically never end up here in this example.\n");
+ break;
+ }
+
+ libifc_close(lifh);
+ lifh = NULL;
+ free(ifname);
+ return (-1);
+ }
+}
Index: share/examples/libifc/setdescription.c
===================================================================
--- share/examples/libifc/setdescription.c
+++ share/examples/libifc/setdescription.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2016, Marie Helene Kvello-Aune
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * thislist of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libifc.h>
+
+
+int main(int argc, char *argv[])
+{
+ if (argc != 3) {
+ errx(EINVAL, "Invalid number of arguments."
+ " First argument should be interface name, second argument"
+ " should be the description to set.");
+ }
+
+ char *ifname, *ifdescr, *curdescr;
+ /* We have a static number of arguments. Therefore we can do it simple. */
+ ifname = strdup(argv[1]);
+ ifdescr = strdup(argv[2]);
+ curdescr = NULL;
+
+ printf("Interface name: %s\n", ifname);
+
+ libifc_handle_t *lifh = libifc_open();
+ if (libifc_get_description(lifh, ifname, &curdescr) == 0) {
+ printf("Old description: %s\n", curdescr);
+ }
+
+ printf("New description: %s\n\n", ifdescr);
+
+ if (libifc_set_description(lifh, ifname, ifdescr) == 0) {
+ printf("New description successfully set.\n");
+ } else {
+ switch (libifc_err_errtype(lifh)) {
+ case SOCKET:
+ err(libifc_err_errno(lifh), "Socket error");
+ break;
+ case IOCTL:
+ err(libifc_err_errno(
+ lifh), "IOCTL(%lu) error",
+ libifc_err_ioctlreq(lifh));
+ break;
+ case OTHER:
+ err(libifc_err_errno(lifh), "Other error");
+ break;
+ }
+ }
+
+ free(ifname);
+ free(ifdescr);
+ free(curdescr);
+ ifname = NULL;
+ ifdescr = NULL;
+ curdescr = NULL;
+
+ libifc_close(lifh);
+ return (0);
+}
Index: share/examples/libifc/setmtu.c
===================================================================
--- share/examples/libifc/setmtu.c
+++ share/examples/libifc/setmtu.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016, Marie Helene Kvello-Aune
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * thislist of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its contributors
+ * may be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <err.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <libifc.h>
+
+
+int main(int argc, char *argv[])
+{
+ if (argc != 3) {
+ errx(EINVAL, "Invalid number of arguments."
+ " First argument should be interface name, second argument"
+ " should be the MTU to set.");
+ }
+
+ char *ifname, *ptr;
+ int mtu;
+
+ /* We have a static number of arguments. Therefore we can do it simple. */
+ ifname = strdup(argv[1]);
+ mtu = (int)strtol(argv[2], &ptr, 10);
+
+ printf("Interface name: %s\n", ifname);
+ printf("New MTU: %d", mtu);
+
+ libifc_handle_t *lifh = libifc_open();
+ if (libifc_set_mtu(lifh, ifname, mtu) == 0) {
+ printf("Successfully changed MTU of %s to %d\n", ifname, mtu);
+ libifc_close(lifh);
+ lifh = NULL;
+ free(ifname);
+ return (0);
+ } else {
+ switch (libifc_err_errtype(lifh)) {
+ case SOCKET:
+ warnx("couldn't create socket. This shouldn't happen.\n");
+ break;
+ case IOCTL:
+ if (libifc_err_ioctlreq(lifh) == SIOCSIFMTU) {
+ warnx("Failed to set MTU (SIOCSIFMTU)\n");
+ } else {
+ warnx(
+ "Failed to set MTU due to error in unexpected ioctl() call %lu. Error code: %i.\n",
+ libifc_err_ioctlreq(lifh),
+ libifc_err_errno(lifh));
+ }
+ break;
+ default:
+ warnx(
+ "Should basically never end up here in this example.\n");
+ break;
+ }
+
+ libifc_close(lifh);
+ lifh = NULL;
+ free(ifname);
+ return (-1);
+ }
+}
Index: share/mk/bsd.libnames.mk
===================================================================
--- share/mk/bsd.libnames.mk
+++ share/mk/bsd.libnames.mk
@@ -82,6 +82,7 @@
LIBIBSDP?= ${DESTDIR}${LIBDIR}/libibsdp.a
LIBIBUMAD?= ${DESTDIR}${LIBDIR}/libibumad.a
LIBIBVERBS?= ${DESTDIR}${LIBDIR}/libibverbs.a
+LIBIFC?= ${DESTDIR}${LIBDIR}/libifc.a
LIBIPSEC?= ${DESTDIR}${LIBDIR}/libipsec.a
LIBJAIL?= ${DESTDIR}${LIBDIR}/libjail.a
LIBKADM5CLNT?= ${DESTDIR}${LIBDIR}/libkadm5clnt.a
Index: share/mk/src.libnames.mk
===================================================================
--- share/mk/src.libnames.mk
+++ share/mk/src.libnames.mk
@@ -105,6 +105,7 @@
heimntlm \
heimsqlite \
hx509 \
+ ifc \
ipsec \
jail \
kadm5clnt \

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 26, 3:10 PM (11 m, 38 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26217113
Default Alt Text
D7529.id19687.diff (35 KB)

Event Timeline