Index: head/lib/Makefile =================================================================== --- head/lib/Makefile +++ head/lib/Makefile @@ -60,7 +60,7 @@ ${_libgssapi} \ ${_librpcsec_gss} \ ${_libiconv_modules} \ - libifc \ + libifconfig \ libipsec \ libjail \ libkiconv \ Index: head/lib/libifc/Makefile =================================================================== --- head/lib/libifc/Makefile +++ head/lib/libifc/Makefile @@ -1,20 +0,0 @@ -# $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 Index: head/lib/libifc/libifc.h =================================================================== --- head/lib/libifc/libifc.h +++ head/lib/libifc/libifc.h @@ -1,111 +0,0 @@ -/* - * 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: head/lib/libifc/libifc.c =================================================================== --- head/lib/libifc/libifc.c +++ head/lib/libifc/libifc.c @@ -1,397 +0,0 @@ -/* - * 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 - -#include - -#include -#include -#include -#include -#include -#include -#include - -#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: head/lib/libifc/libifc_internal.h =================================================================== --- head/lib/libifc/libifc_internal.h +++ head/lib/libifc/libifc_internal.h @@ -1,87 +0,0 @@ -/* - * 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 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: head/lib/libifc/libifc_internal.c =================================================================== --- head/lib/libifc/libifc_internal.c +++ head/lib/libifc/libifc_internal.c @@ -1,100 +0,0 @@ -/* - * 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 - -#include -#include -#include -#include -#include - - -#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: head/lib/libifconfig/Makefile =================================================================== --- head/lib/libifconfig/Makefile +++ head/lib/libifconfig/Makefile @@ -0,0 +1,20 @@ +# $FreeBSD$ + +PACKAGE= lib${LIB} +LIB= ifconfig +# Don't build shared library, for now. +NO_PIC= + +SHLIBDIR?= /lib +SHLIB_MAJOR= 1 +SRCS= libifconfig.c libifconfig_internal.c + +INCSDIR= ${INCLUDEDIR} +INCS= libifconfig.h + +#MAN= libifconfig.3 + +CFLAGS+= -I${.CURDIR} +WARNS?=6 + +.include Index: head/lib/libifconfig/libifconfig.h =================================================================== --- head/lib/libifconfig/libifconfig.h +++ head/lib/libifconfig/libifconfig.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 +} ifconfig_errtype; + +/* + * Opaque definition so calling application can just pass a + * pointer to it for library use. + */ +struct ifconfig_handle; +typedef struct ifconfig_handle ifconfig_handle_t; + +struct ifconfig_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 + * ifconfig_handle_t *lifh = ifconfig_open(); + * + * // Do stuff with it + * + * // Dispose of the state object + * ifconfig_close(lifh); + * lifh = NULL; + *} + */ +ifconfig_handle_t *ifconfig_open(void); + +/** Frees resources held in the provided state object. + * @param h The state object to close. + * @see #ifconfig_open(void) + */ +void ifconfig_close(ifconfig_handle_t *h); + +/** Identifies what kind of error occured. */ +ifconfig_errtype ifconfig_err_errtype(ifconfig_handle_t *h); + +/** Retrieves the errno associated with the error, if any. */ +int ifconfig_err_errno(ifconfig_handle_t *h); + +/** If error type was IOCTL, this identifies which request failed. */ +unsigned long ifconfig_err_ioctlreq(ifconfig_handle_t *h); + +int ifconfig_get_description(ifconfig_handle_t *h, const char *name, + char **description); +int ifconfig_set_description(ifconfig_handle_t *h, const char *name, + const char *newdescription); +int ifconfig_unset_description(ifconfig_handle_t *h, const char *name); +int ifconfig_set_name(ifconfig_handle_t *h, const char *name, const char *newname); +int ifconfig_set_mtu(ifconfig_handle_t *h, const char *name, const int mtu); +int ifconfig_get_mtu(ifconfig_handle_t *h, const char *name, int *mtu); + +int ifconfig_set_metric(ifconfig_handle_t *h, const char *name, const int metric); +int ifconfig_get_metric(ifconfig_handle_t *h, const char *name, int *metric); + +int ifconfig_set_capability(ifconfig_handle_t *h, const char *name, + const int capability); +int ifconfig_get_capability(ifconfig_handle_t *h, const char *name, + struct ifconfig_capabilities *capability); + +/** Destroy a virtual interface + * @param name Interface to destroy + */ +int ifconfig_destroy_interface(ifconfig_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 ifconfig_create_interface(ifconfig_handle_t *h, const char *name, + char **ifname); Index: head/lib/libifconfig/libifconfig.c =================================================================== --- head/lib/libifconfig/libifconfig.c +++ head/lib/libifconfig/libifconfig.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 + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "libifconfig.h" +#include "libifconfig_internal.h" + + +ifconfig_handle_t * +ifconfig_open(void) +{ + struct ifconfig_handle *h; + + h = calloc(1, sizeof(struct ifconfig_handle)); + + for (int i = 0; i <= AF_MAX; i++) { + h->sockets[i] = -1; + } + + return (h); +} + + +void +ifconfig_close(ifconfig_handle_t *h) +{ + for (int i = 0; i <= AF_MAX; i++) { + if (h->sockets[i] != -1) { + (void)close(h->sockets[i]); + } + } + free(h); +} + + +ifconfig_errtype +ifconfig_err_errtype(ifconfig_handle_t *h) +{ + return (h->error.errtype); +} + + +int +ifconfig_err_errno(ifconfig_handle_t *h) +{ + return (h->error.errcode); +} + + +unsigned long +ifconfig_err_ioctlreq(ifconfig_handle_t *h) +{ + return (h->error.ioctl_request); +} + + +int +ifconfig_get_description(ifconfig_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 (ifconfig_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 +ifconfig_set_description(ifconfig_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 (ifconfig_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 (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR, &ifr) != 0) { + free(ifr.ifr_buffer.buffer); + return (-1); + } + free(ifr.ifr_buffer.buffer); + return (0); +} + + +int ifconfig_unset_description(ifconfig_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 (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR, &ifr) < 0) { + return (-1); + } + return (0); +} + + +int ifconfig_set_name(ifconfig_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 (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFNAME, &ifr) != 0) { + free(tmpname); + return (-1); + } + free(tmpname); + return (0); +} + + +int ifconfig_set_mtu(ifconfig_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 (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMTU, &ifr) < 0) { + return (-1); + } + return (0); +} + + +int ifconfig_get_mtu(ifconfig_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 (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFMTU, &ifr) == -1) { + return (-1); + } + *mtu = ifr.ifr_mtu; + return (0); +} + + +int ifconfig_set_metric(ifconfig_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 (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMETRIC, &ifr) < 0) { + return (-1); + } + return (0); +} + + +int ifconfig_get_metric(ifconfig_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 (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFMETRIC, &ifr) == -1) { + return (-1); + } + *metric = ifr.ifr_metric; + return (0); +} + + +int ifconfig_set_capability(ifconfig_handle_t *h, const char *name, + const int capability) +{ + struct ifreq ifr; + struct ifconfig_capabilities ifcap; + int flags; + int value; + + memset(&ifr, 0, sizeof(struct ifreq)); + if (ifconfig_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 (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFCAP, &ifr) < 0) { + return (-1); + } + return (0); +} + + +int ifconfig_get_capability(ifconfig_handle_t *h, const char *name, + struct ifconfig_capabilities *capability) +{ + struct ifreq ifr; + + memset(&ifr, 0, sizeof(struct ifreq)); + (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFCAP, &ifr) < 0) { + return (-1); + } + capability->curcap = ifr.ifr_curcap; + capability->reqcap = ifr.ifr_reqcap; + return (0); +} + + +int ifconfig_destroy_interface(ifconfig_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 (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCIFDESTROY, &ifr) < 0) { + return (-1); + } + return (0); +} + + +int ifconfig_create_interface(ifconfig_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 (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCIFCREATE2, &ifr) < 0) { + return (-1); + } + *ifname = strdup(ifr.ifr_name); + return (0); +} Index: head/lib/libifconfig/libifconfig_internal.h =================================================================== --- head/lib/libifconfig/libifconfig_internal.h +++ head/lib/libifconfig/libifconfig_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 "libifconfig.h" + + +struct errstate { + /** + * Type of error. + */ + ifconfig_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 ifconfig_handle { + struct errstate error; + int sockets[AF_MAX + 1]; +}; + +/** + * Retrieves socket for address family 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 (ifconfig_socket(AF_LOCAL, &s) != 0) \{ + * // Handle error state here + * \} + * // user code here + * \} + * } + * } + */ +int ifconfig_socket(ifconfig_handle_t *h, const int addressfamily, int *s); + +/** Function used by other wrapper functions to populate _errstate when appropriate.*/ +int ifconfig_ioctlwrap_ret(ifconfig_handle_t *h, unsigned long request, int rcode); + +/** Function to wrap ioctl() and automatically populate ifconfig_errstate when appropriate.*/ +int ifconfig_ioctlwrap(ifconfig_handle_t *h, const int addressfamily, + unsigned long request, struct ifreq *ifr); Index: head/lib/libifconfig/libifconfig_internal.c =================================================================== --- head/lib/libifconfig/libifconfig_internal.c +++ head/lib/libifconfig/libifconfig_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 + +#include +#include +#include +#include +#include + + +#include "libifconfig.h" // Needed for ifconfig_errstate +#include "libifconfig_internal.h" + +int +ifconfig_ioctlwrap_ret(ifconfig_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 +ifconfig_ioctlwrap(ifconfig_handle_t *h, const int addressfamily, + unsigned long request, struct ifreq *ifr) +{ + int s; + + if (ifconfig_socket(h, addressfamily, &s) != 0) { + return (-1); + } + + int rcode = ioctl(s, request, ifr); + return (ifconfig_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 ifconfig_socket(ifconfig_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: head/share/examples/libifc/Makefile =================================================================== --- head/share/examples/libifc/Makefile +++ head/share/examples/libifc/Makefile @@ -1,9 +0,0 @@ -# $FreeBSD$ - -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: head/share/examples/libifc/ifcreate.c =================================================================== --- head/share/examples/libifc/ifcreate.c +++ head/share/examples/libifc/ifcreate.c @@ -1,93 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include - - -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: head/share/examples/libifc/ifdestroy.c =================================================================== --- head/share/examples/libifc/ifdestroy.c +++ head/share/examples/libifc/ifdestroy.c @@ -1,87 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include - - -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: head/share/examples/libifc/setdescription.c =================================================================== --- head/share/examples/libifc/setdescription.c +++ head/share/examples/libifc/setdescription.c @@ -1,91 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include - - -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: head/share/examples/libifc/setmtu.c =================================================================== --- head/share/examples/libifc/setmtu.c +++ head/share/examples/libifc/setmtu.c @@ -1,94 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include - - -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: head/share/examples/libifconfig/Makefile =================================================================== --- head/share/examples/libifconfig/Makefile +++ head/share/examples/libifconfig/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ +default: + $(CC) -Wall -fPIC -lifconfig -g -o example_setdescription setdescription.c + $(CC) -Wall -fPIC -lifconfig -g -o example_setmtu setmtu.c + $(CC) -Wall -fPIC -lifconfig -g -o example_ifdestroy ifdestroy.c + $(CC) -Wall -fPIC -lifconfig -g -o example_ifcreate ifcreate.c +clean: + rm -f example_* Index: head/share/examples/libifconfig/ifcreate.c =================================================================== --- head/share/examples/libifconfig/ifcreate.c +++ head/share/examples/libifconfig/ifcreate.c @@ -0,0 +1,93 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + + +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); + + ifconfig_handle_t *lifh = ifconfig_open(); + if (ifconfig_create_interface(lifh, ifname, &ifactualname) == 0) { + printf("Successfully created interface '%s'\n", ifactualname); + ifconfig_close(lifh); + lifh = NULL; + free(ifname); + free(ifactualname); + return (0); + } else { + switch (ifconfig_err_errtype(lifh)) { + case SOCKET: + warnx("couldn't create socket. This shouldn't happen.\n"); + break; + case IOCTL: + if (ifconfig_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", ifconfig_err_errno( + lifh)); + break; + } + + ifconfig_close(lifh); + lifh = NULL; + free(ifname); + free(ifactualname); + return (-1); + } +} Index: head/share/examples/libifconfig/ifdestroy.c =================================================================== --- head/share/examples/libifconfig/ifdestroy.c +++ head/share/examples/libifconfig/ifdestroy.c @@ -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$ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +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); + + ifconfig_handle_t *lifh = ifconfig_open(); + if (ifconfig_destroy_interface(lifh, ifname) == 0) { + printf("Successfully destroyed interface '%s'.", ifname); + ifconfig_close(lifh); + lifh = NULL; + free(ifname); + return (0); + } else { + switch (ifconfig_err_errtype(lifh)) { + case SOCKET: + warnx("couldn't create socket. This shouldn't happen.\n"); + break; + case IOCTL: + if (ifconfig_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; + } + + ifconfig_close(lifh); + lifh = NULL; + free(ifname); + return (-1); + } +} Index: head/share/examples/libifconfig/setdescription.c =================================================================== --- head/share/examples/libifconfig/setdescription.c +++ head/share/examples/libifconfig/setdescription.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. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include + + +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); + + ifconfig_handle_t *lifh = ifconfig_open(); + if (ifconfig_get_description(lifh, ifname, &curdescr) == 0) { + printf("Old description: %s\n", curdescr); + } + + printf("New description: %s\n\n", ifdescr); + + if (ifconfig_set_description(lifh, ifname, ifdescr) == 0) { + printf("New description successfully set.\n"); + } else { + switch (ifconfig_err_errtype(lifh)) { + case SOCKET: + err(ifconfig_err_errno(lifh), "Socket error"); + break; + case IOCTL: + err(ifconfig_err_errno( + lifh), "IOCTL(%lu) error", + ifconfig_err_ioctlreq(lifh)); + break; + case OTHER: + err(ifconfig_err_errno(lifh), "Other error"); + break; + } + } + + free(ifname); + free(ifdescr); + free(curdescr); + ifname = NULL; + ifdescr = NULL; + curdescr = NULL; + + ifconfig_close(lifh); + return (0); +} Index: head/share/examples/libifconfig/setmtu.c =================================================================== --- head/share/examples/libifconfig/setmtu.c +++ head/share/examples/libifconfig/setmtu.c @@ -0,0 +1,94 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include + + +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); + + ifconfig_handle_t *lifh = ifconfig_open(); + if (ifconfig_set_mtu(lifh, ifname, mtu) == 0) { + printf("Successfully changed MTU of %s to %d\n", ifname, mtu); + ifconfig_close(lifh); + lifh = NULL; + free(ifname); + return (0); + } else { + switch (ifconfig_err_errtype(lifh)) { + case SOCKET: + warnx("couldn't create socket. This shouldn't happen.\n"); + break; + case IOCTL: + if (ifconfig_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", + ifconfig_err_ioctlreq(lifh), + ifconfig_err_errno(lifh)); + } + break; + default: + warnx( + "Should basically never end up here in this example.\n"); + break; + } + + ifconfig_close(lifh); + lifh = NULL; + free(ifname); + return (-1); + } +} Index: head/share/mk/bsd.libnames.mk =================================================================== --- head/share/mk/bsd.libnames.mk +++ head/share/mk/bsd.libnames.mk @@ -82,7 +82,7 @@ LIBIBSDP?= ${DESTDIR}${LIBDIR}/libibsdp.a LIBIBUMAD?= ${DESTDIR}${LIBDIR}/libibumad.a LIBIBVERBS?= ${DESTDIR}${LIBDIR}/libibverbs.a -LIBIFC?= ${DESTDIR}${LIBDIR}/libifc.a +LIBIFCONFIG?= ${DESTDIR}${LIBDIR}/libifconfig.a LIBIPSEC?= ${DESTDIR}${LIBDIR}/libipsec.a LIBJAIL?= ${DESTDIR}${LIBDIR}/libjail.a LIBKADM5CLNT?= ${DESTDIR}${LIBDIR}/libkadm5clnt.a Index: head/share/mk/src.libnames.mk =================================================================== --- head/share/mk/src.libnames.mk +++ head/share/mk/src.libnames.mk @@ -105,7 +105,7 @@ heimntlm \ heimsqlite \ hx509 \ - ifc \ + ifconfig \ ipsec \ jail \ kadm5clnt \