Index: lib/libifconfig/Makefile =================================================================== --- lib/libifconfig/Makefile +++ lib/libifconfig/Makefile @@ -3,8 +3,6 @@ PACKAGE= lib${LIB} LIB= ifconfig PRIVATELIB= true -# Don't build shared library, for now. -NO_PIC= SHLIBDIR?= /lib SHLIB_MAJOR= 1 Index: lib/libifconfig/libifconfig.h =================================================================== --- lib/libifconfig/libifconfig.h +++ lib/libifconfig/libifconfig.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Marie Helene Kvello-Aune + * Copyright (c) 2016-2017, Marie Helene Kvello-Aune * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -50,9 +50,13 @@ * Example usage: *{@code * // Create state object - * ifconfig_handle_t *lifh = ifconfig_open(); + * ifconfig_handle_t *lifh; + * lifh = ifconfig_open(); + * if (lifh == NULL) { + * // Handle error + * } * - * // Do stuff with it + * // Do stuff with the handle * * // Dispose of the state object * ifconfig_close(lifh); @@ -103,3 +107,15 @@ */ int ifconfig_create_interface(ifconfig_handle_t *h, const char *name, char **ifname); + +/** Creates a (virtual) interface + * @param name Name of interface to create. Example: vlan0 or ix0.50 + * @param name ifname Is set to actual name of created interface + * @param vlandev Name of interface to attach to + * @param vlanid VLAN ID/Tag. Must not be 0. + */ +int ifconfig_create_interface_vlan(ifconfig_handle_t *h, const char *name, + char **ifname, const char *vlandev, const unsigned short vlantag); + +int ifconfig_set_vlantag(ifconfig_handle_t *h, const char *name, + const char *vlandev, const unsigned short vlantag); Index: lib/libifconfig/libifconfig.c =================================================================== --- lib/libifconfig/libifconfig.c +++ lib/libifconfig/libifconfig.c @@ -1,38 +1,7 @@ /* - * 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. + * Copyright (c) 2016-2017, 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 @@ -73,19 +42,27 @@ #include #include +#include + #include "libifconfig.h" #include "libifconfig_internal.h" +#define NOTAG ((u_short) -1) ifconfig_handle_t * ifconfig_open(void) { - struct ifconfig_handle *h; + ifconfig_handle_t *h; h = calloc(1, sizeof(*h)); + + if (h == NULL) { + return (NULL); + } for (int i = 0; i <= AF_MAX; i++) { h->sockets[i] = -1; } + return (h); } @@ -145,6 +122,7 @@ ifr.ifr_buffer.buffer = descr; ifr.ifr_buffer.length = descrlen; if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFDESCR, &ifr) != 0) { + free(descr); return (-1); } @@ -152,6 +130,13 @@ if (strlen(descr) > 0) { *description = strdup(descr); free(descr); + + if (description == NULL) { + h->error.errtype = OTHER; + h->error.errcode = ENOMEM; + return (-1); + } + return (0); } } else if (ifr.ifr_buffer.length > descrlen) { @@ -194,8 +179,7 @@ return (-1); } - if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR, - &ifr) != 0) { + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR, &ifr) != 0) { free(ifr.ifr_buffer.buffer); return (-1); } @@ -214,8 +198,7 @@ ifr.ifr_buffer.length = 0; ifr.ifr_buffer.buffer = NULL; - if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR, - &ifr) < 0) { + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFDESCR, &ifr) < 0) { return (-1); } return (0); @@ -237,8 +220,7 @@ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_data = tmpname; - if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFNAME, - &ifr) != 0) { + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFNAME, &ifr) != 0) { free(tmpname); return (-1); } @@ -256,8 +238,7 @@ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_mtu = mtu; - if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMTU, - &ifr) < 0) { + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMTU, &ifr) < 0) { return (-1); } @@ -272,8 +253,7 @@ memset(&ifr, 0, sizeof(ifr)); (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); - if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFMTU, - &ifr) == -1) { + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFMTU, &ifr) == -1) { return (-1); } @@ -290,8 +270,7 @@ (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); ifr.ifr_mtu = mtu; - if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMETRIC, - &ifr) < 0) { + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMETRIC, &ifr) < 0) { return (-1); } @@ -306,8 +285,7 @@ memset(&ifr, 0, sizeof(ifr)); (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); - if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFMETRIC, - &ifr) == -1) { + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFMETRIC, &ifr) == -1) { return (-1); } @@ -325,8 +303,7 @@ memset(&ifr, 0, sizeof(ifr)); - if (ifconfig_get_capability(h, name, - &ifcap) != 0) { + if (ifconfig_get_capability(h, name, &ifcap) != 0) { return (-1); } @@ -347,8 +324,7 @@ * set for this request. */ ifr.ifr_reqcap = flags; - if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFCAP, - &ifr) < 0) { + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFCAP, &ifr) < 0) { return (-1); } return (0); @@ -363,8 +339,7 @@ memset(&ifr, 0, sizeof(ifr)); (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); - if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFCAP, - &ifr) < 0) { + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFCAP, &ifr) < 0) { return (-1); } capability->curcap = ifr.ifr_curcap; @@ -380,8 +355,7 @@ memset(&ifr, 0, sizeof(ifr)); (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); - if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCIFDESTROY, - &ifr) < 0) { + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCIFDESTROY, &ifr) < 0) { return (-1); } return (0); @@ -393,6 +367,7 @@ struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); + (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); /* @@ -417,5 +392,57 @@ } *ifname = strdup(ifr.ifr_name); + if (ifname == NULL) { + h->error.errtype = OTHER; + h->error.errcode = ENOMEM; + return (-1); + } + + return (0); +} + +int +ifconfig_create_interface_vlan(ifconfig_handle_t *h, const char *name, + char **ifname, const char *vlandev, const unsigned short vlantag) +{ + struct ifreq ifr; + struct vlanreq params; + + if ((vlantag == NOTAG) || (vlandev[0] == '\0')) { + // TODO: Add proper error tracking here + return (-1); + } + + bzero(¶ms, sizeof(params)); + (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + params.vlr_tag = vlantag; + (void)strlcpy(params.vlr_parent, vlandev, sizeof(params.vlr_parent)); + ifr.ifr_data = (caddr_t)¶ms; + + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCIFCREATE2, &ifr) < 0) { + // TODO: Add proper error tracking here + return (-1); + } + + *ifname = strdup(ifr.ifr_name); + return (0); +} + +int +ifconfig_set_vlantag(ifconfig_handle_t *h, const char *name, + const char *vlandev, const unsigned short vlantag) +{ + struct ifreq ifr; + struct vlanreq params; + + bzero(¶ms, sizeof(params)); + params.vlr_tag = vlantag; + strlcpy(params.vlr_parent, vlandev, sizeof(params.vlr_parent)); + + ifr.ifr_data = (caddr_t)¶ms; + (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSETVLAN, &ifr) == -1) { + return (-1); + } return (0); } Index: lib/libifconfig/libifconfig_internal.h =================================================================== --- lib/libifconfig/libifconfig_internal.h +++ lib/libifconfig/libifconfig_internal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Marie Helene Kvello-Aune + * Copyright (c) 2016-2017, Marie Helene Kvello-Aune * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -75,10 +75,6 @@ */ 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: lib/libifconfig/libifconfig_internal.c =================================================================== --- lib/libifconfig/libifconfig_internal.c +++ lib/libifconfig/libifconfig_internal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, Marie Helene Kvello-Aune + * Copyright (c) 2016-2017, Marie Helene Kvello-Aune * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, @@ -38,20 +38,6 @@ #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) @@ -62,8 +48,14 @@ return (-1); } - int rcode = ioctl(s, request, ifr); - return (ifconfig_ioctlwrap_ret(h, request, rcode)); + if (ioctl(s, request, ifr) != 0) { + h->error.errtype = IOCTL; + h->error.ioctl_request = request; + h->error.errcode = errno; + return (-1); + } + + return (0); } /*