From owner-svn-src-all@freebsd.org Fri Feb 23 14:47:17 2018 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 1CF8DF27C94; Fri, 23 Feb 2018 14:47:17 +0000 (UTC) (envelope-from freebsd@pdx.rh.CN85.dnsmgr.net) Received: from pdx.rh.CN85.dnsmgr.net (br1.CN84in.dnsmgr.net [69.59.192.140]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 784CF837C2; Fri, 23 Feb 2018 14:47:14 +0000 (UTC) (envelope-from freebsd@pdx.rh.CN85.dnsmgr.net) Received: from pdx.rh.CN85.dnsmgr.net (localhost [127.0.0.1]) by pdx.rh.CN85.dnsmgr.net (8.13.3/8.13.3) with ESMTP id w1NEl5WQ096145; Fri, 23 Feb 2018 06:47:05 -0800 (PST) (envelope-from freebsd@pdx.rh.CN85.dnsmgr.net) Received: (from freebsd@localhost) by pdx.rh.CN85.dnsmgr.net (8.13.3/8.13.3/Submit) id w1NEl58N096144; Fri, 23 Feb 2018 06:47:05 -0800 (PST) (envelope-from freebsd) From: "Rodney W. Grimes" Message-Id: <201802231447.w1NEl58N096144@pdx.rh.CN85.dnsmgr.net> Subject: Re: svn commit: r329853 - in head: lib/libifconfig share/examples/libifconfig usr.sbin/wlandebug In-Reply-To: <201802230311.w1N3BhiJ023939@repo.freebsd.org> To: Alan Somers Date: Fri, 23 Feb 2018 06:47:05 -0800 (PST) CC: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Reply-To: rgrimes@freebsd.org X-Mailer: ELM [version 2.4ME+ PL121h (25)] MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset=US-ASCII X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.25 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 23 Feb 2018 14:47:17 -0000 > Author: asomers > Date: Fri Feb 23 03:11:43 2018 > New Revision: 329853 > URL: https://svnweb.freebsd.org/changeset/base/329853 > > Log: > libifconfig: multiple feature additions > > Added the ability to: > > * Create virtual interfaces > * Create vlan interfaces > * Get interface fib > * Get interface groups > * Get interface status > * Get nd6 info > * Get media status > * Get additional ifaddr info in a convenient struct > * Get vhids > * Get carp info > * Get lagg and laggport status > * Iterate over all interfaces and ifaddrs Love that list!!! > > And add more examples, too. Remove MIT 1996 Copyright? Under what conditions is it that this is being done? > Note that this is a backwards-incompatible change. But that's ok, because it's > a private library. > > MFC after: 3 weeks > Sponsored by: Spectra Logic Corp > Differential Revision: https://reviews.freebsd.org/D14463 With 0 feed back? And a ~30 hour life time? It is not a diffential if no one looks at, comments on, or accepts the revision. > Added: > head/lib/libifconfig/libifconfig_carp.c (contents, props changed) > head/lib/libifconfig/libifconfig_inet.c (contents, props changed) > head/lib/libifconfig/libifconfig_inet6.c (contents, props changed) > head/lib/libifconfig/libifconfig_lagg.c (contents, props changed) > head/lib/libifconfig/libifconfig_media.c (contents, props changed) > head/share/examples/libifconfig/ifchangevlan.c (contents, props changed) > head/share/examples/libifconfig/ifcreatevlan.c (contents, props changed) > head/share/examples/libifconfig/status.c (contents, props changed) > Modified: > head/lib/libifconfig/Makefile > head/lib/libifconfig/libifconfig.c > head/lib/libifconfig/libifconfig.h > head/lib/libifconfig/libifconfig_internal.c > head/lib/libifconfig/libifconfig_internal.h > head/share/examples/libifconfig/Makefile > head/share/examples/libifconfig/ifcreate.c > head/share/examples/libifconfig/ifdestroy.c > head/share/examples/libifconfig/setdescription.c > head/share/examples/libifconfig/setmtu.c > head/usr.sbin/wlandebug/wlandebug.c > > Modified: head/lib/libifconfig/Makefile > ============================================================================== > --- head/lib/libifconfig/Makefile Fri Feb 23 02:53:50 2018 (r329852) > +++ head/lib/libifconfig/Makefile Fri Feb 23 03:11:43 2018 (r329853) > @@ -8,7 +8,9 @@ NO_PIC= > > SHLIBDIR?= /lib > SHLIB_MAJOR= 1 > -SRCS= libifconfig.c libifconfig_internal.c > +SRCS= libifconfig.c libifconfig_carp.c libifconfig_inet.c > +SRCS+= libifconfig_inet6.c libifconfig_internal.c libifconfig_lagg.c > +SRCS+= libifconfig_media.c > > INCSDIR= ${INCLUDEDIR} > INCS= libifconfig.h > @@ -16,6 +18,6 @@ INCS= libifconfig.h > #MAN= libifconfig.3 > > CFLAGS+= -I${.CURDIR} > -WARNS?=6 > +NO_WCAST_ALIGN= yes > > .include > > Modified: head/lib/libifconfig/libifconfig.c > ============================================================================== > --- head/lib/libifconfig/libifconfig.c Fri Feb 23 02:53:50 2018 (r329852) > +++ head/lib/libifconfig/libifconfig.c Fri Feb 23 03:11:43 2018 (r329853) > @@ -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 > @@ -61,65 +30,63 @@ > * $FreeBSD$ > */ > > - /* > - * Copyright 1996 Massachusetts Institute of Technology > - * > - * Permission to use, copy, modify, and distribute this software and > - * its documentation for any purpose and without fee is hereby > - * granted, provided that both the above copyright notice and this > - * permission notice appear in all copies, that both the above > - * copyright notice and this permission notice appear in all > - * supporting documentation, and that the name of M.I.T. not be used > - * in advertising or publicity pertaining to distribution of the > - * software without specific, written prior permission. M.I.T. makes > - * no representations about the suitability of this software for any > - * purpose. It is provided "as is" without express or implied > - * warranty. > - * > - * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS > - * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, > - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT > - * SHALL M.I.T. 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 > > #include > #include > #include > +#include > +#include > #include > #include > #include > #include > > +#include > + > #include "libifconfig.h" > #include "libifconfig_internal.h" > > +#define NOTAG ((u_short) -1) > > +static bool > +isnd6defif(ifconfig_handle_t *h, const char *name) > +{ > + struct in6_ndifreq ndifreq; > + unsigned int ifindex; > + > + memset(&ndifreq, 0, sizeof(ndifreq)); > + strlcpy(ndifreq.ifname, name, sizeof(ndifreq.ifname)); > + ifindex = if_nametoindex(ndifreq.ifname); > + if (ifconfig_ioctlwrap(h, AF_INET6, SIOCGDEFIFACE_IN6, &ndifreq) < 0) { > + return (false); > + } > + h->error.errtype = OK; > + return (ndifreq.ifindex == ifindex); > +} > + > 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); > } > > @@ -132,6 +99,7 @@ ifconfig_close(ifconfig_handle_t *h) > (void)close(h->sockets[i]); > } > } > + freeifaddrs(h->ifap); > free(h); > } > > @@ -157,6 +125,46 @@ ifconfig_err_ioctlreq(ifconfig_handle_t *h) > } > > int > +ifconfig_foreach_iface(ifconfig_handle_t *h, > + ifconfig_foreach_func_t cb, void *udata) > +{ > + int ret; > + > + ret = ifconfig_getifaddrs(h); > + if (ret == 0) { > + struct ifaddrs *ifa; > + char *ifname = NULL; > + > + for (ifa = h->ifap; ifa; ifa = ifa->ifa_next) { > + if (ifname != ifa->ifa_name) { > + ifname = ifa->ifa_name; > + cb(h, ifa, udata); > + } > + } > + } > + /* Free ifaddrs so we don't accidentally cache stale data */ > + freeifaddrs(h->ifap); > + h->ifap = NULL; > + > + return (ret); > +} > + > +void > +ifconfig_foreach_ifaddr(ifconfig_handle_t *h, struct ifaddrs *ifa, > + ifconfig_foreach_func_t cb, void *udata) > +{ > + struct ifaddrs *ift; > + > + for (ift = ifa; > + ift != NULL && > + ift->ifa_addr != NULL && > + strcmp(ift->ifa_name, ifa->ifa_name) == 0; > + ift = ift->ifa_next) { > + cb(h, ift, udata); > + } > +} > + > +int > ifconfig_get_description(ifconfig_handle_t *h, const char *name, > char **description) > { > @@ -179,6 +187,7 @@ ifconfig_get_description(ifconfig_handle_t *h, const c > ifr.ifr_buffer.buffer = descr; > ifr.ifr_buffer.length = descrlen; > if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFDESCR, &ifr) != 0) { > + free(descr); > return (-1); > } > > @@ -186,6 +195,13 @@ ifconfig_get_description(ifconfig_handle_t *h, const c > 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) { > @@ -228,8 +244,7 @@ ifconfig_set_description(ifconfig_handle_t *h, const c > 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); > } > @@ -248,8 +263,7 @@ ifconfig_unset_description(ifconfig_handle_t *h, const > 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); > @@ -271,8 +285,7 @@ ifconfig_set_name(ifconfig_handle_t *h, const char *na > > (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); > } > @@ -285,61 +298,60 @@ int > ifconfig_get_orig_name(ifconfig_handle_t *h, const char *ifname, > char **orig_name) > { > - struct ifmibdata ifmd; > size_t len; > + unsigned int ifindex; > int name[6]; > - int i, maxifno; > > + ifindex = if_nametoindex(ifname); > + if (ifindex == 0) { > + goto fail; > + } > + > name[0] = CTL_NET; > name[1] = PF_LINK; > name[2] = NETLINK_GENERIC; > - name[3] = IFMIB_SYSTEM; > - name[4] = IFMIB_IFCOUNT; > + name[3] = IFMIB_IFDATA; > + name[4] = ifindex; > + name[5] = IFDATA_DRIVERNAME; > > - len = sizeof maxifno; > - if (sysctl(name, 5, &maxifno, &len, 0, 0) < 0) { > - h->error.errtype = OTHER; > - h->error.errcode = errno; > - return (-1); > + len = 0; > + if (sysctl(name, 6, NULL, &len, 0, 0) < 0) { > + goto fail; > } > > - name[3] = IFMIB_IFDATA; > - name[5] = IFDATA_GENERAL; > - for (i = 1; i <= maxifno; i++) { > - len = sizeof ifmd; > - name[4] = i; > - if (sysctl(name, 6, &ifmd, &len, 0, 0) < 0) { > - if (errno == ENOENT) > - continue; > + *orig_name = malloc(len); > + if (*orig_name == NULL) { > + goto fail; > + } > > - goto fail; > - } > + if (sysctl(name, 6, *orig_name, &len, 0, 0) < 0) { > + free(*orig_name); > + *orig_name = NULL; > + goto fail; > + } > > - if (strncmp(ifmd.ifmd_name, ifname, IFNAMSIZ) != 0) > - continue; > + return (0); > > - len = 0; > - name[5] = IFDATA_DRIVERNAME; > - if (sysctl(name, 6, NULL, &len, 0, 0) < 0) > - goto fail; > +fail: > + h->error.errtype = OTHER; > + h->error.errcode = (errno != 0) ? errno : ENOENT; > + return (-1); > +} > > - *orig_name = malloc(len); > - if (*orig_name == NULL) > - goto fail; > +int > +ifconfig_get_fib(ifconfig_handle_t *h, const char *name, int *fib) > +{ > + struct ifreq ifr; > > - if (sysctl(name, 6, *orig_name, &len, 0, 0) < 0) { > - free(*orig_name); > - *orig_name = NULL; > - goto fail; > - } > + memset(&ifr, 0, sizeof(ifr)); > + (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); > > - return (0); > + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFFIB, &ifr) == -1) { > + return (-1); > } > > -fail: > - h->error.errtype = OTHER; > - h->error.errcode = (i <= maxifno) ? errno : ENOENT; > - return (-1); > + *fib = ifr.ifr_fib; > + return (0); > } > > int > @@ -351,8 +363,7 @@ ifconfig_set_mtu(ifconfig_handle_t *h, const char *nam > (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); > } > > @@ -367,8 +378,7 @@ ifconfig_get_mtu(ifconfig_handle_t *h, const char *nam > 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); > } > > @@ -377,6 +387,24 @@ ifconfig_get_mtu(ifconfig_handle_t *h, const char *nam > } > > int > +ifconfig_get_nd6(ifconfig_handle_t *h, const char *name, > + struct in6_ndireq *nd) > +{ > + memset(nd, 0, sizeof(*nd)); > + strlcpy(nd->ifname, name, sizeof(nd->ifname)); > + if (ifconfig_ioctlwrap(h, AF_INET6, SIOCGIFINFO_IN6, nd) == -1) { > + return (-1); > + } > + if (isnd6defif(h, name)) { > + nd->ndi.flags |= ND6_IFF_DEFAULTIF; > + } else if (h->error.errtype != OK) { > + return (-1); > + } > + > + return (0); > +} > + > +int > ifconfig_set_metric(ifconfig_handle_t *h, const char *name, const int metric) > { > struct ifreq ifr; > @@ -385,8 +413,7 @@ ifconfig_set_metric(ifconfig_handle_t *h, const char * > (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); > ifr.ifr_metric = metric; > > - if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMETRIC, > - &ifr) < 0) { > + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCSIFMETRIC, &ifr) < 0) { > return (-1); > } > > @@ -401,8 +428,7 @@ ifconfig_get_metric(ifconfig_handle_t *h, const char * > 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); > } > > @@ -420,8 +446,7 @@ ifconfig_set_capability(ifconfig_handle_t *h, const ch > > memset(&ifr, 0, sizeof(ifr)); > > - if (ifconfig_get_capability(h, name, > - &ifcap) != 0) { > + if (ifconfig_get_capability(h, name, &ifcap) != 0) { > return (-1); > } > > @@ -442,8 +467,7 @@ ifconfig_set_capability(ifconfig_handle_t *h, const ch > * 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); > @@ -458,8 +482,7 @@ ifconfig_get_capability(ifconfig_handle_t *h, const ch > 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; > @@ -468,6 +491,45 @@ ifconfig_get_capability(ifconfig_handle_t *h, const ch > } > > int > +ifconfig_get_groups(ifconfig_handle_t *h, const char *name, > + struct ifgroupreq *ifgr) > +{ > + int len; > + > + memset(ifgr, 0, sizeof(*ifgr)); > + strlcpy(ifgr->ifgr_name, name, IFNAMSIZ); > + > + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFGROUP, ifgr) == -1) { > + if ((h->error.errcode == EINVAL) || > + (h->error.errcode == ENOTTY)) { > + return (0); > + } else { > + return (-1); > + } > + } > + > + len = ifgr->ifgr_len; > + ifgr->ifgr_groups = (struct ifg_req *)malloc(len); > + if (ifgr->ifgr_groups == NULL) { > + return (1); > + } > + bzero(ifgr->ifgr_groups, len); > + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFGROUP, ifgr) == -1) { > + return (-1); > + } > + > + return (0); > +} > + > +int > +ifconfig_get_ifstatus(ifconfig_handle_t *h, const char *name, > + struct ifstat *ifs) > +{ > + strlcpy(ifs->ifs_name, name, sizeof(ifs->ifs_name)); > + return (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGIFSTATUS, ifs)); > +} > + > +int > ifconfig_destroy_interface(ifconfig_handle_t *h, const char *name) > { > struct ifreq ifr; > @@ -475,8 +537,7 @@ ifconfig_destroy_interface(ifconfig_handle_t *h, const > 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); > @@ -488,6 +549,7 @@ ifconfig_create_interface(ifconfig_handle_t *h, const > struct ifreq ifr; > > memset(&ifr, 0, sizeof(ifr)); > + > (void)strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); > > /* > @@ -512,5 +574,57 @@ ifconfig_create_interface(ifconfig_handle_t *h, const > } > > *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); > } > > Modified: head/lib/libifconfig/libifconfig.h > ============================================================================== > --- head/lib/libifconfig/libifconfig.h Fri Feb 23 02:53:50 2018 (r329852) > +++ head/lib/libifconfig/libifconfig.h Fri Feb 23 03:11:43 2018 (r329853) > @@ -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, > @@ -28,8 +28,16 @@ > > #pragma once > > +#include > +#include > + > +#define ND6_IFF_DEFAULTIF 0x8000 > + > typedef enum { > - OTHER, IOCTL, SOCKET > + OK = 0, > + OTHER, > + IOCTL, > + SOCKET > } ifconfig_errtype; > > /* > @@ -37,8 +45,16 @@ typedef enum { > * pointer to it for library use. > */ > struct ifconfig_handle; > -typedef struct ifconfig_handle ifconfig_handle_t; > +typedef struct ifconfig_handle ifconfig_handle_t; > > +struct carpreq; > +struct ifaddrs; > +struct in6_ndireq; > +struct lagg_reqall; > +struct lagg_reqflags; > +struct lagg_reqopts; > +struct lagg_reqport; > + > struct ifconfig_capabilities { > /** Current capabilities (ifconfig prints this as 'options')*/ > int curcap; > @@ -46,13 +62,44 @@ struct ifconfig_capabilities { > int reqcap; > }; > > +/** Stores extra info associated with an inet address */ > +struct ifconfig_inet_addr { > + const struct sockaddr_in *sin; > + const struct sockaddr_in *netmask; > + const struct sockaddr_in *dst; > + const struct sockaddr_in *broadcast; > + int prefixlen; > + uint8_t vhid; > +}; > + > +/** Stores extra info associated with an inet6 address */ > +struct ifconfig_inet6_addr { > + struct sockaddr_in6 *sin6; > + struct sockaddr_in6 *dstin6; > + struct in6_addrlifetime lifetime; > + int prefixlen; > + uint32_t flags; > + uint8_t vhid; > +}; > + > +/** Stores extra info associated with a lagg(4) interface */ > +struct ifconfig_lagg_status { > + struct lagg_reqall *ra; > + struct lagg_reqopts *ro; > + struct lagg_reqflags *rf; > +}; > + > /** Retrieves a new state object for use in other API calls. > * 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); > @@ -73,6 +120,28 @@ ifconfig_errtype ifconfig_err_errtype(ifconfig_handle_ > /** Retrieves the errno associated with the error, if any. */ > int ifconfig_err_errno(ifconfig_handle_t *h); > > +typedef void (*ifconfig_foreach_func_t)(ifconfig_handle_t *h, > + struct ifaddrs *ifa, void *udata); > + > +/** Iterate over every network interface > + * @param h An open ifconfig state object > + * @param cb A callback function to call with a pointer to each interface > + * @param udata An opaque value that will be passed to the callback. > + * @return 0 on success, nonzero if the list could not be iterated > + */ > +int ifconfig_foreach_iface(ifconfig_handle_t *h, ifconfig_foreach_func_t cb, > + void *udata); > + > +/** Iterate over every address on a single network interface > + * @param h An open ifconfig state object > + * @param ifa A pointer that was supplied by a previous call to > + * ifconfig_foreach_iface > + * @param udata An opaque value that will be passed to the callback. > + * @param cb A callback function to call with a pointer to each ifaddr > + */ > +void ifconfig_foreach_ifaddr(ifconfig_handle_t *h, struct ifaddrs *ifa, > + ifconfig_foreach_func_t cb, void *udata); > + > /** 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, > @@ -84,8 +153,12 @@ int ifconfig_set_name(ifconfig_handle_t *h, const char > const char *newname); > int ifconfig_get_orig_name(ifconfig_handle_t *h, const char *ifname, > char **orig_name); > +int ifconfig_set_fib(ifconfig_handle_t *h, const char *name, int fib); > +int ifconfig_get_fib(ifconfig_handle_t *h, const char *name, int *fib); > 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_get_nd6(ifconfig_handle_t *h, const char *name, > + struct in6_ndireq *nd); > 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); > @@ -94,6 +167,70 @@ int ifconfig_set_capability(ifconfig_handle_t *h, cons > int ifconfig_get_capability(ifconfig_handle_t *h, const char *name, > struct ifconfig_capabilities *capability); > > +/** Retrieve the list of groups to which this interface belongs > + * @param h An open ifconfig state object > + * @param name The interface name > + * @param ifgr return argument. The caller is responsible for freeing > + * ifgr->ifgr_groups > + * @return 0 on success, nonzero on failure > + */ > +int ifconfig_get_groups(ifconfig_handle_t *h, const char *name, > + struct ifgroupreq *ifgr); > +int ifconfig_get_ifstatus(ifconfig_handle_t *h, const char *name, > + struct ifstat *stat); > + > +/** Retrieve the interface media information > + * @param h An open ifconfig state object > + * @param name The interface name > + * @param ifmr Return argument. The caller is responsible for freeing it > + * @return 0 on success, nonzero on failure > + */ > +int ifconfig_media_get_mediareq(ifconfig_handle_t *h, const char *name, > + struct ifmediareq **ifmr); > +const char *ifconfig_media_get_type(int ifmw); > +const char *ifconfig_media_get_subtype(int ifmw); > +const char *ifconfig_media_get_status(const struct ifmediareq *ifmr); > +void ifconfig_media_get_options_string(int ifmw, char *buf, size_t buflen); > + > +int ifconfig_carp_get_info(ifconfig_handle_t *h, const char *name, > + struct carpreq *carpr, int ncarpr); > + > +/** Retrieve additional information about an inet address > + * @param h An open ifconfig state object > + * @param name The interface name > + * @param ifa Pointer to the the address structure of interest > + * @param addr Return argument. It will be filled with additional information > + * about the address. > + * @return 0 on success, nonzero on failure. > + */ > +int ifconfig_inet_get_addrinfo(ifconfig_handle_t *h, > + const char *name, struct ifaddrs *ifa, struct ifconfig_inet_addr *addr); > + > +/** Retrieve additional information about an inet6 address > + * @param h An open ifconfig state object > + * @param name The interface name > + * @param ifa Pointer to the the address structure of interest > + * @param addr Return argument. It will be filled with additional information > + * about the address. > + * @return 0 on success, nonzero on failure. > + */ > +int ifconfig_inet6_get_addrinfo(ifconfig_handle_t *h, > + const char *name, struct ifaddrs *ifa, struct ifconfig_inet6_addr *addr); > + > +/** Retrieve additional information about a lagg(4) interface */ > +int ifconfig_lagg_get_lagg_status(ifconfig_handle_t *h, > + const char *name, struct ifconfig_lagg_status **lagg_status); > + > +/** Retrieve additional information about a member of a lagg(4) interface */ > +int ifconfig_lagg_get_laggport_status(ifconfig_handle_t *h, > + const char *name, struct lagg_reqport *rp); > + > +/** Frees the structure returned by ifconfig_lagg_get_status. Does nothing if > + * the argument is NULL > + * @param laggstat Pointer to the structure to free > + */ > +void ifconfig_lagg_free_lagg_status(struct ifconfig_lagg_status *laggstat); > + > /** Destroy a virtual interface > * @param name Interface to destroy > */ > @@ -105,3 +242,15 @@ int ifconfig_destroy_interface(ifconfig_handle_t *h, c > */ > 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); > > Added: head/lib/libifconfig/libifconfig_carp.c > ============================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/lib/libifconfig/libifconfig_carp.c Fri Feb 23 03:11:43 2018 (r329853) > @@ -0,0 +1,60 @@ > +/* > + * 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. > + * 3. 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. > + * > + * $FreeBSD$ > + */ > +#include > +#include > + > +#include > +#include > + > +#include > +#include > + > +#include "libifconfig.h" > +#include "libifconfig_internal.h" > + > + > +int > +ifconfig_carp_get_info(ifconfig_handle_t *h, const char *name, > + struct carpreq *carpr, int ncarpr) > +{ > + struct ifreq ifr; > + > + bzero(carpr, sizeof(struct carpreq) * ncarpr); > + carpr[0].carpr_count = ncarpr; > + strlcpy(ifr.ifr_name, name, sizeof(ifr.ifr_name)); > + ifr.ifr_data = (caddr_t)carpr; > + > + if (ifconfig_ioctlwrap(h, AF_LOCAL, SIOCGVH, &ifr) != 0) { > + return (-1); > + } > + > + return (0); > +} > > Added: head/lib/libifconfig/libifconfig_inet.c > ============================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/lib/libifconfig/libifconfig_inet.c Fri Feb 23 03:11:43 2018 (r329853) > @@ -0,0 +1,98 @@ > +/* > + * 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. > + * 3. 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. > + * > + * $FreeBSD$ > + */ > +#include > +#include > + > +#include > +#include > + > +#include > +#include > +#include > +#include > + > +#include "libifconfig.h" > +#include "libifconfig_internal.h" > + > +static const struct sockaddr_in NULL_SIN; > + > +static int > +inet_prefixlen(const struct in_addr *addr) > +{ > + int x; > + > + x = ffs(ntohl(addr->s_addr)); > + return (x == 0 ? 0 : 33 - x); > +} > + > +int > +ifconfig_inet_get_addrinfo(ifconfig_handle_t *h __unused, > + const char *name __unused, struct ifaddrs *ifa, > + struct ifconfig_inet_addr *addr) > +{ > + bzero(addr, sizeof(*addr)); > + > + /* Set the address */ > + if (ifa->ifa_addr == NULL) { > + return (-1); > + } else { > + addr->sin = (struct sockaddr_in *)ifa->ifa_addr; > + } > + > + /* Set the destination address */ > + if (ifa->ifa_flags & IFF_POINTOPOINT) { > + if (ifa->ifa_dstaddr) { > + addr->dst = (struct sockaddr_in *)ifa->ifa_dstaddr; > + } else { > + addr->dst = &NULL_SIN; > + } > + } > + > + /* Set the netmask and prefixlen */ > + if (ifa->ifa_netmask) { > + addr->netmask = (struct sockaddr_in *)ifa->ifa_netmask; > + } else { > + addr->netmask = &NULL_SIN; > + } > + addr->prefixlen = inet_prefixlen(&addr->netmask->sin_addr); > + > + /* Set the broadcast */ > + if (ifa->ifa_flags & IFF_BROADCAST) { > + addr->broadcast = (struct sockaddr_in *)ifa->ifa_broadaddr; > + } > + > + /* Set the vhid */ > + if (ifa->ifa_data) { > + addr->vhid = ((struct if_data *)ifa->ifa_data)->ifi_vhid; > + } > + > + return (0); > +} > > Added: head/lib/libifconfig/libifconfig_inet6.c > ============================================================================== > --- /dev/null 00:00:00 1970 (empty, because file is newly added) > +++ head/lib/libifconfig/libifconfig_inet6.c Fri Feb 23 03:11:43 2018 (r329853) > @@ -0,0 +1,105 @@ > +/* > + * 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. > + * 3. 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. > + * > + * $FreeBSD$ > + */ > > *** DIFF OUTPUT TRUNCATED AT 1000 LINES *** > > -- Rod Grimes rgrimes@freebsd.org