Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Feb 2018 06:47:05 -0800 (PST)
From:      "Rodney W. Grimes" <freebsd@pdx.rh.CN85.dnsmgr.net>
To:        Alan Somers <asomers@freebsd.org>
Cc:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   Re: svn commit: r329853 - in head: lib/libifconfig share/examples/libifconfig usr.sbin/wlandebug
Message-ID:  <201802231447.w1NEl58N096144@pdx.rh.CN85.dnsmgr.net>
In-Reply-To: <201802230311.w1N3BhiJ023939@repo.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
> 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 <bsd.lib.mk>
> 
> 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 <sys/types.h>
>  #include <sys/ioctl.h>
>  #include <sys/sysctl.h>
>  
>  #include <net/if.h>
>  #include <net/if_mib.h>
> +#include <netinet/in.h>
> +#include <netinet6/in6_var.h>
> +#include <netinet6/nd6.h>
>  
>  #include <err.h>
>  #include <errno.h>
>  #include <fcntl.h>
> +#include <ifaddrs.h>
> +#include <stdbool.h>
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <string.h>
>  #include <unistd.h>
>  
> +#include <net/if_vlan_var.h>
> +
>  #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(&params, 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)&params;
> +
> +	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(&params, sizeof(params));
> +	params.vlr_tag = vlantag;
> +	strlcpy(params.vlr_parent, vlandev, sizeof(params.vlr_parent));
> +
> +	ifr.ifr_data = (caddr_t)&params;
> +	(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 <netinet/in.h>
> +#include <netinet6/in6_var.h>
> +
> +#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 <sys/param.h>
> +#include <sys/ioctl.h>
> +
> +#include <net/if.h>
> +#include <netinet/ip_carp.h>
> +
> +#include <string.h>
> +#include <strings.h>
> +
> +#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 <sys/param.h>
> +#include <sys/ioctl.h>
> +
> +#include <net/if.h>
> +#include <netinet/in.h>
> +
> +#include <errno.h>
> +#include <ifaddrs.h>
> +#include <string.h>
> +#include <strings.h>
> +
> +#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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802231447.w1NEl58N096144>