Home | History | Annotate | Line # | Download | only in ifconfig
ifconfig.c revision 1.141.4.1
      1  1.141.4.1       snj /*	$NetBSD: ifconfig.c,v 1.141.4.1 2005/07/24 01:36:26 snj Exp $	*/
      2       1.24   thorpej 
      3       1.41   thorpej /*-
      4       1.64   thorpej  * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc.
      5       1.24   thorpej  * All rights reserved.
      6       1.24   thorpej  *
      7       1.41   thorpej  * This code is derived from software contributed to The NetBSD Foundation
      8       1.41   thorpej  * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
      9       1.41   thorpej  * NASA Ames Research Center.
     10       1.41   thorpej  *
     11       1.24   thorpej  * Redistribution and use in source and binary forms, with or without
     12       1.24   thorpej  * modification, are permitted provided that the following conditions
     13       1.24   thorpej  * are met:
     14       1.24   thorpej  * 1. Redistributions of source code must retain the above copyright
     15       1.24   thorpej  *    notice, this list of conditions and the following disclaimer.
     16       1.24   thorpej  * 2. Redistributions in binary form must reproduce the above copyright
     17       1.24   thorpej  *    notice, this list of conditions and the following disclaimer in the
     18       1.24   thorpej  *    documentation and/or other materials provided with the distribution.
     19       1.24   thorpej  * 3. All advertising materials mentioning features or use of this software
     20       1.24   thorpej  *    must display the following acknowledgement:
     21       1.41   thorpej  *	This product includes software developed by the NetBSD
     22       1.41   thorpej  *	Foundation, Inc. and its contributors.
     23       1.41   thorpej  * 4. Neither the name of The NetBSD Foundation nor the names of its
     24       1.41   thorpej  *    contributors may be used to endorse or promote products derived
     25       1.41   thorpej  *    from this software without specific prior written permission.
     26       1.24   thorpej  *
     27       1.41   thorpej  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     28       1.41   thorpej  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     29       1.41   thorpej  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     30       1.41   thorpej  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     31       1.41   thorpej  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     32       1.41   thorpej  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     33       1.41   thorpej  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     34       1.41   thorpej  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     35       1.41   thorpej  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     36       1.41   thorpej  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     37       1.41   thorpej  * POSSIBILITY OF SUCH DAMAGE.
     38       1.24   thorpej  */
     39       1.19       cgd 
     40        1.1       cgd /*
     41       1.13   mycroft  * Copyright (c) 1983, 1993
     42       1.13   mycroft  *	The Regents of the University of California.  All rights reserved.
     43        1.1       cgd  *
     44        1.1       cgd  * Redistribution and use in source and binary forms, with or without
     45        1.1       cgd  * modification, are permitted provided that the following conditions
     46        1.1       cgd  * are met:
     47        1.1       cgd  * 1. Redistributions of source code must retain the above copyright
     48        1.1       cgd  *    notice, this list of conditions and the following disclaimer.
     49        1.1       cgd  * 2. Redistributions in binary form must reproduce the above copyright
     50        1.1       cgd  *    notice, this list of conditions and the following disclaimer in the
     51        1.1       cgd  *    documentation and/or other materials provided with the distribution.
     52      1.138       agc  * 3. Neither the name of the University nor the names of its contributors
     53        1.1       cgd  *    may be used to endorse or promote products derived from this software
     54        1.1       cgd  *    without specific prior written permission.
     55        1.1       cgd  *
     56        1.1       cgd  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     57        1.1       cgd  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     58        1.1       cgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     59        1.1       cgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     60        1.1       cgd  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     61        1.1       cgd  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     62        1.1       cgd  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     63        1.1       cgd  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     64        1.1       cgd  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     65        1.1       cgd  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     66        1.1       cgd  * SUCH DAMAGE.
     67        1.1       cgd  */
     68        1.1       cgd 
     69       1.39     lukem #include <sys/cdefs.h>
     70        1.1       cgd #ifndef lint
     71       1.39     lukem __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\
     72       1.39     lukem 	The Regents of the University of California.  All rights reserved.\n");
     73        1.1       cgd #endif /* not lint */
     74        1.1       cgd 
     75        1.1       cgd #ifndef lint
     76       1.19       cgd #if 0
     77       1.19       cgd static char sccsid[] = "@(#)ifconfig.c	8.2 (Berkeley) 2/16/94";
     78       1.19       cgd #else
     79  1.141.4.1       snj __RCSID("$NetBSD: ifconfig.c,v 1.141.4.1 2005/07/24 01:36:26 snj Exp $");
     80       1.19       cgd #endif
     81        1.1       cgd #endif /* not lint */
     82        1.1       cgd 
     83        1.1       cgd #include <sys/param.h>
     84        1.1       cgd #include <sys/socket.h>
     85        1.1       cgd #include <sys/ioctl.h>
     86        1.1       cgd 
     87        1.1       cgd #include <net/if.h>
     88       1.30   thorpej #include <net/if_dl.h>
     89       1.24   thorpej #include <net/if_media.h>
     90       1.62    chopps #include <net/if_ether.h>
     91      1.139    dyoung #include <net80211/ieee80211.h>
     92      1.139    dyoung #include <net80211/ieee80211_ioctl.h>
     93       1.89   thorpej #include <net/if_vlanvar.h>
     94        1.1       cgd #include <netinet/in.h>
     95       1.53    itojun #include <netinet/in_var.h>
     96       1.54  sommerfe #ifdef INET6
     97       1.53    itojun #include <netinet6/nd6.h>
     98       1.54  sommerfe #endif
     99        1.1       cgd #include <arpa/inet.h>
    100        1.1       cgd 
    101       1.32  christos #include <netatalk/at.h>
    102       1.32  christos 
    103        1.1       cgd #define	NSIP
    104        1.1       cgd #include <netns/ns.h>
    105        1.1       cgd #include <netns/ns_if.h>
    106       1.13   mycroft #include <netdb.h>
    107        1.1       cgd 
    108        1.1       cgd #define EON
    109        1.1       cgd #include <netiso/iso.h>
    110        1.1       cgd #include <netiso/iso_var.h>
    111        1.1       cgd #include <sys/protosw.h>
    112        1.1       cgd 
    113       1.13   mycroft #include <ctype.h>
    114       1.13   mycroft #include <err.h>
    115       1.13   mycroft #include <errno.h>
    116       1.50    chopps #include <stddef.h>
    117        1.1       cgd #include <stdio.h>
    118        1.1       cgd #include <stdlib.h>
    119        1.1       cgd #include <string.h>
    120       1.13   mycroft #include <unistd.h>
    121       1.78    itojun #include <ifaddrs.h>
    122      1.130  christos #include <util.h>
    123        1.1       cgd 
    124       1.79     enami struct	ifreq		ifr, ridreq;
    125       1.35   thorpej struct	ifaliasreq	addreq __attribute__((aligned(4)));
    126      1.122    itojun struct	in_aliasreq	in_addreq;
    127       1.53    itojun #ifdef INET6
    128       1.53    itojun struct	in6_ifreq	ifr6;
    129       1.53    itojun struct	in6_ifreq	in6_ridreq;
    130      1.122    itojun struct	in6_aliasreq	in6_addreq;
    131       1.53    itojun #endif
    132       1.50    chopps struct	iso_ifreq	iso_ridreq;
    133        1.1       cgd struct	iso_aliasreq	iso_addreq;
    134        1.1       cgd struct	sockaddr_in	netmask;
    135       1.32  christos struct	netrange	at_nr;		/* AppleTalk net range */
    136       1.32  christos 
    137        1.1       cgd char	name[30];
    138      1.130  christos u_short	flags;
    139      1.130  christos int	setaddr, setipdst, doalias;
    140      1.125    itojun u_long	metric, mtu;
    141       1.16       cgd int	clearaddr, s;
    142       1.36     lukem int	newaddr = -1;
    143      1.112     david int	conflicting = 0;
    144        1.1       cgd int	nsellength = 1;
    145       1.24   thorpej int	af;
    146      1.134     perry int	aflag, bflag, Cflag, dflag, lflag, mflag, sflag, uflag, vflag, zflag;
    147       1.53    itojun #ifdef INET6
    148       1.53    itojun int	Lflag;
    149       1.53    itojun #endif
    150       1.53    itojun int	explicit_prefix = 0;
    151       1.89   thorpej u_int	vlan_tag = (u_int)-1;
    152        1.1       cgd 
    153      1.108   thorpej struct ifcapreq g_ifcr;
    154      1.108   thorpej int	g_ifcr_updated;
    155      1.108   thorpej 
    156       1.80   thorpej void 	notealias __P((const char *, int));
    157       1.80   thorpej void 	notrailers __P((const char *, int));
    158       1.80   thorpej void 	setifaddr __P((const char *, int));
    159       1.80   thorpej void 	setifdstaddr __P((const char *, int));
    160       1.80   thorpej void 	setifflags __P((const char *, int));
    161      1.108   thorpej void	setifcaps __P((const char *, int));
    162       1.80   thorpej void 	setifbroadaddr __P((const char *, int));
    163       1.80   thorpej void 	setifipdst __P((const char *, int));
    164       1.80   thorpej void 	setifmetric __P((const char *, int));
    165       1.80   thorpej void 	setifmtu __P((const char *, int));
    166       1.80   thorpej void	setifnwid __P((const char *, int));
    167       1.88      onoe void	setifnwkey __P((const char *, int));
    168      1.131   thorpej void	setifbssid __P((const char *, int));
    169      1.131   thorpej void	setifchan __P((const char *, int));
    170       1.92   thorpej void	setifpowersave __P((const char *, int));
    171       1.92   thorpej void	setifpowersavesleep __P((const char *, int));
    172       1.80   thorpej void 	setifnetmask __P((const char *, int));
    173       1.80   thorpej void	setifprefixlen __P((const char *, int));
    174       1.80   thorpej void 	setnsellength __P((const char *, int));
    175       1.80   thorpej void 	setsnpaoffset __P((const char *, int));
    176       1.80   thorpej void	setatrange __P((const char *, int));
    177       1.80   thorpej void	setatphase __P((const char *, int));
    178       1.80   thorpej void	settunnel __P((const char *, const char *));
    179       1.80   thorpej void	deletetunnel __P((const char *, int));
    180       1.80   thorpej #ifdef INET6
    181       1.80   thorpej void 	setia6flags __P((const char *, int));
    182       1.80   thorpej void	setia6pltime __P((const char *, int));
    183       1.80   thorpej void	setia6vltime __P((const char *, int));
    184       1.80   thorpej void	setia6lifetime __P((const char *, const char *));
    185      1.127    itojun void	setia6eui64 __P((const char *, int));
    186       1.53    itojun #endif
    187       1.32  christos void	checkatrange __P ((struct sockaddr_at *));
    188       1.80   thorpej void	setmedia __P((const char *, int));
    189      1.139    dyoung void	setmediamode __P((const char *, int));
    190       1.80   thorpej void	setmediaopt __P((const char *, int));
    191       1.80   thorpej void	unsetmediaopt __P((const char *, int));
    192       1.80   thorpej void	setmediainst __P((const char *, int));
    193       1.81   thorpej void	clone_create __P((const char *, int));
    194       1.81   thorpej void	clone_destroy __P((const char *, int));
    195       1.32  christos void	fixnsel __P((struct sockaddr_iso *));
    196       1.89   thorpej void	setvlan __P((const char *, int));
    197       1.89   thorpej void	setvlanif __P((const char *, int));
    198       1.89   thorpej void	unsetvlanif __P((const char *, int));
    199       1.32  christos int	main __P((int, char *[]));
    200        1.1       cgd 
    201       1.45   thorpej /*
    202       1.45   thorpej  * Media stuff.  Whenever a media command is first performed, the
    203       1.45   thorpej  * currently select media is grabbed for this interface.  If `media'
    204       1.45   thorpej  * is given, the current media word is modifed.  `mediaopt' commands
    205       1.45   thorpej  * only modify the set and clear words.  They then operate on the
    206       1.45   thorpej  * current media word later.
    207       1.45   thorpej  */
    208       1.45   thorpej int	media_current;
    209       1.45   thorpej int	mediaopt_set;
    210       1.45   thorpej int	mediaopt_clear;
    211       1.45   thorpej 
    212       1.46   thorpej int	actions;			/* Actions performed */
    213       1.45   thorpej 
    214       1.46   thorpej #define	A_MEDIA		0x0001		/* media command */
    215       1.46   thorpej #define	A_MEDIAOPTSET	0x0002		/* mediaopt command */
    216       1.46   thorpej #define	A_MEDIAOPTCLR	0x0004		/* -mediaopt command */
    217       1.46   thorpej #define	A_MEDIAOPT	(A_MEDIAOPTSET|A_MEDIAOPTCLR)
    218       1.47   thorpej #define	A_MEDIAINST	0x0008		/* instance or inst command */
    219      1.139    dyoung #define	A_MEDIAMODE	0x0010		/* mode command */
    220       1.45   thorpej 
    221        1.1       cgd #define	NEXTARG		0xffffff
    222       1.80   thorpej #define	NEXTARG2	0xfffffe
    223        1.1       cgd 
    224       1.80   thorpej const struct cmd {
    225       1.80   thorpej 	const char *c_name;
    226       1.80   thorpej 	int	c_parameter;	/* NEXTARG means next argv */
    227       1.46   thorpej 	int	c_action;	/* defered action */
    228       1.80   thorpej 	void	(*c_func) __P((const char *, int));
    229       1.80   thorpej 	void	(*c_func2) __P((const char *, const char *));
    230        1.1       cgd } cmds[] = {
    231       1.45   thorpej 	{ "up",		IFF_UP,		0,		setifflags } ,
    232       1.45   thorpej 	{ "down",	-IFF_UP,	0,		setifflags },
    233       1.45   thorpej 	{ "trailers",	-1,		0,		notrailers },
    234       1.45   thorpej 	{ "-trailers",	1,		0,		notrailers },
    235       1.45   thorpej 	{ "arp",	-IFF_NOARP,	0,		setifflags },
    236       1.45   thorpej 	{ "-arp",	IFF_NOARP,	0,		setifflags },
    237       1.45   thorpej 	{ "debug",	IFF_DEBUG,	0,		setifflags },
    238       1.45   thorpej 	{ "-debug",	-IFF_DEBUG,	0,		setifflags },
    239       1.45   thorpej 	{ "alias",	IFF_UP,		0,		notealias },
    240       1.45   thorpej 	{ "-alias",	-IFF_UP,	0,		notealias },
    241       1.45   thorpej 	{ "delete",	-IFF_UP,	0,		notealias },
    242        1.1       cgd #ifdef notdef
    243        1.1       cgd #define	EN_SWABIPS	0x1000
    244       1.45   thorpej 	{ "swabips",	EN_SWABIPS,	0,		setifflags },
    245       1.45   thorpej 	{ "-swabips",	-EN_SWABIPS,	0,		setifflags },
    246        1.1       cgd #endif
    247       1.45   thorpej 	{ "netmask",	NEXTARG,	0,		setifnetmask },
    248       1.45   thorpej 	{ "metric",	NEXTARG,	0,		setifmetric },
    249       1.45   thorpej 	{ "mtu",	NEXTARG,	0,		setifmtu },
    250      1.131   thorpej 	{ "bssid",	NEXTARG,	0,		setifbssid },
    251      1.131   thorpej 	{ "-bssid",	-1,		0,		setifbssid },
    252      1.131   thorpej 	{ "chan",	NEXTARG,	0,		setifchan },
    253      1.133      onoe 	{ "-chan",	-1,		0,		setifchan },
    254      1.141     perry 	{ "ssid",	NEXTARG,	0,		setifnwid },
    255       1.62    chopps 	{ "nwid",	NEXTARG,	0,		setifnwid },
    256       1.88      onoe 	{ "nwkey",	NEXTARG,	0,		setifnwkey },
    257       1.88      onoe 	{ "-nwkey",	-1,		0,		setifnwkey },
    258       1.92   thorpej 	{ "powersave",	1,		0,		setifpowersave },
    259       1.92   thorpej 	{ "-powersave",	0,		0,		setifpowersave },
    260       1.92   thorpej 	{ "powersavesleep", NEXTARG,	0,		setifpowersavesleep },
    261       1.45   thorpej 	{ "broadcast",	NEXTARG,	0,		setifbroadaddr },
    262       1.45   thorpej 	{ "ipdst",	NEXTARG,	0,		setifipdst },
    263       1.53    itojun 	{ "prefixlen",  NEXTARG,	0,		setifprefixlen},
    264       1.53    itojun #ifdef INET6
    265       1.53    itojun 	{ "anycast",	IN6_IFF_ANYCAST,	0,	setia6flags },
    266       1.53    itojun 	{ "-anycast",	-IN6_IFF_ANYCAST,	0,	setia6flags },
    267       1.53    itojun 	{ "tentative",	IN6_IFF_TENTATIVE,	0,	setia6flags },
    268       1.53    itojun 	{ "-tentative",	-IN6_IFF_TENTATIVE,	0,	setia6flags },
    269      1.104    itojun 	{ "deprecated",	IN6_IFF_DEPRECATED,	0,	setia6flags },
    270      1.104    itojun 	{ "-deprecated", -IN6_IFF_DEPRECATED,	0,	setia6flags },
    271       1.53    itojun 	{ "pltime",	NEXTARG,	0,		setia6pltime },
    272       1.53    itojun 	{ "vltime",	NEXTARG,	0,		setia6vltime },
    273      1.127    itojun 	{ "eui64",	0,		0,		setia6eui64 },
    274       1.53    itojun #endif /*INET6*/
    275       1.21       gwr #ifndef INET_ONLY
    276       1.45   thorpej 	{ "range",	NEXTARG,	0,		setatrange },
    277       1.45   thorpej 	{ "phase",	NEXTARG,	0,		setatphase },
    278       1.45   thorpej 	{ "snpaoffset",	NEXTARG,	0,		setsnpaoffset },
    279       1.45   thorpej 	{ "nsellength",	NEXTARG,	0,		setnsellength },
    280       1.21       gwr #endif	/* INET_ONLY */
    281       1.80   thorpej 	{ "tunnel",	NEXTARG2,	0,		NULL,
    282       1.80   thorpej 							settunnel } ,
    283       1.80   thorpej 	{ "deletetunnel", 0,		0,		deletetunnel },
    284       1.89   thorpej 	{ "vlan",	NEXTARG,	0,		setvlan } ,
    285       1.89   thorpej 	{ "vlanif",	NEXTARG,	0,		setvlanif } ,
    286       1.89   thorpej 	{ "-vlanif",	0,		0,		unsetvlanif } ,
    287       1.81   thorpej #if 0
    288       1.81   thorpej 	/* XXX `create' special-cased below */
    289       1.81   thorpej 	{ "create",	0,		0,		clone_create } ,
    290       1.81   thorpej #endif
    291       1.81   thorpej 	{ "destroy",	0,		0,		clone_destroy } ,
    292       1.45   thorpej 	{ "link0",	IFF_LINK0,	0,		setifflags } ,
    293       1.45   thorpej 	{ "-link0",	-IFF_LINK0,	0,		setifflags } ,
    294       1.45   thorpej 	{ "link1",	IFF_LINK1,	0,		setifflags } ,
    295       1.45   thorpej 	{ "-link1",	-IFF_LINK1,	0,		setifflags } ,
    296       1.45   thorpej 	{ "link2",	IFF_LINK2,	0,		setifflags } ,
    297       1.45   thorpej 	{ "-link2",	-IFF_LINK2,	0,		setifflags } ,
    298       1.46   thorpej 	{ "media",	NEXTARG,	A_MEDIA,	setmedia },
    299       1.46   thorpej 	{ "mediaopt",	NEXTARG,	A_MEDIAOPTSET,	setmediaopt },
    300       1.46   thorpej 	{ "-mediaopt",	NEXTARG,	A_MEDIAOPTCLR,	unsetmediaopt },
    301      1.139    dyoung 	{ "mode",	NEXTARG,	A_MEDIAMODE,	setmediamode },
    302       1.47   thorpej 	{ "instance",	NEXTARG,	A_MEDIAINST,	setmediainst },
    303       1.47   thorpej 	{ "inst",	NEXTARG,	A_MEDIAINST,	setmediainst },
    304      1.108   thorpej 	{ "ip4csum",	IFCAP_CSUM_IPv4,0,		setifcaps },
    305      1.108   thorpej 	{ "-ip4csum",	-IFCAP_CSUM_IPv4,0,		setifcaps },
    306      1.108   thorpej 	{ "tcp4csum",	IFCAP_CSUM_TCPv4,0,		setifcaps },
    307      1.108   thorpej 	{ "-tcp4csum",	-IFCAP_CSUM_TCPv4,0,		setifcaps },
    308      1.108   thorpej 	{ "udp4csum",	IFCAP_CSUM_UDPv4,0,		setifcaps },
    309      1.108   thorpej 	{ "-udp4csum",	-IFCAP_CSUM_UDPv4,0,		setifcaps },
    310      1.108   thorpej 	{ "tcp6csum",	IFCAP_CSUM_TCPv6,0,		setifcaps },
    311      1.108   thorpej 	{ "-tcp6csum",	-IFCAP_CSUM_TCPv6,0,		setifcaps },
    312      1.108   thorpej 	{ "udp6csum",	IFCAP_CSUM_UDPv6,0,		setifcaps },
    313      1.108   thorpej 	{ "-udp6csum",	-IFCAP_CSUM_UDPv6,0,		setifcaps },
    314      1.115   thorpej 	{ "tcp4csum-rx",IFCAP_CSUM_TCPv4_Rx,0,		setifcaps },
    315      1.115   thorpej 	{ "-tcp4csum-rx",-IFCAP_CSUM_TCPv4_Rx,0,	setifcaps },
    316      1.115   thorpej 	{ "udp4csum-rx",IFCAP_CSUM_UDPv4_Rx,0,		setifcaps },
    317      1.115   thorpej 	{ "-udp4csum-rx",-IFCAP_CSUM_UDPv4_Rx,0,	setifcaps },
    318       1.45   thorpej 	{ 0,		0,		0,		setifaddr },
    319       1.45   thorpej 	{ 0,		0,		0,		setifdstaddr },
    320        1.1       cgd };
    321        1.1       cgd 
    322       1.32  christos void 	adjust_nsellength __P((void));
    323       1.16       cgd int	getinfo __P((struct ifreq *));
    324       1.54  sommerfe int	carrier __P((void));
    325       1.16       cgd void	getsock __P((int));
    326      1.107    itojun void	printall __P((const char *));
    327       1.87   thorpej void	list_cloners __P((void));
    328       1.53    itojun int	prefix __P((void *, int));
    329      1.119     bjh21 void 	status __P((const struct sockaddr_dl *));
    330       1.32  christos void 	usage __P((void));
    331       1.88      onoe const char *get_string __P((const char *, const char *, u_int8_t *, int *));
    332       1.88      onoe void	print_string __P((const u_int8_t *, int));
    333       1.53    itojun char	*sec2str __P((time_t));
    334       1.16       cgd 
    335       1.42   thorpej const char *get_media_type_string __P((int));
    336       1.42   thorpej const char *get_media_subtype_string __P((int));
    337      1.139    dyoung int	get_media_mode __P((int, const char *));
    338       1.42   thorpej int	get_media_subtype __P((int, const char *));
    339       1.42   thorpej int	get_media_options __P((int, const char *));
    340       1.42   thorpej int	lookup_media_word __P((struct ifmedia_description *, int,
    341       1.42   thorpej 	    const char *));
    342       1.44   thorpej void	print_media_word __P((int, int, int));
    343       1.45   thorpej void	process_media_commands __P((void));
    344       1.45   thorpej void	init_current_media __P((void));
    345       1.24   thorpej 
    346        1.1       cgd /*
    347       1.13   mycroft  * XNS support liberally adapted from code written at the University of
    348       1.13   mycroft  * Maryland principally by James O'Toole and Chris Torek.
    349        1.1       cgd  */
    350       1.49  christos void	in_alias __P((struct ifreq *));
    351       1.16       cgd void	in_status __P((int));
    352       1.80   thorpej void 	in_getaddr __P((const char *, int));
    353       1.95    itojun void 	in_getprefix __P((const char *, int));
    354       1.53    itojun #ifdef INET6
    355       1.59    itojun void	in6_fillscopeid __P((struct sockaddr_in6 *sin6));
    356       1.53    itojun void	in6_alias __P((struct in6_ifreq *));
    357       1.53    itojun void	in6_status __P((int));
    358       1.80   thorpej void 	in6_getaddr __P((const char *, int));
    359       1.80   thorpej void 	in6_getprefix __P((const char *, int));
    360       1.53    itojun #endif
    361       1.32  christos void	at_status __P((int));
    362       1.80   thorpej void	at_getaddr __P((const char *, int));
    363       1.16       cgd void 	xns_status __P((int));
    364       1.80   thorpej void 	xns_getaddr __P((const char *, int));
    365       1.16       cgd void 	iso_status __P((int));
    366       1.80   thorpej void 	iso_getaddr __P((const char *, int));
    367       1.80   thorpej 
    368       1.62    chopps void	ieee80211_status __P((void));
    369       1.80   thorpej void	tunnel_status __P((void));
    370       1.89   thorpej void	vlan_status __P((void));
    371        1.1       cgd 
    372        1.1       cgd /* Known address families */
    373        1.1       cgd struct afswtch {
    374       1.80   thorpej 	const char *af_name;
    375        1.1       cgd 	short af_af;
    376       1.32  christos 	void (*af_status) __P((int));
    377       1.80   thorpej 	void (*af_getaddr) __P((const char *, int));
    378       1.80   thorpej 	void (*af_getprefix) __P((const char *, int));
    379       1.15       cgd 	u_long af_difaddr;
    380       1.15       cgd 	u_long af_aifaddr;
    381       1.76     enami 	u_long af_gifaddr;
    382        1.1       cgd 	caddr_t af_ridreq;
    383        1.1       cgd 	caddr_t af_addreq;
    384        1.1       cgd } afs[] = {
    385        1.1       cgd #define C(x) ((caddr_t) &x)
    386       1.95    itojun 	{ "inet", AF_INET, in_status, in_getaddr, in_getprefix,
    387      1.122    itojun 	     SIOCDIFADDR, SIOCAIFADDR, SIOCGIFADDR, C(ridreq), C(in_addreq) },
    388       1.53    itojun #ifdef INET6
    389       1.53    itojun 	{ "inet6", AF_INET6, in6_status, in6_getaddr, in6_getprefix,
    390       1.76     enami 	     SIOCDIFADDR_IN6, SIOCAIFADDR_IN6,
    391       1.76     enami 	     /*
    392       1.76     enami 	      * Deleting the first address before setting new one is
    393       1.76     enami 	      * not prefered way in this protocol.
    394       1.76     enami 	      */
    395       1.76     enami 	     0,
    396       1.76     enami 	     C(in6_ridreq), C(in6_addreq) },
    397       1.53    itojun #endif
    398       1.21       gwr #ifndef INET_ONLY	/* small version, for boot media */
    399       1.53    itojun 	{ "atalk", AF_APPLETALK, at_status, at_getaddr, NULL,
    400       1.76     enami 	     SIOCDIFADDR, SIOCAIFADDR, SIOCGIFADDR, C(addreq), C(addreq) },
    401       1.53    itojun 	{ "ns", AF_NS, xns_status, xns_getaddr, NULL,
    402       1.76     enami 	     SIOCDIFADDR, SIOCAIFADDR, SIOCGIFADDR, C(ridreq), C(addreq) },
    403       1.53    itojun 	{ "iso", AF_ISO, iso_status, iso_getaddr, NULL,
    404       1.76     enami 	     SIOCDIFADDR_ISO, SIOCAIFADDR_ISO, SIOCGIFADDR_ISO,
    405       1.76     enami 	     C(iso_ridreq), C(iso_addreq) },
    406       1.21       gwr #endif	/* INET_ONLY */
    407        1.1       cgd 	{ 0,	0,	    0,		0 }
    408        1.1       cgd };
    409        1.1       cgd 
    410        1.1       cgd struct afswtch *afp;	/*the address family being set or asked about*/
    411        1.1       cgd 
    412       1.24   thorpej struct afswtch *lookup_af __P((const char *));
    413       1.24   thorpej 
    414       1.16       cgd int
    415        1.1       cgd main(argc, argv)
    416        1.1       cgd 	int argc;
    417        1.1       cgd 	char *argv[];
    418        1.1       cgd {
    419       1.49  christos 	int ch;
    420       1.24   thorpej 
    421       1.24   thorpej 	/* Parse command-line options */
    422      1.134     perry 	aflag = mflag = vflag = zflag = 0;
    423      1.134     perry 	while ((ch = getopt(argc, argv, "AabCdlmsuvz"
    424       1.53    itojun #ifdef INET6
    425       1.53    itojun 					"L"
    426       1.53    itojun #endif
    427       1.53    itojun 			)) != -1) {
    428       1.24   thorpej 		switch (ch) {
    429       1.49  christos 		case 'A':
    430      1.107    itojun 			warnx("-A is deprecated");
    431       1.49  christos 			break;
    432       1.49  christos 
    433       1.24   thorpej 		case 'a':
    434       1.24   thorpej 			aflag = 1;
    435       1.24   thorpej 			break;
    436       1.24   thorpej 
    437       1.54  sommerfe 		case 'b':
    438       1.54  sommerfe 			bflag = 1;
    439       1.54  sommerfe 			break;
    440       1.54  sommerfe 
    441       1.87   thorpej 		case 'C':
    442       1.87   thorpej 			Cflag = 1;
    443       1.87   thorpej 			break;
    444       1.87   thorpej 
    445       1.34     lukem 		case 'd':
    446       1.34     lukem 			dflag = 1;
    447       1.34     lukem 			break;
    448       1.34     lukem 
    449       1.53    itojun #ifdef INET6
    450       1.53    itojun 		case 'L':
    451       1.53    itojun 			Lflag = 1;
    452       1.53    itojun 			break;
    453       1.53    itojun #endif
    454       1.53    itojun 
    455       1.31   thorpej 		case 'l':
    456       1.31   thorpej 			lflag = 1;
    457       1.31   thorpej 			break;
    458       1.31   thorpej 
    459       1.24   thorpej 		case 'm':
    460       1.24   thorpej 			mflag = 1;
    461       1.24   thorpej 			break;
    462        1.1       cgd 
    463       1.54  sommerfe 		case 's':
    464       1.54  sommerfe 			sflag = 1;
    465       1.54  sommerfe 			break;
    466       1.54  sommerfe 
    467       1.34     lukem 		case 'u':
    468       1.34     lukem 			uflag = 1;
    469       1.34     lukem 			break;
    470       1.34     lukem 
    471      1.124      matt 		case 'v':
    472      1.124      matt 			vflag = 1;
    473      1.124      matt 			break;
    474      1.124      matt 
    475      1.134     perry 		case 'z':
    476      1.134     perry 			zflag = 1;
    477      1.134     perry 			break;
    478      1.134     perry 
    479       1.54  sommerfe 
    480       1.24   thorpej 		default:
    481       1.24   thorpej 			usage();
    482       1.24   thorpej 			/* NOTREACHED */
    483       1.24   thorpej 		}
    484        1.1       cgd 	}
    485       1.24   thorpej 	argc -= optind;
    486       1.24   thorpej 	argv += optind;
    487       1.24   thorpej 
    488       1.31   thorpej 	/*
    489       1.31   thorpej 	 * -l means "list all interfaces", and is mutally exclusive with
    490       1.31   thorpej 	 * all other flags/commands.
    491       1.31   thorpej 	 *
    492       1.87   thorpej 	 * -C means "list all names of cloners", and it mutually exclusive
    493       1.87   thorpej 	 * with all other flags/commands.
    494       1.87   thorpej 	 *
    495       1.31   thorpej 	 * -a means "print status of all interfaces".
    496       1.31   thorpej 	 */
    497      1.134     perry 	if ((lflag || Cflag) && (aflag || mflag || vflag || argc || zflag))
    498       1.54  sommerfe 		usage();
    499       1.54  sommerfe #ifdef INET6
    500       1.87   thorpej 	if ((lflag || Cflag) && Lflag)
    501       1.31   thorpej 		usage();
    502       1.54  sommerfe #endif
    503       1.87   thorpej 	if (lflag && Cflag)
    504       1.87   thorpej 		usage();
    505       1.87   thorpej 	if (Cflag) {
    506       1.87   thorpej 		if (argc)
    507       1.87   thorpej 			usage();
    508       1.87   thorpej 		list_cloners();
    509       1.87   thorpej 		exit(0);
    510       1.87   thorpej 	}
    511       1.31   thorpej 	if (aflag || lflag) {
    512       1.24   thorpej 		if (argc > 1)
    513       1.18     glass 			usage();
    514       1.24   thorpej 		else if (argc == 1) {
    515       1.24   thorpej 			afp = lookup_af(argv[0]);
    516       1.24   thorpej 			if (afp == NULL)
    517       1.24   thorpej 				usage();
    518       1.32  christos 		}
    519       1.32  christos 		if (afp)
    520       1.32  christos 			af = ifr.ifr_addr.sa_family = afp->af_af;
    521       1.32  christos 		else
    522       1.32  christos 			af = ifr.ifr_addr.sa_family = afs[0].af_af;
    523      1.107    itojun 		printall(NULL);
    524        1.5   deraadt 		exit(0);
    525        1.5   deraadt 	}
    526       1.24   thorpej 
    527       1.24   thorpej 	/* Make sure there's an interface name. */
    528       1.24   thorpej 	if (argc < 1)
    529       1.24   thorpej 		usage();
    530      1.140    itojun 	if (strlcpy(name, argv[0], sizeof(name)) >= sizeof(name))
    531      1.140    itojun 		errx(1, "interface name '%s' too long", argv[0]);
    532       1.24   thorpej 	argc--; argv++;
    533       1.24   thorpej 
    534       1.81   thorpej 	/*
    535       1.81   thorpej 	 * NOTE:  We must special-case the `create' command right
    536       1.81   thorpej 	 * here as we would otherwise fail in getinfo().
    537       1.81   thorpej 	 */
    538       1.81   thorpej 	if (argc > 0 && strcmp(argv[0], "create") == 0) {
    539       1.81   thorpej 		clone_create(argv[0], 0);
    540       1.81   thorpej 		argc--, argv++;
    541       1.81   thorpej 		if (argc == 0)
    542       1.81   thorpej 			exit(0);
    543       1.81   thorpej 	}
    544       1.81   thorpej 
    545       1.24   thorpej 	/* Check for address family. */
    546       1.24   thorpej 	afp = NULL;
    547       1.24   thorpej 	if (argc > 0) {
    548       1.24   thorpej 		afp = lookup_af(argv[0]);
    549       1.24   thorpej 		if (afp != NULL) {
    550       1.24   thorpej 			argv++;
    551       1.24   thorpej 			argc--;
    552       1.24   thorpej 		}
    553       1.24   thorpej 	}
    554       1.24   thorpej 
    555       1.51   thorpej 	/* Initialize af, just for use in getinfo(). */
    556       1.24   thorpej 	if (afp == NULL)
    557       1.51   thorpej 		af = afs->af_af;
    558       1.52   thorpej 	else
    559       1.52   thorpej 		af = afp->af_af;
    560       1.24   thorpej 
    561       1.24   thorpej 	/* Get information about the interface. */
    562       1.32  christos 	(void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
    563       1.13   mycroft 	if (getinfo(&ifr) < 0)
    564        1.1       cgd 		exit(1);
    565       1.24   thorpej 
    566       1.54  sommerfe 	if (sflag) {
    567       1.54  sommerfe 		if (argc != 0)
    568       1.54  sommerfe 			usage();
    569       1.54  sommerfe 		else
    570       1.54  sommerfe 			exit(carrier());
    571       1.54  sommerfe 	}
    572       1.54  sommerfe 
    573       1.24   thorpej 	/* No more arguments means interface status. */
    574       1.13   mycroft 	if (argc == 0) {
    575      1.107    itojun 		printall(name);
    576        1.5   deraadt 		exit(0);
    577        1.5   deraadt 	}
    578       1.51   thorpej 
    579       1.69     enami 	/* The following operations assume inet family as the default. */
    580       1.51   thorpej 	if (afp == NULL)
    581       1.51   thorpej 		afp = afs;
    582       1.51   thorpej 	af = ifr.ifr_addr.sa_family = afp->af_af;
    583       1.24   thorpej 
    584       1.53    itojun #ifdef INET6
    585       1.53    itojun 	/* initialization */
    586       1.53    itojun 	in6_addreq.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME;
    587       1.53    itojun 	in6_addreq.ifra_lifetime.ia6t_vltime = ND6_INFINITE_LIFETIME;
    588       1.53    itojun #endif
    589       1.53    itojun 
    590       1.24   thorpej 	/* Process commands. */
    591        1.1       cgd 	while (argc > 0) {
    592       1.80   thorpej 		const struct cmd *p;
    593        1.1       cgd 
    594        1.1       cgd 		for (p = cmds; p->c_name; p++)
    595       1.24   thorpej 			if (strcmp(argv[0], p->c_name) == 0)
    596        1.1       cgd 				break;
    597       1.55   darrenr 		if (p->c_name == 0 && setaddr) {
    598       1.57   thorpej 			if ((flags & IFF_POINTOPOINT) == 0) {
    599      1.127    itojun 				errx(EXIT_FAILURE,
    600      1.127    itojun 				    "can't set destination address %s",
    601       1.55   darrenr 				     "on non-point-to-point link");
    602       1.57   thorpej 			}
    603        1.1       cgd 			p++;	/* got src, do dst */
    604       1.55   darrenr 		}
    605       1.80   thorpej 		if (p->c_func != NULL || p->c_func2 != NULL) {
    606        1.1       cgd 			if (p->c_parameter == NEXTARG) {
    607       1.24   thorpej 				if (argc < 2)
    608      1.127    itojun 					errx(EXIT_FAILURE,
    609      1.127    itojun 					    "'%s' requires argument",
    610       1.12       cgd 					    p->c_name);
    611       1.32  christos 				(*p->c_func)(argv[1], 0);
    612        1.1       cgd 				argc--, argv++;
    613       1.80   thorpej 			} else if (p->c_parameter == NEXTARG2) {
    614       1.80   thorpej 				if (argc < 3)
    615      1.127    itojun 					errx(EXIT_FAILURE,
    616      1.127    itojun 					    "'%s' requires 2 arguments",
    617       1.80   thorpej 					    p->c_name);
    618       1.80   thorpej 				(*p->c_func2)(argv[1], argv[2]);
    619       1.80   thorpej 				argc -= 2, argv += 2;
    620        1.1       cgd 			} else
    621       1.24   thorpej 				(*p->c_func)(argv[0], p->c_parameter);
    622       1.46   thorpej 			actions |= p->c_action;
    623        1.1       cgd 		}
    624        1.1       cgd 		argc--, argv++;
    625        1.1       cgd 	}
    626       1.21       gwr 
    627      1.113     david 	/*
    628      1.113     david 	 * See if multiple alias, -alias, or delete commands were
    629      1.113     david 	 * specified. More than one constitutes an invalid command line
    630      1.113     david 	 */
    631      1.112     david 
    632      1.112     david 	if (conflicting > 1)
    633      1.120    atatat 		err(EXIT_FAILURE,
    634      1.120    atatat 		    "Only one use of alias, -alias or delete is valid.");
    635      1.112     david 
    636       1.45   thorpej 	/* Process any media commands that may have been issued. */
    637       1.45   thorpej 	process_media_commands();
    638       1.45   thorpej 
    639       1.53    itojun 	if (af == AF_INET6 && explicit_prefix == 0) {
    640       1.53    itojun 		/*
    641       1.53    itojun 		 * Aggregatable address architecture defines all prefixes
    642       1.53    itojun 		 * are 64. So, it is convenient to set prefixlen to 64 if
    643       1.53    itojun 		 * it is not specified.
    644       1.53    itojun 		 */
    645       1.53    itojun 		setifprefixlen("64", 0);
    646       1.53    itojun 		/* in6_getprefix("64", MASK) if MASK is available here... */
    647       1.53    itojun 	}
    648       1.53    itojun 
    649       1.21       gwr #ifndef INET_ONLY
    650        1.1       cgd 	if (af == AF_ISO)
    651        1.1       cgd 		adjust_nsellength();
    652       1.32  christos 
    653       1.32  christos 	if (af == AF_APPLETALK)
    654       1.32  christos 		checkatrange((struct sockaddr_at *) &addreq.ifra_addr);
    655       1.32  christos 
    656        1.1       cgd 	if (setipdst && af==AF_NS) {
    657        1.1       cgd 		struct nsip_req rq;
    658        1.1       cgd 		int size = sizeof(rq);
    659        1.1       cgd 
    660        1.1       cgd 		rq.rq_ns = addreq.ifra_addr;
    661        1.1       cgd 		rq.rq_ip = addreq.ifra_dstaddr;
    662        1.1       cgd 
    663        1.1       cgd 		if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0)
    664       1.13   mycroft 			warn("encapsulation routing");
    665        1.1       cgd 	}
    666       1.21       gwr 
    667       1.21       gwr #endif	/* INET_ONLY */
    668       1.21       gwr 
    669        1.1       cgd 	if (clearaddr) {
    670       1.32  christos 		(void) strncpy(afp->af_ridreq, name, sizeof ifr.ifr_name);
    671      1.120    atatat 		if (ioctl(s, afp->af_difaddr, afp->af_ridreq) == -1)
    672      1.120    atatat 			err(EXIT_FAILURE, "SIOCDIFADDR");
    673        1.1       cgd 	}
    674       1.36     lukem 	if (newaddr > 0) {
    675       1.32  christos 		(void) strncpy(afp->af_addreq, name, sizeof ifr.ifr_name);
    676      1.120    atatat 		if (ioctl(s, afp->af_aifaddr, afp->af_addreq) == -1)
    677       1.13   mycroft 			warn("SIOCAIFADDR");
    678        1.1       cgd 	}
    679       1.79     enami 
    680      1.108   thorpej 	if (g_ifcr_updated) {
    681      1.108   thorpej 		(void) strncpy(g_ifcr.ifcr_name, name,
    682      1.108   thorpej 		    sizeof(g_ifcr.ifcr_name));
    683      1.120    atatat 		if (ioctl(s, SIOCSIFCAP, (caddr_t) &g_ifcr) == -1)
    684      1.120    atatat 			err(EXIT_FAILURE, "SIOCSIFCAP");
    685      1.108   thorpej 	}
    686      1.108   thorpej 
    687       1.13   mycroft 	exit(0);
    688       1.13   mycroft }
    689       1.13   mycroft 
    690       1.24   thorpej struct afswtch *
    691       1.24   thorpej lookup_af(cp)
    692       1.24   thorpej 	const char *cp;
    693       1.24   thorpej {
    694       1.24   thorpej 	struct afswtch *a;
    695       1.24   thorpej 
    696       1.24   thorpej 	for (a = afs; a->af_name != NULL; a++)
    697       1.24   thorpej 		if (strcmp(a->af_name, cp) == 0)
    698       1.24   thorpej 			return (a);
    699       1.24   thorpej 	return (NULL);
    700       1.24   thorpej }
    701       1.24   thorpej 
    702       1.13   mycroft void
    703       1.13   mycroft getsock(naf)
    704       1.13   mycroft 	int naf;
    705       1.13   mycroft {
    706       1.13   mycroft 	static int oaf = -1;
    707       1.13   mycroft 
    708       1.13   mycroft 	if (oaf == naf)
    709       1.13   mycroft 		return;
    710       1.13   mycroft 	if (oaf != -1)
    711       1.13   mycroft 		close(s);
    712       1.13   mycroft 	s = socket(naf, SOCK_DGRAM, 0);
    713       1.13   mycroft 	if (s < 0)
    714       1.13   mycroft 		oaf = -1;
    715       1.13   mycroft 	else
    716       1.13   mycroft 		oaf = naf;
    717       1.13   mycroft }
    718       1.13   mycroft 
    719       1.13   mycroft int
    720      1.121     lukem getinfo(giifr)
    721      1.121     lukem 	struct ifreq *giifr;
    722       1.13   mycroft {
    723        1.5   deraadt 
    724       1.13   mycroft 	getsock(af);
    725       1.13   mycroft 	if (s < 0)
    726      1.120    atatat 		err(EXIT_FAILURE, "socket");
    727      1.121     lukem 	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)giifr) == -1) {
    728      1.121     lukem 		warn("SIOCGIFFLAGS %s", giifr->ifr_name);
    729       1.13   mycroft 		return (-1);
    730       1.13   mycroft 	}
    731      1.121     lukem 	flags = giifr->ifr_flags;
    732      1.121     lukem 	if (ioctl(s, SIOCGIFMETRIC, (caddr_t)giifr) == -1) {
    733      1.121     lukem 		warn("SIOCGIFMETRIC %s", giifr->ifr_name);
    734       1.13   mycroft 		metric = 0;
    735       1.13   mycroft 	} else
    736      1.121     lukem 		metric = giifr->ifr_metric;
    737      1.121     lukem 	if (ioctl(s, SIOCGIFMTU, (caddr_t)giifr) == -1)
    738       1.33        is 		mtu = 0;
    739       1.33        is 	else
    740      1.121     lukem 		mtu = giifr->ifr_mtu;
    741      1.108   thorpej 
    742      1.108   thorpej 	memset(&g_ifcr, 0, sizeof(g_ifcr));
    743      1.121     lukem 	strcpy(g_ifcr.ifcr_name, giifr->ifr_name);
    744      1.108   thorpej 	(void) ioctl(s, SIOCGIFCAP, (caddr_t) &g_ifcr);
    745      1.108   thorpej 
    746       1.13   mycroft 	return (0);
    747        1.1       cgd }
    748        1.5   deraadt 
    749       1.13   mycroft void
    750      1.107    itojun printall(ifname)
    751      1.107    itojun 	const char *ifname;
    752        1.5   deraadt {
    753       1.78    itojun 	struct ifaddrs *ifap, *ifa;
    754      1.121     lukem 	struct ifreq paifr;
    755       1.94    itojun 	const struct sockaddr_dl *sdl = NULL;
    756       1.78    itojun 	int idx;
    757       1.78    itojun 	char *p;
    758       1.78    itojun 
    759       1.78    itojun 	if (getifaddrs(&ifap) != 0)
    760      1.120    atatat 		err(EXIT_FAILURE, "getifaddrs");
    761       1.78    itojun 	p = NULL;
    762       1.78    itojun 	idx = 0;
    763       1.78    itojun 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
    764      1.121     lukem 		memset(&paifr, 0, sizeof(paifr));
    765      1.121     lukem 		strncpy(paifr.ifr_name, ifa->ifa_name, sizeof(paifr.ifr_name));
    766      1.121     lukem 		if (sizeof(paifr.ifr_addr) >= ifa->ifa_addr->sa_len) {
    767      1.121     lukem 			memcpy(&paifr.ifr_addr, ifa->ifa_addr,
    768       1.78    itojun 			    ifa->ifa_addr->sa_len);
    769       1.78    itojun 		}
    770       1.78    itojun 
    771      1.107    itojun 		if (ifname && strcmp(ifname, ifa->ifa_name) != 0)
    772      1.107    itojun 			continue;
    773       1.78    itojun 		if (ifa->ifa_addr->sa_family == AF_LINK)
    774       1.78    itojun 			sdl = (const struct sockaddr_dl *) ifa->ifa_addr;
    775       1.78    itojun 		if (p && strcmp(p, ifa->ifa_name) == 0)
    776       1.78    itojun 			continue;
    777      1.140    itojun 		if (strlcpy(name, ifa->ifa_name, sizeof(name)) >= sizeof(name))
    778      1.140    itojun 			continue;
    779       1.78    itojun 		p = ifa->ifa_name;
    780       1.78    itojun 
    781      1.121     lukem 		if (getinfo(&paifr) < 0)
    782       1.78    itojun 			continue;
    783      1.135     lukem 		if (bflag && (ifa->ifa_flags & IFF_BROADCAST) == 0)
    784       1.78    itojun 			continue;
    785       1.78    itojun 		if (dflag && (ifa->ifa_flags & IFF_UP) != 0)
    786       1.78    itojun 			continue;
    787       1.78    itojun 		if (uflag && (ifa->ifa_flags & IFF_UP) == 0)
    788       1.78    itojun 			continue;
    789       1.78    itojun 
    790       1.78    itojun 		if (sflag && carrier())
    791       1.78    itojun 			continue;
    792       1.78    itojun 		idx++;
    793       1.78    itojun 		/*
    794       1.78    itojun 		 * Are we just listing the interfaces?
    795       1.78    itojun 		 */
    796       1.78    itojun 		if (lflag) {
    797       1.78    itojun 			if (idx > 1)
    798       1.78    itojun 				putchar(' ');
    799       1.78    itojun 			fputs(name, stdout);
    800       1.78    itojun 			continue;
    801       1.78    itojun 		}
    802       1.78    itojun 
    803      1.119     bjh21 		status(sdl);
    804      1.119     bjh21 		sdl = NULL;
    805       1.78    itojun 	}
    806       1.78    itojun 	if (lflag)
    807       1.78    itojun 		putchar('\n');
    808       1.78    itojun 	freeifaddrs(ifap);
    809       1.87   thorpej }
    810       1.87   thorpej 
    811       1.87   thorpej void
    812       1.87   thorpej list_cloners(void)
    813       1.87   thorpej {
    814       1.87   thorpej 	struct if_clonereq ifcr;
    815       1.87   thorpej 	char *cp, *buf;
    816       1.87   thorpej 	int idx;
    817       1.87   thorpej 
    818       1.87   thorpej 	memset(&ifcr, 0, sizeof(ifcr));
    819       1.87   thorpej 
    820       1.87   thorpej 	getsock(AF_INET);
    821       1.87   thorpej 
    822      1.120    atatat 	if (ioctl(s, SIOCIFGCLONERS, &ifcr) == -1)
    823      1.120    atatat 		err(EXIT_FAILURE, "SIOCIFGCLONERS for count");
    824       1.87   thorpej 
    825       1.87   thorpej 	buf = malloc(ifcr.ifcr_total * IFNAMSIZ);
    826       1.87   thorpej 	if (buf == NULL)
    827      1.120    atatat 		err(EXIT_FAILURE, "unable to allocate cloner name buffer");
    828       1.87   thorpej 
    829       1.87   thorpej 	ifcr.ifcr_count = ifcr.ifcr_total;
    830       1.87   thorpej 	ifcr.ifcr_buffer = buf;
    831       1.87   thorpej 
    832      1.120    atatat 	if (ioctl(s, SIOCIFGCLONERS, &ifcr) == -1)
    833      1.120    atatat 		err(EXIT_FAILURE, "SIOCIFGCLONERS for names");
    834       1.87   thorpej 
    835       1.87   thorpej 	/*
    836       1.87   thorpej 	 * In case some disappeared in the mean time, clamp it down.
    837       1.87   thorpej 	 */
    838       1.87   thorpej 	if (ifcr.ifcr_count > ifcr.ifcr_total)
    839       1.87   thorpej 		ifcr.ifcr_count = ifcr.ifcr_total;
    840       1.87   thorpej 
    841       1.87   thorpej 	for (cp = buf, idx = 0; idx < ifcr.ifcr_count; idx++, cp += IFNAMSIZ) {
    842       1.87   thorpej 		if (idx > 0)
    843       1.87   thorpej 			putchar(' ');
    844       1.87   thorpej 		printf("%s", cp);
    845       1.87   thorpej 	}
    846       1.87   thorpej 
    847       1.87   thorpej 	putchar('\n');
    848       1.87   thorpej 	free(buf);
    849       1.87   thorpej 	return;
    850        1.5   deraadt }
    851        1.5   deraadt 
    852       1.81   thorpej /*ARGSUSED*/
    853       1.81   thorpej void
    854       1.81   thorpej clone_create(addr, param)
    855       1.81   thorpej 	const char *addr;
    856       1.81   thorpej 	int param;
    857       1.81   thorpej {
    858       1.81   thorpej 
    859       1.81   thorpej 	/* We're called early... */
    860       1.81   thorpej 	getsock(AF_INET);
    861       1.81   thorpej 
    862       1.81   thorpej 	(void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
    863      1.120    atatat 	if (ioctl(s, SIOCIFCREATE, &ifr) == -1)
    864      1.120    atatat 		err(EXIT_FAILURE, "SIOCIFCREATE");
    865       1.81   thorpej }
    866       1.81   thorpej 
    867       1.81   thorpej /*ARGSUSED*/
    868       1.81   thorpej void
    869       1.81   thorpej clone_destroy(addr, param)
    870       1.81   thorpej 	const char *addr;
    871       1.81   thorpej 	int param;
    872       1.81   thorpej {
    873       1.81   thorpej 
    874       1.81   thorpej 	(void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
    875      1.120    atatat 	if (ioctl(s, SIOCIFDESTROY, &ifr) == -1)
    876      1.120    atatat 		err(EXIT_FAILURE, "SIOCIFDESTROY");
    877       1.81   thorpej }
    878       1.81   thorpej 
    879        1.1       cgd #define RIDADDR 0
    880        1.1       cgd #define ADDR	1
    881        1.1       cgd #define MASK	2
    882        1.1       cgd #define DSTADDR	3
    883        1.1       cgd 
    884        1.1       cgd /*ARGSUSED*/
    885       1.16       cgd void
    886        1.1       cgd setifaddr(addr, param)
    887       1.80   thorpej 	const char *addr;
    888       1.16       cgd 	int param;
    889        1.1       cgd {
    890      1.121     lukem 	struct ifreq *siifr;		/* XXX */
    891       1.76     enami 
    892        1.1       cgd 	/*
    893        1.1       cgd 	 * Delay the ioctl to set the interface addr until flags are all set.
    894        1.1       cgd 	 * The address interpretation may depend on the flags,
    895        1.1       cgd 	 * and the flags may change when the address is set.
    896        1.1       cgd 	 */
    897        1.1       cgd 	setaddr++;
    898       1.36     lukem 	if (newaddr == -1)
    899       1.36     lukem 		newaddr = 1;
    900       1.76     enami 	if (doalias == 0 && afp->af_gifaddr != 0) {
    901      1.121     lukem 		siifr = (struct ifreq *)afp->af_ridreq;
    902      1.121     lukem 		(void) strncpy(siifr->ifr_name, name, sizeof(siifr->ifr_name));
    903      1.121     lukem 		siifr->ifr_addr.sa_family = afp->af_af;
    904       1.76     enami 		if (ioctl(s, afp->af_gifaddr, afp->af_ridreq) == 0)
    905       1.76     enami 			clearaddr = 1;
    906       1.76     enami 		else if (errno == EADDRNOTAVAIL)
    907       1.76     enami 			/* No address was assigned yet. */
    908       1.76     enami 			;
    909       1.76     enami 		else
    910      1.120    atatat 			err(EXIT_FAILURE, "SIOCGIFADDR");
    911       1.76     enami 	}
    912       1.76     enami 
    913        1.1       cgd 	(*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR));
    914        1.1       cgd }
    915        1.1       cgd 
    916       1.16       cgd void
    917       1.80   thorpej settunnel(src, dst)
    918       1.80   thorpej 	const char *src, *dst;
    919       1.80   thorpej {
    920       1.80   thorpej 	struct addrinfo hints, *srcres, *dstres;
    921       1.80   thorpej 	int ecode;
    922      1.100    itojun 	struct if_laddrreq req;
    923       1.80   thorpej 
    924       1.80   thorpej 	memset(&hints, 0, sizeof(hints));
    925       1.80   thorpej 	hints.ai_family = afp->af_af;
    926      1.102    itojun 	hints.ai_socktype = SOCK_DGRAM;	/*dummy*/
    927       1.80   thorpej 
    928      1.102    itojun 	if ((ecode = getaddrinfo(src, NULL, &hints, &srcres)) != 0)
    929      1.127    itojun 		errx(EXIT_FAILURE, "error in parsing address string: %s",
    930       1.80   thorpej 		    gai_strerror(ecode));
    931       1.80   thorpej 
    932      1.103    itojun 	if ((ecode = getaddrinfo(dst, NULL, &hints, &dstres)) != 0)
    933      1.127    itojun 		errx(EXIT_FAILURE, "error in parsing address string: %s",
    934       1.80   thorpej 		    gai_strerror(ecode));
    935       1.80   thorpej 
    936       1.80   thorpej 	if (srcres->ai_addr->sa_family != dstres->ai_addr->sa_family)
    937      1.127    itojun 		errx(EXIT_FAILURE,
    938       1.80   thorpej 		    "source and destination address families do not match");
    939       1.80   thorpej 
    940      1.100    itojun 	if (srcres->ai_addrlen > sizeof(req.addr) ||
    941      1.100    itojun 	    dstres->ai_addrlen > sizeof(req.dstaddr))
    942      1.127    itojun 		errx(EXIT_FAILURE, "invalid sockaddr");
    943      1.100    itojun 
    944      1.100    itojun 	memset(&req, 0, sizeof(req));
    945      1.100    itojun 	strncpy(req.iflr_name, name, sizeof(req.iflr_name));
    946      1.100    itojun 	memcpy(&req.addr, srcres->ai_addr, srcres->ai_addrlen);
    947      1.100    itojun 	memcpy(&req.dstaddr, dstres->ai_addr, dstres->ai_addrlen);
    948      1.111    itojun 
    949      1.111    itojun #ifdef INET6
    950      1.111    itojun 	if (req.addr.ss_family == AF_INET6) {
    951      1.121     lukem 		struct sockaddr_in6 *s6, *d;
    952      1.111    itojun 
    953      1.121     lukem 		s6 = (struct sockaddr_in6 *)&req.addr;
    954      1.111    itojun 		d = (struct sockaddr_in6 *)&req.dstaddr;
    955      1.121     lukem 		if (s6->sin6_scope_id != d->sin6_scope_id) {
    956      1.127    itojun 			errx(EXIT_FAILURE, "scope mismatch");
    957      1.111    itojun 			/* NOTREACHED */
    958      1.111    itojun 		}
    959      1.111    itojun #ifdef __KAME__
    960      1.111    itojun 		/* embed scopeid */
    961      1.121     lukem 		if (s6->sin6_scope_id &&
    962      1.121     lukem 		    (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr) ||
    963      1.121     lukem 		     IN6_IS_ADDR_MC_LINKLOCAL(&s6->sin6_addr))) {
    964      1.121     lukem 			*(u_int16_t *)&s6->sin6_addr.s6_addr[2] =
    965      1.121     lukem 			    htons(s6->sin6_scope_id);
    966      1.111    itojun 		}
    967      1.111    itojun 		if (d->sin6_scope_id &&
    968      1.111    itojun 		    (IN6_IS_ADDR_LINKLOCAL(&d->sin6_addr) ||
    969      1.111    itojun 		     IN6_IS_ADDR_MC_LINKLOCAL(&d->sin6_addr))) {
    970      1.111    itojun 			*(u_int16_t *)&d->sin6_addr.s6_addr[2] =
    971      1.111    itojun 			    htons(d->sin6_scope_id);
    972      1.111    itojun 		}
    973      1.111    itojun #endif
    974      1.111    itojun 	}
    975      1.111    itojun #endif
    976      1.111    itojun 
    977      1.120    atatat 	if (ioctl(s, SIOCSLIFPHYADDR, &req) == -1)
    978      1.100    itojun 		warn("SIOCSLIFPHYADDR");
    979       1.80   thorpej 
    980       1.80   thorpej 	freeaddrinfo(srcres);
    981       1.80   thorpej 	freeaddrinfo(dstres);
    982       1.80   thorpej }
    983       1.80   thorpej 
    984       1.80   thorpej /* ARGSUSED */
    985       1.80   thorpej void
    986       1.80   thorpej deletetunnel(vname, param)
    987       1.80   thorpej 	const char *vname;
    988       1.80   thorpej 	int param;
    989       1.80   thorpej {
    990       1.80   thorpej 
    991      1.120    atatat 	if (ioctl(s, SIOCDIFPHYADDR, &ifr) == -1)
    992      1.120    atatat 		err(EXIT_FAILURE, "SIOCDIFPHYADDR");
    993       1.80   thorpej }
    994       1.80   thorpej 
    995       1.89   thorpej void setvlan(val, d)
    996       1.89   thorpej 	const char *val;
    997       1.89   thorpej 	int d;
    998       1.89   thorpej {
    999       1.89   thorpej 	struct vlanreq vlr;
   1000       1.89   thorpej 
   1001       1.89   thorpej 	if (strncmp(ifr.ifr_name, "vlan", 4) != 0 ||
   1002       1.89   thorpej 	    !isdigit(ifr.ifr_name[4]))
   1003       1.89   thorpej 		errx(EXIT_FAILURE,
   1004       1.89   thorpej 		    "``vlan'' valid only with vlan(4) interfaces");
   1005       1.89   thorpej 
   1006       1.89   thorpej 	vlan_tag = atoi(val);
   1007       1.89   thorpej 
   1008       1.89   thorpej 	memset(&vlr, 0, sizeof(vlr));
   1009       1.89   thorpej 	ifr.ifr_data = (caddr_t)&vlr;
   1010       1.89   thorpej 
   1011       1.89   thorpej 	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
   1012       1.89   thorpej 		err(EXIT_FAILURE, "SIOCGETVLAN");
   1013       1.89   thorpej 
   1014       1.89   thorpej 	vlr.vlr_tag = vlan_tag;
   1015       1.89   thorpej 
   1016       1.89   thorpej 	if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
   1017       1.89   thorpej 		err(EXIT_FAILURE, "SIOCSETVLAN");
   1018       1.89   thorpej }
   1019       1.89   thorpej 
   1020       1.89   thorpej void setvlanif(val, d)
   1021       1.89   thorpej 	const char *val;
   1022       1.89   thorpej 	int d;
   1023       1.89   thorpej {
   1024       1.89   thorpej 	struct vlanreq vlr;
   1025       1.89   thorpej 
   1026       1.89   thorpej 	if (strncmp(ifr.ifr_name, "vlan", 4) != 0 ||
   1027       1.89   thorpej 	    !isdigit(ifr.ifr_name[4]))
   1028       1.89   thorpej 		errx(EXIT_FAILURE,
   1029       1.89   thorpej 		    "``vlanif'' valid only with vlan(4) interfaces");
   1030       1.89   thorpej 
   1031       1.89   thorpej 	if (vlan_tag == (u_int)-1)
   1032       1.89   thorpej 		errx(EXIT_FAILURE,
   1033       1.89   thorpej 		    "must specify both ``vlan'' and ``vlanif''");
   1034       1.89   thorpej 
   1035       1.89   thorpej 	memset(&vlr, 0, sizeof(vlr));
   1036       1.89   thorpej 	ifr.ifr_data = (caddr_t)&vlr;
   1037       1.89   thorpej 
   1038       1.89   thorpej 	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
   1039       1.89   thorpej 		err(EXIT_FAILURE, "SIOCGETVLAN");
   1040       1.89   thorpej 
   1041       1.89   thorpej 	strlcpy(vlr.vlr_parent, val, sizeof(vlr.vlr_parent));
   1042       1.89   thorpej 	vlr.vlr_tag = vlan_tag;
   1043       1.89   thorpej 
   1044       1.89   thorpej 	if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
   1045       1.89   thorpej 		err(EXIT_FAILURE, "SIOCSETVLAN");
   1046       1.89   thorpej }
   1047       1.89   thorpej 
   1048       1.89   thorpej void unsetvlanif(val, d)
   1049       1.89   thorpej 	const char *val;
   1050       1.89   thorpej 	int d;
   1051       1.89   thorpej {
   1052       1.89   thorpej 	struct vlanreq vlr;
   1053       1.89   thorpej 
   1054       1.89   thorpej 	if (strncmp(ifr.ifr_name, "vlan", 4) != 0 ||
   1055       1.89   thorpej 	    !isdigit(ifr.ifr_name[4]))
   1056       1.89   thorpej 		errx(EXIT_FAILURE,
   1057       1.89   thorpej 		    "``vlanif'' valid only with vlan(4) interfaces");
   1058       1.89   thorpej 
   1059       1.89   thorpej 	memset(&vlr, 0, sizeof(vlr));
   1060       1.89   thorpej 	ifr.ifr_data = (caddr_t)&vlr;
   1061       1.89   thorpej 
   1062       1.89   thorpej 	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
   1063       1.89   thorpej 		err(EXIT_FAILURE, "SIOCGETVLAN");
   1064       1.89   thorpej 
   1065       1.89   thorpej 	vlr.vlr_parent[0] = '\0';
   1066       1.89   thorpej 	vlr.vlr_tag = 0;
   1067       1.89   thorpej 
   1068       1.89   thorpej 	if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
   1069       1.89   thorpej 		err(EXIT_FAILURE, "SIOCSETVLAN");
   1070       1.89   thorpej }
   1071       1.89   thorpej 
   1072       1.80   thorpej void
   1073       1.32  christos setifnetmask(addr, d)
   1074       1.80   thorpej 	const char *addr;
   1075       1.32  christos 	int d;
   1076        1.1       cgd {
   1077        1.1       cgd 	(*afp->af_getaddr)(addr, MASK);
   1078        1.1       cgd }
   1079        1.1       cgd 
   1080       1.16       cgd void
   1081       1.32  christos setifbroadaddr(addr, d)
   1082       1.80   thorpej 	const char *addr;
   1083       1.32  christos 	int d;
   1084        1.1       cgd {
   1085        1.1       cgd 	(*afp->af_getaddr)(addr, DSTADDR);
   1086        1.1       cgd }
   1087        1.1       cgd 
   1088       1.16       cgd void
   1089       1.32  christos setifipdst(addr, d)
   1090       1.80   thorpej 	const char *addr;
   1091       1.32  christos 	int d;
   1092        1.1       cgd {
   1093        1.1       cgd 	in_getaddr(addr, DSTADDR);
   1094        1.1       cgd 	setipdst++;
   1095        1.1       cgd 	clearaddr = 0;
   1096        1.1       cgd 	newaddr = 0;
   1097        1.1       cgd }
   1098       1.16       cgd 
   1099        1.1       cgd #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
   1100        1.1       cgd /*ARGSUSED*/
   1101       1.16       cgd void
   1102        1.1       cgd notealias(addr, param)
   1103       1.80   thorpej 	const char *addr;
   1104       1.16       cgd 	int param;
   1105        1.1       cgd {
   1106        1.1       cgd 	if (setaddr && doalias == 0 && param < 0)
   1107       1.32  christos 		(void) memcpy(rqtosa(af_ridreq), rqtosa(af_addreq),
   1108       1.32  christos 		    rqtosa(af_addreq)->sa_len);
   1109        1.1       cgd 	doalias = param;
   1110        1.1       cgd 	if (param < 0) {
   1111        1.1       cgd 		clearaddr = 1;
   1112        1.1       cgd 		newaddr = 0;
   1113      1.112     david 		conflicting++;
   1114      1.113     david 	} else {
   1115        1.1       cgd 		clearaddr = 0;
   1116      1.112     david 		conflicting++;
   1117      1.113     david 	}
   1118        1.1       cgd }
   1119        1.1       cgd 
   1120        1.1       cgd /*ARGSUSED*/
   1121       1.16       cgd void
   1122       1.13   mycroft notrailers(vname, value)
   1123       1.80   thorpej 	const char *vname;
   1124       1.13   mycroft 	int value;
   1125       1.13   mycroft {
   1126       1.34     lukem 	puts("Note: trailers are no longer sent, but always received");
   1127       1.13   mycroft }
   1128       1.13   mycroft 
   1129       1.13   mycroft /*ARGSUSED*/
   1130       1.16       cgd void
   1131        1.1       cgd setifdstaddr(addr, param)
   1132       1.80   thorpej 	const char *addr;
   1133        1.1       cgd 	int param;
   1134        1.1       cgd {
   1135        1.1       cgd 	(*afp->af_getaddr)(addr, DSTADDR);
   1136        1.1       cgd }
   1137        1.1       cgd 
   1138       1.16       cgd void
   1139        1.1       cgd setifflags(vname, value)
   1140       1.80   thorpej 	const char *vname;
   1141       1.16       cgd 	int value;
   1142        1.1       cgd {
   1143       1.79     enami 	struct ifreq ifreq;
   1144       1.79     enami 
   1145       1.79     enami 	(void) strncpy(ifreq.ifr_name, name, sizeof(ifreq.ifr_name));
   1146      1.120    atatat  	if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifreq) == -1)
   1147      1.120    atatat 		err(EXIT_FAILURE, "SIOCGIFFLAGS");
   1148       1.79     enami  	flags = ifreq.ifr_flags;
   1149        1.1       cgd 
   1150        1.1       cgd 	if (value < 0) {
   1151        1.1       cgd 		value = -value;
   1152        1.1       cgd 		flags &= ~value;
   1153        1.1       cgd 	} else
   1154        1.1       cgd 		flags |= value;
   1155       1.79     enami 	ifreq.ifr_flags = flags;
   1156      1.120    atatat 	if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifreq) == -1)
   1157      1.120    atatat 		err(EXIT_FAILURE, "SIOCSIFFLAGS");
   1158        1.1       cgd }
   1159        1.1       cgd 
   1160      1.108   thorpej void
   1161      1.108   thorpej setifcaps(vname, value)
   1162      1.108   thorpej 	const char *vname;
   1163      1.108   thorpej 	int value;
   1164      1.108   thorpej {
   1165      1.108   thorpej 
   1166      1.108   thorpej 	if (value < 0) {
   1167      1.108   thorpej 		value = -value;
   1168      1.108   thorpej 		g_ifcr.ifcr_capenable &= ~value;
   1169      1.108   thorpej 	} else
   1170      1.108   thorpej 		g_ifcr.ifcr_capenable |= value;
   1171      1.108   thorpej 
   1172      1.108   thorpej 	g_ifcr_updated = 1;
   1173      1.108   thorpej }
   1174      1.108   thorpej 
   1175       1.53    itojun #ifdef INET6
   1176       1.53    itojun void
   1177       1.53    itojun setia6flags(vname, value)
   1178       1.80   thorpej 	const char *vname;
   1179       1.53    itojun 	int value;
   1180       1.53    itojun {
   1181      1.125    itojun 
   1182       1.53    itojun 	if (value < 0) {
   1183       1.53    itojun 		value = -value;
   1184       1.53    itojun 		in6_addreq.ifra_flags &= ~value;
   1185       1.53    itojun 	} else
   1186       1.53    itojun 		in6_addreq.ifra_flags |= value;
   1187       1.53    itojun }
   1188       1.53    itojun 
   1189       1.53    itojun void
   1190       1.53    itojun setia6pltime(val, d)
   1191       1.80   thorpej 	const char *val;
   1192       1.53    itojun 	int d;
   1193       1.53    itojun {
   1194      1.125    itojun 
   1195       1.53    itojun 	setia6lifetime("pltime", val);
   1196       1.53    itojun }
   1197       1.53    itojun 
   1198       1.53    itojun void
   1199       1.53    itojun setia6vltime(val, d)
   1200       1.80   thorpej 	const char *val;
   1201       1.53    itojun 	int d;
   1202       1.53    itojun {
   1203      1.125    itojun 
   1204       1.53    itojun 	setia6lifetime("vltime", val);
   1205       1.53    itojun }
   1206       1.53    itojun 
   1207       1.53    itojun void
   1208       1.53    itojun setia6lifetime(cmd, val)
   1209       1.80   thorpej 	const char *cmd;
   1210       1.80   thorpej 	const char *val;
   1211       1.53    itojun {
   1212       1.53    itojun 	time_t newval, t;
   1213       1.53    itojun 	char *ep;
   1214       1.53    itojun 
   1215       1.53    itojun 	t = time(NULL);
   1216       1.53    itojun 	newval = (time_t)strtoul(val, &ep, 0);
   1217       1.53    itojun 	if (val == ep)
   1218      1.127    itojun 		errx(EXIT_FAILURE, "invalid %s", cmd);
   1219       1.53    itojun 	if (afp->af_af != AF_INET6)
   1220      1.127    itojun 		errx(EXIT_FAILURE, "%s not allowed for the AF", cmd);
   1221       1.53    itojun 	if (strcmp(cmd, "vltime") == 0) {
   1222       1.53    itojun 		in6_addreq.ifra_lifetime.ia6t_expire = t + newval;
   1223       1.53    itojun 		in6_addreq.ifra_lifetime.ia6t_vltime = newval;
   1224       1.53    itojun 	} else if (strcmp(cmd, "pltime") == 0) {
   1225       1.53    itojun 		in6_addreq.ifra_lifetime.ia6t_preferred = t + newval;
   1226       1.53    itojun 		in6_addreq.ifra_lifetime.ia6t_pltime = newval;
   1227       1.53    itojun 	}
   1228       1.53    itojun }
   1229      1.127    itojun 
   1230      1.127    itojun void
   1231      1.127    itojun setia6eui64(cmd, val)
   1232      1.127    itojun 	const char *cmd;
   1233      1.127    itojun 	int val;
   1234      1.127    itojun {
   1235      1.127    itojun 	struct ifaddrs *ifap, *ifa;
   1236      1.127    itojun 	const struct sockaddr_in6 *sin6 = NULL;
   1237      1.127    itojun 	const struct in6_addr *lladdr = NULL;
   1238      1.127    itojun 	struct in6_addr *in6;
   1239      1.127    itojun 
   1240      1.127    itojun 	if (afp->af_af != AF_INET6)
   1241      1.127    itojun 		errx(EXIT_FAILURE, "%s not allowed for the AF", cmd);
   1242      1.127    itojun  	in6 = (struct in6_addr *)&in6_addreq.ifra_addr.sin6_addr;
   1243      1.127    itojun 	if (memcmp(&in6addr_any.s6_addr[8], &in6->s6_addr[8], 8) != 0)
   1244      1.127    itojun 		errx(EXIT_FAILURE, "interface index is already filled");
   1245      1.127    itojun 	if (getifaddrs(&ifap) != 0)
   1246      1.127    itojun 		err(EXIT_FAILURE, "getifaddrs");
   1247      1.127    itojun 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
   1248      1.128    itojun 		if (ifa->ifa_addr->sa_family == AF_INET6 &&
   1249      1.128    itojun 		    strcmp(ifa->ifa_name, name) == 0) {
   1250      1.127    itojun 			sin6 = (const struct sockaddr_in6 *)ifa->ifa_addr;
   1251      1.127    itojun 			if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
   1252      1.127    itojun 				lladdr = &sin6->sin6_addr;
   1253      1.127    itojun 				break;
   1254      1.127    itojun 			}
   1255      1.127    itojun 		}
   1256      1.127    itojun 	}
   1257      1.127    itojun 	if (!lladdr)
   1258      1.127    itojun 		errx(EXIT_FAILURE, "could not determine link local address");
   1259      1.127    itojun 
   1260      1.127    itojun  	memcpy(&in6->s6_addr[8], &lladdr->s6_addr[8], 8);
   1261      1.127    itojun 
   1262      1.127    itojun 	freeifaddrs(ifap);
   1263      1.127    itojun }
   1264       1.53    itojun #endif
   1265       1.53    itojun 
   1266       1.16       cgd void
   1267       1.32  christos setifmetric(val, d)
   1268       1.80   thorpej 	const char *val;
   1269       1.32  christos 	int d;
   1270        1.1       cgd {
   1271      1.126    itojun 	char *ep = NULL;
   1272      1.125    itojun 
   1273       1.32  christos 	(void) strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
   1274      1.125    itojun 	ifr.ifr_metric = strtoul(val, &ep, 10);
   1275      1.125    itojun 	if (!ep || *ep)
   1276      1.127    itojun 		errx(EXIT_FAILURE, "%s: invalid metric", val);
   1277      1.120    atatat 	if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) == -1)
   1278       1.13   mycroft 		warn("SIOCSIFMETRIC");
   1279        1.1       cgd }
   1280        1.1       cgd 
   1281       1.24   thorpej void
   1282       1.33        is setifmtu(val, d)
   1283       1.80   thorpej 	const char *val;
   1284       1.33        is 	int d;
   1285       1.33        is {
   1286      1.126    itojun 	char *ep = NULL;
   1287      1.125    itojun 
   1288       1.33        is 	(void)strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
   1289      1.125    itojun 	ifr.ifr_mtu = strtoul(val, &ep, 10);
   1290      1.125    itojun 	if (!ep || *ep)
   1291      1.127    itojun 		errx(EXIT_FAILURE, "%s: invalid mtu", val);
   1292      1.120    atatat 	if (ioctl(s, SIOCSIFMTU, (caddr_t)&ifr) == -1)
   1293       1.33        is 		warn("SIOCSIFMTU");
   1294       1.33        is }
   1295       1.33        is 
   1296       1.88      onoe const char *
   1297       1.88      onoe get_string(val, sep, buf, lenp)
   1298       1.88      onoe 	const char *val, *sep;
   1299       1.88      onoe 	u_int8_t *buf;
   1300       1.88      onoe 	int *lenp;
   1301       1.62    chopps {
   1302       1.85      onoe 	int len;
   1303       1.88      onoe 	int hexstr;
   1304       1.82      onoe 	u_int8_t *p;
   1305       1.62    chopps 
   1306       1.88      onoe 	len = *lenp;
   1307       1.88      onoe 	p = buf;
   1308       1.88      onoe 	hexstr = (val[0] == '0' && tolower((u_char)val[1]) == 'x');
   1309       1.88      onoe 	if (hexstr)
   1310       1.82      onoe 		val += 2;
   1311       1.88      onoe 	for (;;) {
   1312       1.88      onoe 		if (*val == '\0')
   1313       1.88      onoe 			break;
   1314       1.88      onoe 		if (sep != NULL && strchr(sep, *val) != NULL) {
   1315       1.88      onoe 			val++;
   1316       1.88      onoe 			break;
   1317       1.88      onoe 		}
   1318       1.88      onoe 		if (hexstr) {
   1319       1.88      onoe 			if (!isxdigit((u_char)val[0]) ||
   1320       1.88      onoe 			    !isxdigit((u_char)val[1])) {
   1321       1.88      onoe 				warnx("bad hexadecimal digits");
   1322       1.88      onoe 				return NULL;
   1323       1.85      onoe 			}
   1324       1.88      onoe 		}
   1325       1.88      onoe 		if (p > buf + len) {
   1326       1.88      onoe 			if (hexstr)
   1327       1.88      onoe 				warnx("hexadecimal digits too long");
   1328       1.88      onoe 			else
   1329       1.88      onoe 				warnx("strings too long");
   1330       1.88      onoe 			return NULL;
   1331       1.88      onoe 		}
   1332       1.88      onoe 		if (hexstr) {
   1333       1.82      onoe #define	tohex(x)	(isdigit(x) ? (x) - '0' : tolower(x) - 'a' + 10)
   1334       1.84      onoe 			*p++ = (tohex((u_char)val[0]) << 4) |
   1335       1.84      onoe 			    tohex((u_char)val[1]);
   1336       1.82      onoe #undef tohex
   1337       1.82      onoe 			val += 2;
   1338       1.88      onoe 		} else
   1339       1.88      onoe 			*p++ = *val++;
   1340       1.88      onoe 	}
   1341       1.88      onoe 	len = p - buf;
   1342       1.88      onoe 	if (len < *lenp)
   1343       1.88      onoe 		memset(p, 0, *lenp - len);
   1344       1.88      onoe 	*lenp = len;
   1345       1.88      onoe 	return val;
   1346       1.88      onoe }
   1347       1.88      onoe 
   1348       1.88      onoe void
   1349       1.88      onoe print_string(buf, len)
   1350       1.88      onoe 	const u_int8_t *buf;
   1351       1.88      onoe 	int len;
   1352       1.88      onoe {
   1353       1.88      onoe 	int i;
   1354       1.88      onoe 	int hasspc;
   1355       1.88      onoe 
   1356       1.88      onoe 	i = 0;
   1357       1.88      onoe 	hasspc = 0;
   1358       1.88      onoe 	if (len < 2 || buf[0] != '0' || tolower(buf[1]) != 'x') {
   1359       1.88      onoe 		for (; i < len; i++) {
   1360       1.88      onoe 			if (!isprint(buf[i]))
   1361       1.88      onoe 				break;
   1362       1.88      onoe 			if (isspace(buf[i]))
   1363       1.88      onoe 				hasspc++;
   1364       1.88      onoe 		}
   1365       1.88      onoe 	}
   1366       1.88      onoe 	if (i == len) {
   1367       1.88      onoe 		if (hasspc || len == 0)
   1368       1.88      onoe 			printf("\"%.*s\"", len, buf);
   1369       1.88      onoe 		else
   1370       1.88      onoe 			printf("%.*s", len, buf);
   1371       1.88      onoe 	} else {
   1372       1.88      onoe 		printf("0x");
   1373       1.88      onoe 		for (i = 0; i < len; i++)
   1374       1.88      onoe 			printf("%02x", buf[i]);
   1375       1.88      onoe 	}
   1376       1.88      onoe }
   1377       1.88      onoe 
   1378       1.88      onoe void
   1379       1.88      onoe setifnwid(val, d)
   1380       1.88      onoe 	const char *val;
   1381       1.88      onoe 	int d;
   1382       1.88      onoe {
   1383       1.88      onoe 	struct ieee80211_nwid nwid;
   1384       1.88      onoe 	int len;
   1385       1.88      onoe 
   1386       1.88      onoe 	len = sizeof(nwid.i_nwid);
   1387       1.88      onoe 	if (get_string(val, NULL, nwid.i_nwid, &len) == NULL)
   1388       1.88      onoe 		return;
   1389       1.88      onoe 	nwid.i_len = len;
   1390       1.88      onoe 	(void)strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
   1391       1.88      onoe 	ifr.ifr_data = (caddr_t)&nwid;
   1392      1.120    atatat 	if (ioctl(s, SIOCS80211NWID, (caddr_t)&ifr) == -1)
   1393       1.88      onoe 		warn("SIOCS80211NWID");
   1394       1.88      onoe }
   1395       1.88      onoe 
   1396       1.88      onoe void
   1397      1.131   thorpej setifbssid(val, d)
   1398      1.131   thorpej 	const char *val;
   1399      1.131   thorpej 	int d;
   1400      1.131   thorpej {
   1401      1.131   thorpej 	struct ieee80211_bssid bssid;
   1402      1.131   thorpej 	struct ether_addr *ea;
   1403      1.131   thorpej 
   1404      1.131   thorpej 	if (d != 0) {
   1405      1.131   thorpej 		/* no BSSID is especially desired */
   1406      1.131   thorpej 		memset(&bssid.i_bssid, 0, sizeof(bssid.i_bssid));
   1407      1.131   thorpej 	} else {
   1408      1.131   thorpej 		ea = ether_aton(val);
   1409      1.131   thorpej 		if (ea == NULL) {
   1410      1.131   thorpej 			warnx("malformed BSSID: %s", val);
   1411      1.131   thorpej 			return;
   1412      1.131   thorpej 		}
   1413      1.131   thorpej 		memcpy(&bssid.i_bssid, ea->ether_addr_octet,
   1414      1.131   thorpej 		    sizeof(bssid.i_bssid));
   1415      1.131   thorpej 	}
   1416      1.131   thorpej 	(void)strncpy(bssid.i_name, name, sizeof(bssid.i_name));
   1417      1.131   thorpej 	if (ioctl(s, SIOCS80211BSSID, (caddr_t)&bssid) == -1)
   1418      1.131   thorpej 		warn("SIOCS80211BSSID");
   1419      1.131   thorpej }
   1420      1.131   thorpej 
   1421      1.131   thorpej void
   1422      1.131   thorpej setifchan(val, d)
   1423      1.131   thorpej 	const char *val;
   1424      1.131   thorpej 	int d;
   1425      1.131   thorpej {
   1426      1.139    dyoung 	struct ieee80211chanreq channel;
   1427      1.131   thorpej 	int chan;
   1428      1.131   thorpej 
   1429      1.133      onoe 	if (d != 0)
   1430      1.133      onoe 		chan = IEEE80211_CHAN_ANY;
   1431      1.133      onoe 	else {
   1432      1.133      onoe 		chan = atoi(val);
   1433      1.133      onoe 		if (chan < 0 || chan > 0xffff) {
   1434      1.133      onoe 			warnx("invalid channel: %s", val);
   1435      1.133      onoe 			return;
   1436      1.133      onoe 		}
   1437      1.131   thorpej 	}
   1438      1.131   thorpej 
   1439      1.131   thorpej 	(void)strncpy(channel.i_name, name, sizeof(channel.i_name));
   1440      1.131   thorpej 	channel.i_channel = (u_int16_t) chan;
   1441      1.131   thorpej 	if (ioctl(s, SIOCS80211CHANNEL, (caddr_t)&channel) == -1)
   1442      1.131   thorpej 		warn("SIOCS80211CHANNEL");
   1443      1.131   thorpej }
   1444      1.131   thorpej 
   1445      1.131   thorpej void
   1446       1.88      onoe setifnwkey(val, d)
   1447       1.88      onoe 	const char *val;
   1448       1.88      onoe 	int d;
   1449       1.88      onoe {
   1450       1.88      onoe 	struct ieee80211_nwkey nwkey;
   1451       1.88      onoe 	int i;
   1452       1.88      onoe 	u_int8_t keybuf[IEEE80211_WEP_NKID][16];
   1453       1.88      onoe 
   1454      1.109      onoe 	nwkey.i_wepon = IEEE80211_NWKEY_WEP;
   1455       1.88      onoe 	nwkey.i_defkid = 1;
   1456       1.88      onoe 	for (i = 0; i < IEEE80211_WEP_NKID; i++) {
   1457       1.88      onoe 		nwkey.i_key[i].i_keylen = sizeof(keybuf[i]);
   1458       1.88      onoe 		nwkey.i_key[i].i_keydat = keybuf[i];
   1459       1.88      onoe 	}
   1460       1.88      onoe 	if (d != 0) {
   1461       1.88      onoe 		/* disable WEP encryption */
   1462       1.88      onoe 		nwkey.i_wepon = 0;
   1463       1.88      onoe 		i = 0;
   1464      1.109      onoe 	} else if (strcasecmp("persist", val) == 0) {
   1465      1.109      onoe 		/* use all values from persistent memory */
   1466      1.109      onoe 		nwkey.i_wepon |= IEEE80211_NWKEY_PERSIST;
   1467      1.109      onoe 		nwkey.i_defkid = 0;
   1468      1.109      onoe 		for (i = 0; i < IEEE80211_WEP_NKID; i++)
   1469      1.109      onoe 			nwkey.i_key[i].i_keylen = -1;
   1470      1.109      onoe 	} else if (strncasecmp("persist:", val, 8) == 0) {
   1471      1.109      onoe 		val += 8;
   1472      1.109      onoe 		/* program keys in persistent memory */
   1473      1.109      onoe 		nwkey.i_wepon |= IEEE80211_NWKEY_PERSIST;
   1474      1.109      onoe 		goto set_nwkey;
   1475      1.109      onoe 	} else {
   1476      1.109      onoe   set_nwkey:
   1477      1.109      onoe 		if (isdigit(val[0]) && val[1] == ':') {
   1478      1.109      onoe 			/* specifying a full set of four keys */
   1479      1.109      onoe 			nwkey.i_defkid = val[0] - '0';
   1480      1.109      onoe 			val += 2;
   1481      1.109      onoe 			for (i = 0; i < IEEE80211_WEP_NKID; i++) {
   1482      1.109      onoe 				val = get_string(val, ",", keybuf[i],
   1483      1.109      onoe 				    &nwkey.i_key[i].i_keylen);
   1484      1.109      onoe 				if (val == NULL)
   1485      1.109      onoe 					return;
   1486      1.109      onoe 			}
   1487      1.109      onoe 			if (*val != '\0') {
   1488      1.109      onoe 				warnx("SIOCS80211NWKEY: too many keys.");
   1489      1.109      onoe 				return;
   1490      1.109      onoe 			}
   1491      1.109      onoe 		} else {
   1492      1.109      onoe 			val = get_string(val, NULL, keybuf[0],
   1493      1.109      onoe 			    &nwkey.i_key[0].i_keylen);
   1494       1.88      onoe 			if (val == NULL)
   1495       1.88      onoe 				return;
   1496      1.109      onoe 			i = 1;
   1497       1.82      onoe 		}
   1498       1.82      onoe 	}
   1499       1.88      onoe 	for (; i < IEEE80211_WEP_NKID; i++)
   1500       1.88      onoe 		nwkey.i_key[i].i_keylen = 0;
   1501       1.88      onoe 	(void)strncpy(nwkey.i_name, name, sizeof(nwkey.i_name));
   1502      1.120    atatat 	if (ioctl(s, SIOCS80211NWKEY, (caddr_t)&nwkey) == -1)
   1503       1.88      onoe 		warn("SIOCS80211NWKEY");
   1504       1.62    chopps }
   1505       1.62    chopps 
   1506       1.62    chopps void
   1507       1.92   thorpej setifpowersave(val, d)
   1508       1.92   thorpej 	const char *val;
   1509       1.92   thorpej 	int d;
   1510       1.92   thorpej {
   1511       1.92   thorpej 	struct ieee80211_power power;
   1512       1.92   thorpej 
   1513       1.92   thorpej 	(void)strncpy(power.i_name, name, sizeof(power.i_name));
   1514      1.120    atatat 	if (ioctl(s, SIOCG80211POWER, (caddr_t)&power) == -1) {
   1515       1.92   thorpej 		warn("SIOCG80211POWER");
   1516       1.92   thorpej 		return;
   1517       1.92   thorpej 	}
   1518       1.92   thorpej 
   1519       1.92   thorpej 	power.i_enabled = d;
   1520      1.120    atatat 	if (ioctl(s, SIOCS80211POWER, (caddr_t)&power) == -1)
   1521       1.92   thorpej 		warn("SIOCS80211POWER");
   1522       1.92   thorpej }
   1523       1.92   thorpej 
   1524       1.92   thorpej void
   1525       1.92   thorpej setifpowersavesleep(val, d)
   1526       1.92   thorpej 	const char *val;
   1527       1.92   thorpej 	int d;
   1528       1.92   thorpej {
   1529       1.92   thorpej 	struct ieee80211_power power;
   1530       1.92   thorpej 
   1531       1.92   thorpej 	(void)strncpy(power.i_name, name, sizeof(power.i_name));
   1532      1.120    atatat 	if (ioctl(s, SIOCG80211POWER, (caddr_t)&power) == -1) {
   1533       1.92   thorpej 		warn("SIOCG80211POWER");
   1534       1.92   thorpej 		return;
   1535       1.92   thorpej 	}
   1536       1.92   thorpej 
   1537       1.92   thorpej 	power.i_maxsleep = atoi(val);
   1538      1.120    atatat 	if (ioctl(s, SIOCS80211POWER, (caddr_t)&power) == -1)
   1539       1.92   thorpej 		warn("SIOCS80211POWER");
   1540       1.92   thorpej }
   1541       1.92   thorpej 
   1542       1.92   thorpej void
   1543       1.62    chopps ieee80211_status()
   1544       1.62    chopps {
   1545      1.109      onoe 	int i, nwkey_verbose;
   1546       1.82      onoe 	struct ieee80211_nwid nwid;
   1547       1.88      onoe 	struct ieee80211_nwkey nwkey;
   1548       1.92   thorpej 	struct ieee80211_power power;
   1549       1.88      onoe 	u_int8_t keybuf[IEEE80211_WEP_NKID][16];
   1550      1.131   thorpej 	struct ieee80211_bssid bssid;
   1551      1.139    dyoung 	struct ieee80211chanreq channel;
   1552      1.131   thorpej 	struct ether_addr ea;
   1553      1.133      onoe 	static const u_int8_t zero_macaddr[IEEE80211_ADDR_LEN];
   1554       1.62    chopps 
   1555       1.62    chopps 	memset(&ifr, 0, sizeof(ifr));
   1556       1.82      onoe 	ifr.ifr_data = (caddr_t)&nwid;
   1557       1.62    chopps 	(void)strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
   1558      1.120    atatat 	if (ioctl(s, SIOCG80211NWID, (caddr_t)&ifr) == -1)
   1559       1.82      onoe 		return;
   1560       1.83      onoe 	if (nwid.i_len > IEEE80211_NWID_LEN) {
   1561       1.86     enami 		warnx("SIOCG80211NWID: wrong length of nwid (%d)", nwid.i_len);
   1562       1.83      onoe 		return;
   1563       1.83      onoe 	}
   1564      1.141     perry 	printf("\tssid ");
   1565       1.88      onoe 	print_string(nwid.i_nwid, nwid.i_len);
   1566       1.88      onoe 	memset(&nwkey, 0, sizeof(nwkey));
   1567       1.88      onoe 	(void)strncpy(nwkey.i_name, name, sizeof(nwkey.i_name));
   1568       1.88      onoe 	/* show nwkey only when WEP is enabled */
   1569      1.120    atatat 	if (ioctl(s, SIOCG80211NWKEY, (caddr_t)&nwkey) == -1 ||
   1570       1.88      onoe 	    nwkey.i_wepon == 0) {
   1571       1.88      onoe 		printf("\n");
   1572       1.92   thorpej 		goto skip_wep;
   1573       1.88      onoe 	}
   1574       1.88      onoe 
   1575       1.88      onoe 	printf(" nwkey ");
   1576       1.88      onoe 	/* try to retrieve WEP keys */
   1577       1.88      onoe 	for (i = 0; i < IEEE80211_WEP_NKID; i++) {
   1578       1.88      onoe 		nwkey.i_key[i].i_keydat = keybuf[i];
   1579       1.88      onoe 		nwkey.i_key[i].i_keylen = sizeof(keybuf[i]);
   1580       1.88      onoe 	}
   1581      1.120    atatat 	if (ioctl(s, SIOCG80211NWKEY, (caddr_t)&nwkey) == -1) {
   1582       1.88      onoe 		printf("*****");
   1583       1.88      onoe 	} else {
   1584      1.109      onoe 		nwkey_verbose = 0;
   1585      1.109      onoe 		/* check to see non default key or multiple keys defined */
   1586       1.88      onoe 		if (nwkey.i_defkid != 1) {
   1587      1.109      onoe 			nwkey_verbose = 1;
   1588       1.88      onoe 		} else {
   1589       1.88      onoe 			for (i = 1; i < IEEE80211_WEP_NKID; i++) {
   1590      1.109      onoe 				if (nwkey.i_key[i].i_keylen != 0) {
   1591      1.109      onoe 					nwkey_verbose = 1;
   1592       1.88      onoe 					break;
   1593      1.109      onoe 				}
   1594       1.88      onoe 			}
   1595       1.88      onoe 		}
   1596      1.109      onoe 		/* check extra ambiguity with keywords */
   1597      1.109      onoe 		if (!nwkey_verbose) {
   1598      1.109      onoe 			if (nwkey.i_key[0].i_keylen >= 2 &&
   1599      1.109      onoe 			    isdigit(nwkey.i_key[0].i_keydat[0]) &&
   1600      1.109      onoe 			    nwkey.i_key[0].i_keydat[1] == ':')
   1601      1.109      onoe 				nwkey_verbose = 1;
   1602      1.109      onoe 			else if (nwkey.i_key[0].i_keylen >= 7 &&
   1603      1.109      onoe 			    strncasecmp("persist", nwkey.i_key[0].i_keydat, 7)
   1604      1.109      onoe 			    == 0)
   1605      1.109      onoe 				nwkey_verbose = 1;
   1606      1.109      onoe 		}
   1607      1.109      onoe 		if (nwkey_verbose)
   1608       1.88      onoe 			printf("%d:", nwkey.i_defkid);
   1609      1.109      onoe 		for (i = 0; i < IEEE80211_WEP_NKID; i++) {
   1610      1.109      onoe 			if (i > 0)
   1611      1.109      onoe 				printf(",");
   1612      1.109      onoe 			if (nwkey.i_key[i].i_keylen < 0)
   1613      1.109      onoe 				printf("persist");
   1614      1.109      onoe 			else
   1615       1.88      onoe 				print_string(nwkey.i_key[i].i_keydat,
   1616       1.88      onoe 				    nwkey.i_key[i].i_keylen);
   1617      1.109      onoe 			if (!nwkey_verbose)
   1618      1.109      onoe 				break;
   1619       1.82      onoe 		}
   1620       1.82      onoe 	}
   1621       1.92   thorpej 	printf("\n");
   1622       1.92   thorpej 
   1623       1.92   thorpej  skip_wep:
   1624       1.92   thorpej 	(void)strncpy(power.i_name, name, sizeof(power.i_name));
   1625      1.120    atatat 	if (ioctl(s, SIOCG80211POWER, &power) == -1)
   1626      1.131   thorpej 		goto skip_power;
   1627       1.92   thorpej 	printf("\tpowersave ");
   1628       1.92   thorpej 	if (power.i_enabled)
   1629       1.92   thorpej 		printf("on (%dms sleep)", power.i_maxsleep);
   1630       1.92   thorpej 	else
   1631       1.92   thorpej 		printf("off");
   1632       1.88      onoe 	printf("\n");
   1633      1.131   thorpej 
   1634      1.131   thorpej  skip_power:
   1635      1.131   thorpej 	(void)strncpy(bssid.i_name, name, sizeof(bssid.i_name));
   1636      1.131   thorpej 	if (ioctl(s, SIOCG80211BSSID, &bssid) == -1)
   1637      1.131   thorpej 		return;
   1638      1.131   thorpej 	(void)strncpy(channel.i_name, name, sizeof(channel.i_name));
   1639      1.131   thorpej 	if (ioctl(s, SIOCG80211CHANNEL, &channel) == -1)
   1640      1.131   thorpej 		return;
   1641      1.133      onoe 	if (memcmp(bssid.i_bssid, zero_macaddr, IEEE80211_ADDR_LEN) == 0) {
   1642      1.133      onoe 		if (channel.i_channel != (u_int16_t)-1)
   1643      1.133      onoe 			printf("\tchan %d\n", channel.i_channel);
   1644      1.133      onoe 	} else {
   1645      1.133      onoe 		memcpy(ea.ether_addr_octet, bssid.i_bssid,
   1646      1.133      onoe 		    sizeof(ea.ether_addr_octet));
   1647      1.133      onoe 		printf("\tbssid %s", ether_ntoa(&ea));
   1648      1.133      onoe 		if (channel.i_channel != IEEE80211_CHAN_ANY)
   1649      1.133      onoe 			printf(" chan %d", channel.i_channel);
   1650      1.133      onoe 		printf("\n");
   1651      1.133      onoe 	}
   1652       1.62    chopps }
   1653       1.62    chopps 
   1654       1.62    chopps void
   1655       1.45   thorpej init_current_media()
   1656       1.24   thorpej {
   1657       1.24   thorpej 	struct ifmediareq ifmr;
   1658       1.24   thorpej 
   1659       1.45   thorpej 	/*
   1660       1.45   thorpej 	 * If we have not yet done so, grab the currently-selected
   1661       1.45   thorpej 	 * media.
   1662       1.45   thorpej 	 */
   1663      1.139    dyoung 	if ((actions & (A_MEDIA|A_MEDIAOPT|A_MEDIAMODE)) == 0) {
   1664       1.45   thorpej 		(void) memset(&ifmr, 0, sizeof(ifmr));
   1665       1.45   thorpej 		(void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
   1666       1.45   thorpej 
   1667      1.120    atatat 		if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) {
   1668       1.45   thorpej 			/*
   1669       1.45   thorpej 			 * If we get E2BIG, the kernel is telling us
   1670       1.45   thorpej 			 * that there are more, so we can ignore it.
   1671       1.45   thorpej 			 */
   1672       1.45   thorpej 			if (errno != E2BIG)
   1673      1.120    atatat 				err(EXIT_FAILURE, "SGIOCGIFMEDIA");
   1674       1.45   thorpej 		}
   1675       1.24   thorpej 
   1676       1.45   thorpej 		media_current = ifmr.ifm_current;
   1677       1.24   thorpej 	}
   1678       1.24   thorpej 
   1679       1.45   thorpej 	/* Sanity. */
   1680       1.45   thorpej 	if (IFM_TYPE(media_current) == 0)
   1681      1.127    itojun 		errx(EXIT_FAILURE, "%s: no link type?", name);
   1682       1.45   thorpej }
   1683       1.45   thorpej 
   1684       1.45   thorpej void
   1685       1.45   thorpej process_media_commands()
   1686       1.45   thorpej {
   1687       1.45   thorpej 
   1688      1.139    dyoung 	if ((actions & (A_MEDIA|A_MEDIAOPT|A_MEDIAMODE)) == 0) {
   1689       1.45   thorpej 		/* Nothing to do. */
   1690       1.45   thorpej 		return;
   1691       1.45   thorpej 	}
   1692       1.24   thorpej 
   1693       1.24   thorpej 	/*
   1694       1.45   thorpej 	 * Media already set up, and commands sanity-checked.  Set/clear
   1695       1.45   thorpej 	 * any options, and we're ready to go.
   1696       1.24   thorpej 	 */
   1697       1.45   thorpej 	media_current |= mediaopt_set;
   1698       1.45   thorpej 	media_current &= ~mediaopt_clear;
   1699       1.24   thorpej 
   1700       1.24   thorpej 	strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
   1701       1.45   thorpej 	ifr.ifr_media = media_current;
   1702       1.24   thorpej 
   1703      1.120    atatat 	if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) == -1)
   1704      1.120    atatat 		err(EXIT_FAILURE, "SIOCSIFMEDIA");
   1705       1.24   thorpej }
   1706       1.24   thorpej 
   1707       1.24   thorpej void
   1708       1.45   thorpej setmedia(val, d)
   1709       1.80   thorpej 	const char *val;
   1710       1.32  christos 	int d;
   1711       1.24   thorpej {
   1712       1.45   thorpej 	int type, subtype, inst;
   1713       1.45   thorpej 
   1714       1.45   thorpej 	init_current_media();
   1715       1.45   thorpej 
   1716       1.45   thorpej 	/* Only one media command may be given. */
   1717       1.46   thorpej 	if (actions & A_MEDIA)
   1718      1.127    itojun 		errx(EXIT_FAILURE, "only one `media' command may be issued");
   1719       1.24   thorpej 
   1720      1.139    dyoung 	/* Must not come after mode commands */
   1721      1.139    dyoung 	if (actions & A_MEDIAMODE)
   1722      1.139    dyoung 		errx(EXIT_FAILURE,
   1723      1.139    dyoung 		    "may not issue `media' after `mode' commands");
   1724      1.139    dyoung 
   1725       1.45   thorpej 	/* Must not come after mediaopt commands */
   1726       1.46   thorpej 	if (actions & A_MEDIAOPT)
   1727      1.127    itojun 		errx(EXIT_FAILURE,
   1728      1.127    itojun 		    "may not issue `media' after `mediaopt' commands");
   1729       1.45   thorpej 
   1730       1.47   thorpej 	/*
   1731       1.47   thorpej 	 * No need to check if `instance' has been issued; setmediainst()
   1732       1.47   thorpej 	 * craps out if `media' has not been specified.
   1733       1.47   thorpej 	 */
   1734       1.47   thorpej 
   1735       1.45   thorpej 	type = IFM_TYPE(media_current);
   1736       1.45   thorpej 	inst = IFM_INST(media_current);
   1737       1.45   thorpej 
   1738       1.45   thorpej 	/* Look up the subtype. */
   1739       1.45   thorpej 	subtype = get_media_subtype(type, val);
   1740       1.24   thorpej 
   1741       1.45   thorpej 	/* Build the new current media word. */
   1742       1.45   thorpej 	media_current = IFM_MAKEWORD(type, subtype, 0, inst);
   1743       1.24   thorpej 
   1744       1.45   thorpej 	/* Media will be set after other processing is complete. */
   1745       1.24   thorpej }
   1746       1.24   thorpej 
   1747       1.24   thorpej void
   1748       1.45   thorpej setmediaopt(val, d)
   1749       1.80   thorpej 	const char *val;
   1750       1.45   thorpej 	int d;
   1751       1.24   thorpej {
   1752       1.24   thorpej 
   1753       1.45   thorpej 	init_current_media();
   1754       1.24   thorpej 
   1755       1.45   thorpej 	/* Can only issue `mediaopt' once. */
   1756       1.46   thorpej 	if (actions & A_MEDIAOPTSET)
   1757      1.127    itojun 		errx(EXIT_FAILURE, "only one `mediaopt' command may be issued");
   1758       1.26   thorpej 
   1759       1.47   thorpej 	/* Can't issue `mediaopt' if `instance' has already been issued. */
   1760       1.47   thorpej 	if (actions & A_MEDIAINST)
   1761      1.127    itojun 		errx(EXIT_FAILURE, "may not issue `mediaopt' after `instance'");
   1762       1.47   thorpej 
   1763       1.45   thorpej 	mediaopt_set = get_media_options(IFM_TYPE(media_current), val);
   1764       1.24   thorpej 
   1765       1.45   thorpej 	/* Media will be set after other processing is complete. */
   1766       1.45   thorpej }
   1767       1.24   thorpej 
   1768       1.45   thorpej void
   1769       1.45   thorpej unsetmediaopt(val, d)
   1770       1.80   thorpej 	const char *val;
   1771       1.45   thorpej 	int d;
   1772       1.45   thorpej {
   1773       1.26   thorpej 
   1774       1.45   thorpej 	init_current_media();
   1775       1.26   thorpej 
   1776       1.45   thorpej 	/* Can only issue `-mediaopt' once. */
   1777       1.46   thorpej 	if (actions & A_MEDIAOPTCLR)
   1778      1.127    itojun 		errx(EXIT_FAILURE,
   1779      1.127    itojun 		    "only one `-mediaopt' command may be issued");
   1780       1.26   thorpej 
   1781       1.45   thorpej 	/* May not issue `media' and `-mediaopt'. */
   1782       1.46   thorpej 	if (actions & A_MEDIA)
   1783      1.127    itojun 		errx(EXIT_FAILURE,
   1784      1.127    itojun 		    "may not issue both `media' and `-mediaopt'");
   1785       1.24   thorpej 
   1786       1.47   thorpej 	/*
   1787       1.47   thorpej 	 * No need to check for A_MEDIAINST, since the test for A_MEDIA
   1788       1.47   thorpej 	 * implicitly checks for A_MEDIAINST.
   1789       1.47   thorpej 	 */
   1790       1.47   thorpej 
   1791       1.45   thorpej 	mediaopt_clear = get_media_options(IFM_TYPE(media_current), val);
   1792       1.24   thorpej 
   1793       1.45   thorpej 	/* Media will be set after other processing is complete. */
   1794       1.24   thorpej }
   1795       1.24   thorpej 
   1796       1.47   thorpej void
   1797       1.47   thorpej setmediainst(val, d)
   1798       1.80   thorpej 	const char *val;
   1799       1.47   thorpej 	int d;
   1800       1.47   thorpej {
   1801       1.47   thorpej 	int type, subtype, options, inst;
   1802       1.47   thorpej 
   1803       1.47   thorpej 	init_current_media();
   1804       1.47   thorpej 
   1805       1.47   thorpej 	/* Can only issue `instance' once. */
   1806       1.47   thorpej 	if (actions & A_MEDIAINST)
   1807      1.127    itojun 		errx(EXIT_FAILURE, "only one `instance' command may be issued");
   1808       1.47   thorpej 
   1809       1.47   thorpej 	/* Must have already specified `media' */
   1810       1.47   thorpej 	if ((actions & A_MEDIA) == 0)
   1811      1.127    itojun 		errx(EXIT_FAILURE, "must specify `media' before `instance'");
   1812       1.47   thorpej 
   1813       1.47   thorpej 	type = IFM_TYPE(media_current);
   1814       1.47   thorpej 	subtype = IFM_SUBTYPE(media_current);
   1815       1.47   thorpej 	options = IFM_OPTIONS(media_current);
   1816       1.47   thorpej 
   1817       1.47   thorpej 	inst = atoi(val);
   1818       1.47   thorpej 	if (inst < 0 || inst > IFM_INST_MAX)
   1819      1.127    itojun 		errx(EXIT_FAILURE, "invalid media instance: %s", val);
   1820       1.47   thorpej 
   1821       1.47   thorpej 	media_current = IFM_MAKEWORD(type, subtype, options, inst);
   1822       1.47   thorpej 
   1823       1.47   thorpej 	/* Media will be set after other processing is complete. */
   1824       1.47   thorpej }
   1825       1.47   thorpej 
   1826      1.139    dyoung void
   1827      1.139    dyoung setmediamode(val, d)
   1828      1.139    dyoung 	const char *val;
   1829      1.139    dyoung 	int d;
   1830      1.139    dyoung {
   1831      1.139    dyoung 	int type, subtype, options, inst, mode;
   1832      1.139    dyoung 
   1833      1.139    dyoung 	init_current_media();
   1834      1.139    dyoung 
   1835      1.139    dyoung 	/* Can only issue `mode' once. */
   1836      1.139    dyoung 	if (actions & A_MEDIAMODE)
   1837      1.139    dyoung 		errx(EXIT_FAILURE, "only one `mode' command may be issued");
   1838      1.139    dyoung 
   1839      1.139    dyoung 	type = IFM_TYPE(media_current);
   1840      1.139    dyoung 	subtype = IFM_SUBTYPE(media_current);
   1841      1.139    dyoung 	options = IFM_OPTIONS(media_current);
   1842      1.139    dyoung 	inst = IFM_INST(media_current);
   1843      1.139    dyoung 
   1844      1.139    dyoung 	if ((mode = get_media_mode(type, val)) == -1)
   1845      1.139    dyoung 		errx(EXIT_FAILURE, "invalid media mode: %s", val);
   1846      1.139    dyoung 
   1847      1.139    dyoung 	media_current = IFM_MAKEWORD(type, subtype, options, inst) | mode;
   1848      1.139    dyoung 
   1849      1.139    dyoung 	/* Media will be set after other processing is complete. */
   1850      1.139    dyoung }
   1851      1.139    dyoung 
   1852      1.139    dyoung struct ifmedia_description ifm_mode_descriptions[] =
   1853      1.139    dyoung     IFM_MODE_DESCRIPTIONS;
   1854      1.139    dyoung 
   1855       1.24   thorpej struct ifmedia_description ifm_type_descriptions[] =
   1856       1.24   thorpej     IFM_TYPE_DESCRIPTIONS;
   1857       1.24   thorpej 
   1858       1.42   thorpej struct ifmedia_description ifm_subtype_descriptions[] =
   1859       1.42   thorpej     IFM_SUBTYPE_DESCRIPTIONS;
   1860       1.24   thorpej 
   1861       1.42   thorpej struct ifmedia_description ifm_option_descriptions[] =
   1862       1.42   thorpej     IFM_OPTION_DESCRIPTIONS;
   1863       1.24   thorpej 
   1864       1.42   thorpej const char *
   1865       1.42   thorpej get_media_type_string(mword)
   1866       1.42   thorpej 	int mword;
   1867       1.42   thorpej {
   1868       1.42   thorpej 	struct ifmedia_description *desc;
   1869       1.24   thorpej 
   1870       1.42   thorpej 	for (desc = ifm_type_descriptions; desc->ifmt_string != NULL;
   1871       1.42   thorpej 	     desc++) {
   1872       1.42   thorpej 		if (IFM_TYPE(mword) == desc->ifmt_word)
   1873       1.42   thorpej 			return (desc->ifmt_string);
   1874       1.42   thorpej 	}
   1875       1.42   thorpej 	return ("<unknown type>");
   1876       1.42   thorpej }
   1877       1.24   thorpej 
   1878       1.42   thorpej const char *
   1879       1.42   thorpej get_media_subtype_string(mword)
   1880       1.42   thorpej 	int mword;
   1881       1.42   thorpej {
   1882       1.42   thorpej 	struct ifmedia_description *desc;
   1883       1.24   thorpej 
   1884       1.42   thorpej 	for (desc = ifm_subtype_descriptions; desc->ifmt_string != NULL;
   1885       1.42   thorpej 	     desc++) {
   1886       1.42   thorpej 		if (IFM_TYPE_MATCH(desc->ifmt_word, mword) &&
   1887       1.42   thorpej 		    IFM_SUBTYPE(desc->ifmt_word) == IFM_SUBTYPE(mword))
   1888       1.42   thorpej 			return (desc->ifmt_string);
   1889       1.42   thorpej 	}
   1890       1.42   thorpej 	return ("<unknown subtype>");
   1891       1.42   thorpej }
   1892       1.24   thorpej 
   1893       1.24   thorpej int
   1894      1.139    dyoung get_media_mode(type, val)
   1895      1.139    dyoung 	int type;
   1896      1.139    dyoung 	const char *val;
   1897      1.139    dyoung {
   1898      1.139    dyoung 	int rval;
   1899      1.139    dyoung 
   1900      1.139    dyoung 	rval = lookup_media_word(ifm_mode_descriptions, type, val);
   1901      1.139    dyoung 	if (rval == -1)
   1902      1.139    dyoung 		errx(EXIT_FAILURE, "unknown %s media mode: %s",
   1903      1.139    dyoung 		    get_media_type_string(type), val);
   1904      1.139    dyoung 
   1905      1.139    dyoung 	return (rval);
   1906      1.139    dyoung }
   1907      1.139    dyoung 
   1908      1.139    dyoung int
   1909       1.24   thorpej get_media_subtype(type, val)
   1910       1.24   thorpej 	int type;
   1911       1.42   thorpej 	const char *val;
   1912       1.24   thorpej {
   1913       1.42   thorpej 	int rval;
   1914       1.24   thorpej 
   1915       1.42   thorpej 	rval = lookup_media_word(ifm_subtype_descriptions, type, val);
   1916       1.42   thorpej 	if (rval == -1)
   1917      1.127    itojun 		errx(EXIT_FAILURE, "unknown %s media subtype: %s",
   1918       1.42   thorpej 		    get_media_type_string(type), val);
   1919       1.24   thorpej 
   1920       1.42   thorpej 	return (rval);
   1921       1.24   thorpej }
   1922       1.24   thorpej 
   1923       1.24   thorpej int
   1924       1.24   thorpej get_media_options(type, val)
   1925       1.24   thorpej 	int type;
   1926       1.42   thorpej 	const char *val;
   1927       1.24   thorpej {
   1928       1.42   thorpej 	char *optlist, *str;
   1929       1.42   thorpej 	int option, rval = 0;
   1930       1.24   thorpej 
   1931       1.24   thorpej 	/* We muck with the string, so copy it. */
   1932       1.24   thorpej 	optlist = strdup(val);
   1933       1.24   thorpej 	if (optlist == NULL)
   1934      1.120    atatat 		err(EXIT_FAILURE, "strdup");
   1935       1.42   thorpej 	str = optlist;
   1936       1.24   thorpej 
   1937       1.24   thorpej 	/*
   1938       1.42   thorpej 	 * Look up the options in the user-provided comma-separated list.
   1939       1.24   thorpej 	 */
   1940       1.42   thorpej 	for (; (str = strtok(str, ",")) != NULL; str = NULL) {
   1941       1.42   thorpej 		option = lookup_media_word(ifm_option_descriptions, type, str);
   1942       1.42   thorpej 		if (option == -1)
   1943      1.127    itojun 			errx(EXIT_FAILURE, "unknown %s media option: %s",
   1944       1.42   thorpej 			    get_media_type_string(type), str);
   1945       1.61   thorpej 		rval |= IFM_OPTIONS(option);
   1946       1.24   thorpej 	}
   1947       1.24   thorpej 
   1948       1.24   thorpej 	free(optlist);
   1949       1.24   thorpej 	return (rval);
   1950       1.24   thorpej }
   1951       1.24   thorpej 
   1952       1.24   thorpej int
   1953       1.42   thorpej lookup_media_word(desc, type, val)
   1954       1.24   thorpej 	struct ifmedia_description *desc;
   1955       1.42   thorpej 	int type;
   1956       1.42   thorpej 	const char *val;
   1957       1.24   thorpej {
   1958       1.24   thorpej 
   1959       1.42   thorpej 	for (; desc->ifmt_string != NULL; desc++) {
   1960       1.42   thorpej 		if (IFM_TYPE_MATCH(desc->ifmt_word, type) &&
   1961       1.42   thorpej 		    strcasecmp(desc->ifmt_string, val) == 0)
   1962       1.24   thorpej 			return (desc->ifmt_word);
   1963       1.42   thorpej 	}
   1964       1.27   thorpej 	return (-1);
   1965       1.24   thorpej }
   1966       1.24   thorpej 
   1967       1.24   thorpej void
   1968       1.44   thorpej print_media_word(ifmw, print_type, as_syntax)
   1969       1.44   thorpej 	int ifmw, print_type, as_syntax;
   1970       1.24   thorpej {
   1971       1.24   thorpej 	struct ifmedia_description *desc;
   1972       1.42   thorpej 	int seen_option = 0;
   1973       1.24   thorpej 
   1974       1.42   thorpej 	if (print_type)
   1975       1.42   thorpej 		printf("%s ", get_media_type_string(ifmw));
   1976       1.44   thorpej 	printf("%s%s", as_syntax ? "media " : "",
   1977       1.44   thorpej 	    get_media_subtype_string(ifmw));
   1978      1.139    dyoung 
   1979      1.139    dyoung 	/* Find mode. */
   1980      1.139    dyoung 	if (IFM_MODE(ifmw) != 0) {
   1981      1.139    dyoung 		for (desc = ifm_mode_descriptions; desc->ifmt_string != NULL;
   1982      1.139    dyoung 		     desc++) {
   1983      1.139    dyoung 			if (IFM_TYPE_MATCH(desc->ifmt_word, ifmw) &&
   1984      1.139    dyoung 			    IFM_MODE(ifmw) == IFM_MODE(desc->ifmt_word)) {
   1985      1.139    dyoung 				printf(" mode %s", desc->ifmt_string);
   1986      1.139    dyoung 				break;
   1987      1.139    dyoung 			}
   1988      1.139    dyoung 		}
   1989      1.139    dyoung 	}
   1990       1.24   thorpej 
   1991       1.24   thorpej 	/* Find options. */
   1992       1.42   thorpej 	for (desc = ifm_option_descriptions; desc->ifmt_string != NULL;
   1993       1.42   thorpej 	     desc++) {
   1994       1.42   thorpej 		if (IFM_TYPE_MATCH(desc->ifmt_word, ifmw) &&
   1995       1.67   mycroft 		    (ifmw & IFM_OPTIONS(desc->ifmt_word)) != 0 &&
   1996       1.42   thorpej 		    (seen_option & IFM_OPTIONS(desc->ifmt_word)) == 0) {
   1997       1.42   thorpej 			if (seen_option == 0)
   1998       1.44   thorpej 				printf(" %s", as_syntax ? "mediaopt " : "");
   1999       1.42   thorpej 			printf("%s%s", seen_option ? "," : "",
   2000       1.42   thorpej 			    desc->ifmt_string);
   2001       1.42   thorpej 			seen_option |= IFM_OPTIONS(desc->ifmt_word);
   2002       1.24   thorpej 		}
   2003       1.24   thorpej 	}
   2004       1.43   thorpej 	if (IFM_INST(ifmw) != 0)
   2005       1.47   thorpej 		printf(" instance %d", IFM_INST(ifmw));
   2006       1.24   thorpej }
   2007       1.54  sommerfe 
   2008       1.54  sommerfe int carrier()
   2009       1.54  sommerfe {
   2010       1.54  sommerfe 	struct ifmediareq ifmr;
   2011       1.54  sommerfe 
   2012       1.54  sommerfe 	(void) memset(&ifmr, 0, sizeof(ifmr));
   2013       1.54  sommerfe 	(void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
   2014       1.54  sommerfe 
   2015      1.120    atatat 	if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) {
   2016       1.54  sommerfe 		/*
   2017       1.54  sommerfe 		 * Interface doesn't support SIOC{G,S}IFMEDIA;
   2018       1.54  sommerfe 		 * assume ok.
   2019       1.54  sommerfe 		 */
   2020       1.54  sommerfe 		return 0;
   2021       1.54  sommerfe 	}
   2022       1.54  sommerfe 	if ((ifmr.ifm_status & IFM_AVALID) == 0) {
   2023       1.54  sommerfe 		/*
   2024       1.54  sommerfe 		 * Interface doesn't report media-valid status.
   2025       1.54  sommerfe 		 * assume ok.
   2026       1.54  sommerfe 		 */
   2027       1.54  sommerfe 		return 0;
   2028       1.54  sommerfe 	}
   2029       1.54  sommerfe 	/* otherwise, return ok for active, not-ok if not active. */
   2030       1.54  sommerfe 	return !(ifmr.ifm_status & IFM_ACTIVE);
   2031       1.54  sommerfe }
   2032       1.54  sommerfe 
   2033       1.24   thorpej 
   2034        1.1       cgd #define	IFFBITS \
   2035       1.13   mycroft "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
   2036       1.13   mycroft \11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST"
   2037        1.1       cgd 
   2038      1.108   thorpej #define	IFCAPBITS \
   2039      1.115   thorpej "\020\1IP4CSUM\2TCP4CSUM\3UDP4CSUM\4TCP6CSUM\5UDP6CSUM\6TCP4CSUM_Rx\7UDP4CSUM_Rx"
   2040      1.108   thorpej 
   2041       1.63   thorpej const int ifm_status_valid_list[] = IFM_STATUS_VALID_LIST;
   2042       1.63   thorpej 
   2043       1.63   thorpej const struct ifmedia_status_description ifm_status_descriptions[] =
   2044       1.63   thorpej     IFM_STATUS_DESCRIPTIONS;
   2045       1.63   thorpej 
   2046        1.1       cgd /*
   2047        1.1       cgd  * Print the status of the interface.  If an address family was
   2048        1.1       cgd  * specified, show it and it only; otherwise, show them all.
   2049        1.1       cgd  */
   2050       1.16       cgd void
   2051      1.119     bjh21 status(sdl)
   2052      1.119     bjh21 	const struct sockaddr_dl *sdl;
   2053        1.1       cgd {
   2054       1.39     lukem 	struct afswtch *p = afp;
   2055       1.24   thorpej 	struct ifmediareq ifmr;
   2056      1.124      matt 	struct ifdatareq ifdr;
   2057       1.24   thorpej 	int *media_list, i;
   2058      1.119     bjh21 	char hbuf[NI_MAXHOST];
   2059      1.130  christos 	char fbuf[BUFSIZ];
   2060        1.1       cgd 
   2061      1.130  christos 	(void)snprintb(fbuf, sizeof(fbuf), IFFBITS, flags);
   2062      1.130  christos 	printf("%s: flags=%s", name, &fbuf[2]);
   2063        1.1       cgd 	if (metric)
   2064      1.125    itojun 		printf(" metric %lu", metric);
   2065       1.33        is 	if (mtu)
   2066      1.125    itojun 		printf(" mtu %lu", mtu);
   2067        1.1       cgd 	putchar('\n');
   2068      1.108   thorpej 
   2069      1.108   thorpej 	if (g_ifcr.ifcr_capabilities) {
   2070      1.130  christos 		(void)snprintb(fbuf, sizeof(fbuf), IFCAPBITS,
   2071      1.130  christos 		    g_ifcr.ifcr_capabilities);
   2072      1.130  christos 		printf("\tcapabilities=%s\n", &fbuf[2]);
   2073      1.130  christos 		(void)snprintb(fbuf, sizeof(fbuf), IFCAPBITS,
   2074      1.130  christos 		    g_ifcr.ifcr_capenable);
   2075      1.130  christos 		printf("\tenabled=%s\n", &fbuf[2]);
   2076      1.108   thorpej 	}
   2077       1.65   thorpej 
   2078       1.65   thorpej 	ieee80211_status();
   2079       1.89   thorpej 	vlan_status();
   2080       1.80   thorpej 	tunnel_status();
   2081       1.65   thorpej 
   2082      1.119     bjh21 	if (sdl != NULL &&
   2083      1.119     bjh21 	    getnameinfo((struct sockaddr *)sdl, sdl->sdl_len,
   2084      1.119     bjh21 		hbuf, sizeof(hbuf), NULL, 0, NI_NUMERICHOST) == 0 &&
   2085      1.119     bjh21 	    hbuf[0] != '\0')
   2086      1.119     bjh21 		printf("\taddress: %s\n", hbuf);
   2087       1.24   thorpej 
   2088       1.32  christos 	(void) memset(&ifmr, 0, sizeof(ifmr));
   2089       1.32  christos 	(void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
   2090       1.24   thorpej 
   2091      1.120    atatat 	if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) {
   2092       1.24   thorpej 		/*
   2093       1.24   thorpej 		 * Interface doesn't support SIOC{G,S}IFMEDIA.
   2094       1.24   thorpej 		 */
   2095      1.124      matt 		goto iface_stats;
   2096       1.24   thorpej 	}
   2097       1.24   thorpej 
   2098       1.24   thorpej 	if (ifmr.ifm_count == 0) {
   2099       1.29   thorpej 		warnx("%s: no media types?", name);
   2100      1.124      matt 		goto iface_stats;
   2101       1.24   thorpej 	}
   2102       1.24   thorpej 
   2103       1.24   thorpej 	media_list = (int *)malloc(ifmr.ifm_count * sizeof(int));
   2104       1.24   thorpej 	if (media_list == NULL)
   2105      1.120    atatat 		err(EXIT_FAILURE, "malloc");
   2106       1.24   thorpej 	ifmr.ifm_ulist = media_list;
   2107       1.24   thorpej 
   2108      1.120    atatat 	if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) == -1)
   2109      1.120    atatat 		err(EXIT_FAILURE, "SIOCGIFMEDIA");
   2110       1.24   thorpej 
   2111       1.24   thorpej 	printf("\tmedia: ");
   2112       1.44   thorpej 	print_media_word(ifmr.ifm_current, 1, 0);
   2113       1.24   thorpej 	if (ifmr.ifm_active != ifmr.ifm_current) {
   2114       1.28   thorpej 		putchar(' ');
   2115       1.24   thorpej 		putchar('(');
   2116       1.44   thorpej 		print_media_word(ifmr.ifm_active, 0, 0);
   2117       1.24   thorpej 		putchar(')');
   2118       1.24   thorpej 	}
   2119       1.42   thorpej 	putchar('\n');
   2120       1.24   thorpej 
   2121       1.63   thorpej 	if (ifmr.ifm_status & IFM_STATUS_VALID) {
   2122       1.63   thorpej 		const struct ifmedia_status_description *ifms;
   2123       1.63   thorpej 		int bitno, found = 0;
   2124       1.63   thorpej 
   2125       1.42   thorpej 		printf("\tstatus: ");
   2126       1.63   thorpej 		for (bitno = 0; ifm_status_valid_list[bitno] != 0; bitno++) {
   2127       1.63   thorpej 			for (ifms = ifm_status_descriptions;
   2128       1.63   thorpej 			     ifms->ifms_valid != 0; ifms++) {
   2129       1.63   thorpej 				if (ifms->ifms_type !=
   2130       1.66   thorpej 				      IFM_TYPE(ifmr.ifm_current) ||
   2131       1.63   thorpej 				    ifms->ifms_valid !=
   2132       1.63   thorpej 				      ifm_status_valid_list[bitno])
   2133       1.63   thorpej 					continue;
   2134       1.63   thorpej 				printf("%s%s", found ? ", " : "",
   2135       1.63   thorpej 				    IFM_STATUS_DESC(ifms, ifmr.ifm_status));
   2136       1.63   thorpej 				found = 1;
   2137       1.63   thorpej 
   2138       1.63   thorpej 				/*
   2139       1.63   thorpej 				 * For each valid indicator bit, there's
   2140       1.63   thorpej 				 * only one entry for each media type, so
   2141       1.63   thorpej 				 * terminate the inner loop now.
   2142       1.63   thorpej 				 */
   2143       1.63   thorpej 				break;
   2144       1.63   thorpej 			}
   2145       1.63   thorpej 		}
   2146       1.24   thorpej 
   2147       1.63   thorpej 		if (found == 0)
   2148       1.42   thorpej 			printf("unknown");
   2149       1.42   thorpej 		putchar('\n');
   2150       1.24   thorpej 	}
   2151       1.24   thorpej 
   2152       1.24   thorpej 	if (mflag) {
   2153       1.44   thorpej 		int type, printed_type;
   2154       1.44   thorpej 
   2155       1.44   thorpej 		for (type = IFM_NMIN; type <= IFM_NMAX; type += IFM_NMIN) {
   2156       1.44   thorpej 			for (i = 0, printed_type = 0; i < ifmr.ifm_count; i++) {
   2157       1.44   thorpej 				if (IFM_TYPE(media_list[i]) == type) {
   2158       1.44   thorpej 					if (printed_type == 0) {
   2159       1.44   thorpej 					    printf("\tsupported %s media:\n",
   2160       1.44   thorpej 					      get_media_type_string(type));
   2161       1.44   thorpej 					    printed_type = 1;
   2162       1.44   thorpej 					}
   2163       1.44   thorpej 					printf("\t\t");
   2164       1.44   thorpej 					print_media_word(media_list[i], 0, 1);
   2165       1.44   thorpej 					printf("\n");
   2166       1.44   thorpej 				}
   2167       1.44   thorpej 			}
   2168       1.24   thorpej 		}
   2169       1.24   thorpej 	}
   2170       1.24   thorpej 
   2171       1.24   thorpej 	free(media_list);
   2172       1.24   thorpej 
   2173      1.124      matt  iface_stats:
   2174      1.134     perry 	if (!vflag && !zflag)
   2175      1.124      matt 		goto proto_status;
   2176      1.124      matt 
   2177      1.124      matt 	(void) strncpy(ifdr.ifdr_name, name, sizeof(ifdr.ifdr_name));
   2178      1.124      matt 
   2179      1.134     perry 	if (ioctl(s, zflag ? SIOCZIFDATA:SIOCGIFDATA, (caddr_t)&ifdr) == -1) {
   2180      1.134     perry 		err(EXIT_FAILURE, zflag ? "SIOCZIFDATA" : "SIOCGIFDATA");
   2181      1.134     perry 	} else {
   2182      1.124      matt 		struct if_data * const ifi = &ifdr.ifdr_data;
   2183      1.124      matt #define	PLURAL(n)	((n) == 1 ? "" : "s")
   2184      1.124      matt 		printf("\tinput: %llu packet%s, %llu byte%s",
   2185      1.124      matt 		    (unsigned long long) ifi->ifi_ipackets,
   2186      1.124      matt 		    PLURAL(ifi->ifi_ipackets),
   2187      1.124      matt 		    (unsigned long long) ifi->ifi_ibytes,
   2188      1.124      matt 		    PLURAL(ifi->ifi_ibytes));
   2189      1.124      matt 		if (ifi->ifi_imcasts)
   2190      1.124      matt 			printf(", %llu multicast%s",
   2191      1.124      matt 			    (unsigned long long) ifi->ifi_imcasts,
   2192      1.124      matt 			    PLURAL(ifi->ifi_imcasts));
   2193      1.124      matt 		if (ifi->ifi_ierrors)
   2194      1.124      matt 			printf(", %llu error%s",
   2195      1.124      matt 			    (unsigned long long) ifi->ifi_ierrors,
   2196      1.124      matt 			    PLURAL(ifi->ifi_ierrors));
   2197      1.124      matt 		if (ifi->ifi_iqdrops)
   2198      1.124      matt 			printf(", %llu queue drop%s",
   2199      1.124      matt 			    (unsigned long long) ifi->ifi_iqdrops,
   2200      1.124      matt 			    PLURAL(ifi->ifi_iqdrops));
   2201      1.124      matt 		if (ifi->ifi_noproto)
   2202      1.124      matt 			printf(", %llu unknown protocol",
   2203      1.124      matt 			    (unsigned long long) ifi->ifi_noproto);
   2204      1.124      matt 		printf("\n\toutput: %llu packet%s, %llu byte%s",
   2205      1.124      matt 		    (unsigned long long) ifi->ifi_opackets,
   2206      1.124      matt 		    PLURAL(ifi->ifi_opackets),
   2207      1.124      matt 		    (unsigned long long) ifi->ifi_obytes,
   2208      1.124      matt 		    PLURAL(ifi->ifi_obytes));
   2209      1.124      matt 		if (ifi->ifi_omcasts)
   2210      1.124      matt 			printf(", %llu multicast%s",
   2211      1.124      matt 			    (unsigned long long) ifi->ifi_omcasts,
   2212      1.124      matt 			    PLURAL(ifi->ifi_omcasts));
   2213      1.124      matt 		if (ifi->ifi_oerrors)
   2214      1.124      matt 			printf(", %llu error%s",
   2215      1.124      matt 			    (unsigned long long) ifi->ifi_oerrors,
   2216      1.124      matt 			    PLURAL(ifi->ifi_oerrors));
   2217      1.124      matt 		if (ifi->ifi_collisions)
   2218      1.124      matt 			printf(", %llu collision%s",
   2219      1.124      matt 			    (unsigned long long) ifi->ifi_collisions,
   2220      1.124      matt 			    PLURAL(ifi->ifi_collisions));
   2221      1.124      matt 		printf("\n");
   2222      1.124      matt #undef PLURAL
   2223      1.124      matt 	}
   2224      1.124      matt 
   2225       1.24   thorpej  proto_status:
   2226        1.1       cgd 	if ((p = afp) != NULL) {
   2227        1.1       cgd 		(*p->af_status)(1);
   2228        1.1       cgd 	} else for (p = afs; p->af_name; p++) {
   2229        1.1       cgd 		ifr.ifr_addr.sa_family = p->af_af;
   2230        1.1       cgd 		(*p->af_status)(0);
   2231       1.49  christos 	}
   2232       1.49  christos }
   2233       1.49  christos 
   2234       1.49  christos void
   2235       1.80   thorpej tunnel_status()
   2236       1.80   thorpej {
   2237       1.80   thorpej 	char psrcaddr[NI_MAXHOST];
   2238       1.80   thorpej 	char pdstaddr[NI_MAXHOST];
   2239       1.80   thorpej 	const char *ver = "";
   2240       1.80   thorpej #ifdef NI_WITHSCOPEID
   2241       1.80   thorpej 	const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID;
   2242       1.80   thorpej #else
   2243       1.80   thorpej 	const int niflag = NI_NUMERICHOST;
   2244       1.80   thorpej #endif
   2245      1.100    itojun 	struct if_laddrreq req;
   2246       1.80   thorpej 
   2247       1.80   thorpej 	psrcaddr[0] = pdstaddr[0] = '\0';
   2248       1.80   thorpej 
   2249      1.100    itojun 	memset(&req, 0, sizeof(req));
   2250      1.100    itojun 	strncpy(req.iflr_name, name, IFNAMSIZ);
   2251      1.120    atatat 	if (ioctl(s, SIOCGLIFPHYADDR, (caddr_t)&req) == -1)
   2252       1.80   thorpej 		return;
   2253       1.80   thorpej #ifdef INET6
   2254      1.100    itojun 	if (req.addr.ss_family == AF_INET6)
   2255      1.100    itojun 		in6_fillscopeid((struct sockaddr_in6 *)&req.addr);
   2256       1.80   thorpej #endif
   2257      1.100    itojun 	getnameinfo((struct sockaddr *)&req.addr, req.addr.ss_len,
   2258       1.80   thorpej 	    psrcaddr, sizeof(psrcaddr), 0, 0, niflag);
   2259       1.80   thorpej #ifdef INET6
   2260      1.100    itojun 	if (req.addr.ss_family == AF_INET6)
   2261       1.80   thorpej 		ver = "6";
   2262       1.80   thorpej #endif
   2263       1.80   thorpej 
   2264       1.80   thorpej #ifdef INET6
   2265      1.100    itojun 	if (req.dstaddr.ss_family == AF_INET6)
   2266      1.100    itojun 		in6_fillscopeid((struct sockaddr_in6 *)&req.dstaddr);
   2267       1.80   thorpej #endif
   2268      1.100    itojun 	getnameinfo((struct sockaddr *)&req.dstaddr, req.dstaddr.ss_len,
   2269       1.80   thorpej 	    pdstaddr, sizeof(pdstaddr), 0, 0, niflag);
   2270       1.80   thorpej 
   2271      1.100    itojun 	printf("\ttunnel inet%s %s --> %s\n", ver, psrcaddr, pdstaddr);
   2272       1.80   thorpej }
   2273       1.80   thorpej 
   2274       1.80   thorpej void
   2275       1.89   thorpej vlan_status()
   2276       1.89   thorpej {
   2277       1.89   thorpej 	struct vlanreq vlr;
   2278       1.89   thorpej 
   2279       1.89   thorpej 	if (strncmp(ifr.ifr_name, "vlan", 4) != 0 ||
   2280       1.89   thorpej 	    !isdigit(ifr.ifr_name[4]))
   2281       1.89   thorpej 		return;
   2282       1.89   thorpej 
   2283       1.89   thorpej 	memset(&vlr, 0, sizeof(vlr));
   2284       1.89   thorpej 	ifr.ifr_data = (caddr_t)&vlr;
   2285       1.89   thorpej 
   2286       1.89   thorpej 	if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
   2287       1.89   thorpej 		return;
   2288       1.89   thorpej 
   2289       1.89   thorpej 	if (vlr.vlr_tag || vlr.vlr_parent[0] != '\0')
   2290       1.89   thorpej 		printf("\tvlan: %d parent: %s\n",
   2291       1.89   thorpej 		    vlr.vlr_tag, vlr.vlr_parent[0] == '\0' ?
   2292       1.89   thorpej 		    "<none>" : vlr.vlr_parent);
   2293       1.89   thorpej }
   2294       1.89   thorpej 
   2295       1.89   thorpej void
   2296       1.49  christos in_alias(creq)
   2297       1.49  christos 	struct ifreq *creq;
   2298       1.49  christos {
   2299      1.121     lukem 	struct sockaddr_in *iasin;
   2300       1.77    itojun 	int alias;
   2301       1.49  christos 
   2302       1.49  christos 	if (lflag)
   2303       1.49  christos 		return;
   2304       1.49  christos 
   2305       1.77    itojun 	alias = 1;
   2306       1.77    itojun 
   2307       1.49  christos 	/* Get the non-alias address for this interface. */
   2308       1.49  christos 	getsock(AF_INET);
   2309       1.49  christos 	if (s < 0) {
   2310       1.49  christos 		if (errno == EPROTONOSUPPORT)
   2311       1.49  christos 			return;
   2312      1.120    atatat 		err(EXIT_FAILURE, "socket");
   2313       1.49  christos 	}
   2314       1.49  christos 	(void) memset(&ifr, 0, sizeof(ifr));
   2315       1.49  christos 	(void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
   2316      1.120    atatat 	if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) == -1) {
   2317       1.49  christos 		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
   2318       1.49  christos 			return;
   2319       1.49  christos 		} else
   2320       1.49  christos 			warn("SIOCGIFADDR");
   2321       1.49  christos 	}
   2322       1.49  christos 	/* If creq and ifr are the same address, this is not an alias. */
   2323       1.49  christos 	if (memcmp(&ifr.ifr_addr, &creq->ifr_addr,
   2324       1.49  christos 		   sizeof(creq->ifr_addr)) == 0)
   2325       1.77    itojun 		alias = 0;
   2326      1.122    itojun 	(void) memset(&in_addreq, 0, sizeof(in_addreq));
   2327      1.122    itojun 	(void) strncpy(in_addreq.ifra_name, name, sizeof(in_addreq.ifra_name));
   2328      1.122    itojun 	memcpy(&in_addreq.ifra_addr, &creq->ifr_addr,
   2329      1.122    itojun 	    sizeof(in_addreq.ifra_addr));
   2330      1.122    itojun 	if (ioctl(s, SIOCGIFALIAS, (caddr_t)&in_addreq) == -1) {
   2331       1.49  christos 		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
   2332       1.49  christos 			return;
   2333       1.49  christos 		} else
   2334       1.49  christos 			warn("SIOCGIFALIAS");
   2335       1.49  christos 	}
   2336       1.49  christos 
   2337      1.122    itojun 	iasin = &in_addreq.ifra_addr;
   2338      1.121     lukem 	printf("\tinet %s%s", alias ? "alias " : "", inet_ntoa(iasin->sin_addr));
   2339       1.49  christos 
   2340       1.49  christos 	if (flags & IFF_POINTOPOINT) {
   2341      1.122    itojun 		iasin = &in_addreq.ifra_dstaddr;
   2342      1.121     lukem 		printf(" -> %s", inet_ntoa(iasin->sin_addr));
   2343       1.49  christos 	}
   2344       1.49  christos 
   2345      1.122    itojun 	iasin = &in_addreq.ifra_mask;
   2346      1.121     lukem 	printf(" netmask 0x%x", ntohl(iasin->sin_addr.s_addr));
   2347       1.49  christos 
   2348       1.49  christos 	if (flags & IFF_BROADCAST) {
   2349      1.122    itojun 		iasin = &in_addreq.ifra_broadaddr;
   2350      1.121     lukem 		printf(" broadcast %s", inet_ntoa(iasin->sin_addr));
   2351        1.1       cgd 	}
   2352       1.49  christos 	printf("\n");
   2353        1.1       cgd }
   2354        1.1       cgd 
   2355       1.16       cgd void
   2356        1.1       cgd in_status(force)
   2357        1.1       cgd 	int force;
   2358        1.1       cgd {
   2359       1.78    itojun 	struct ifaddrs *ifap, *ifa;
   2360      1.121     lukem 	struct ifreq isifr;
   2361       1.78    itojun 
   2362       1.78    itojun 	if (getifaddrs(&ifap) != 0)
   2363      1.120    atatat 		err(EXIT_FAILURE, "getifaddrs");
   2364       1.78    itojun 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
   2365       1.78    itojun 		if (strcmp(name, ifa->ifa_name) != 0)
   2366       1.78    itojun 			continue;
   2367       1.78    itojun 		if (ifa->ifa_addr->sa_family != AF_INET)
   2368       1.78    itojun 			continue;
   2369      1.121     lukem 		if (sizeof(isifr.ifr_addr) < ifa->ifa_addr->sa_len)
   2370       1.78    itojun 			continue;
   2371       1.78    itojun 
   2372      1.121     lukem 		memset(&isifr, 0, sizeof(isifr));
   2373      1.121     lukem 		strncpy(isifr.ifr_name, ifa->ifa_name, sizeof(isifr.ifr_name));
   2374      1.121     lukem 		memcpy(&isifr.ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len);
   2375      1.121     lukem 		in_alias(&isifr);
   2376       1.78    itojun 	}
   2377       1.78    itojun 	freeifaddrs(ifap);
   2378        1.1       cgd }
   2379        1.1       cgd 
   2380       1.53    itojun void
   2381       1.53    itojun setifprefixlen(addr, d)
   2382       1.80   thorpej 	const char *addr;
   2383       1.53    itojun 	int d;
   2384       1.53    itojun {
   2385       1.53    itojun 	if (*afp->af_getprefix)
   2386       1.53    itojun 		(*afp->af_getprefix)(addr, MASK);
   2387       1.53    itojun 	explicit_prefix = 1;
   2388       1.53    itojun }
   2389       1.53    itojun 
   2390       1.53    itojun #ifdef INET6
   2391       1.59    itojun void
   2392       1.59    itojun in6_fillscopeid(sin6)
   2393       1.59    itojun 	struct sockaddr_in6 *sin6;
   2394       1.59    itojun {
   2395       1.59    itojun #if defined(__KAME__) && defined(KAME_SCOPEID)
   2396       1.59    itojun 	if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr)) {
   2397       1.59    itojun 		sin6->sin6_scope_id =
   2398       1.59    itojun 			ntohs(*(u_int16_t *)&sin6->sin6_addr.s6_addr[2]);
   2399       1.59    itojun 		sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
   2400       1.59    itojun 	}
   2401       1.59    itojun #endif
   2402       1.59    itojun }
   2403       1.59    itojun 
   2404       1.53    itojun /* XXX not really an alias */
   2405       1.53    itojun void
   2406       1.53    itojun in6_alias(creq)
   2407       1.53    itojun 	struct in6_ifreq *creq;
   2408       1.53    itojun {
   2409       1.53    itojun 	struct sockaddr_in6 *sin6;
   2410       1.59    itojun 	char hbuf[NI_MAXHOST];
   2411       1.59    itojun 	u_int32_t scopeid;
   2412       1.59    itojun #ifdef NI_WITHSCOPEID
   2413       1.59    itojun 	const int niflag = NI_NUMERICHOST | NI_WITHSCOPEID;
   2414       1.59    itojun #else
   2415       1.59    itojun 	const int niflag = NI_NUMERICHOST;
   2416       1.59    itojun #endif
   2417       1.53    itojun 
   2418       1.53    itojun 	/* Get the non-alias address for this interface. */
   2419       1.53    itojun 	getsock(AF_INET6);
   2420       1.53    itojun 	if (s < 0) {
   2421       1.53    itojun 		if (errno == EPROTONOSUPPORT)
   2422       1.53    itojun 			return;
   2423      1.120    atatat 		err(EXIT_FAILURE, "socket");
   2424       1.53    itojun 	}
   2425       1.53    itojun 
   2426       1.53    itojun 	sin6 = (struct sockaddr_in6 *)&creq->ifr_addr;
   2427       1.53    itojun 
   2428       1.59    itojun 	in6_fillscopeid(sin6);
   2429       1.59    itojun 	scopeid = sin6->sin6_scope_id;
   2430       1.59    itojun 	if (getnameinfo((struct sockaddr *)sin6, sin6->sin6_len,
   2431       1.59    itojun 			hbuf, sizeof(hbuf), NULL, 0, niflag))
   2432      1.136    itojun 		strlcpy(hbuf, "", sizeof(hbuf));	/* some message? */
   2433       1.59    itojun 	printf("\tinet6 %s", hbuf);
   2434       1.53    itojun 
   2435       1.53    itojun 	if (flags & IFF_POINTOPOINT) {
   2436       1.53    itojun 		(void) memset(&ifr6, 0, sizeof(ifr6));
   2437       1.53    itojun 		(void) strncpy(ifr6.ifr_name, name, sizeof(ifr6.ifr_name));
   2438       1.53    itojun 		ifr6.ifr_addr = creq->ifr_addr;
   2439      1.120    atatat 		if (ioctl(s, SIOCGIFDSTADDR_IN6, (caddr_t)&ifr6) == -1) {
   2440       1.53    itojun 			if (errno != EADDRNOTAVAIL)
   2441       1.53    itojun 				warn("SIOCGIFDSTADDR_IN6");
   2442       1.53    itojun 			(void) memset(&ifr6.ifr_addr, 0, sizeof(ifr6.ifr_addr));
   2443       1.53    itojun 			ifr6.ifr_addr.sin6_family = AF_INET6;
   2444       1.53    itojun 			ifr6.ifr_addr.sin6_len = sizeof(struct sockaddr_in6);
   2445       1.53    itojun 		}
   2446       1.53    itojun 		sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr;
   2447       1.59    itojun 		in6_fillscopeid(sin6);
   2448       1.59    itojun 		hbuf[0] = '\0';
   2449       1.59    itojun 		if (getnameinfo((struct sockaddr *)sin6, sin6->sin6_len,
   2450       1.59    itojun 				hbuf, sizeof(hbuf), NULL, 0, niflag))
   2451      1.136    itojun 			strlcpy(hbuf, "", sizeof(hbuf)); /* some message? */
   2452       1.59    itojun 		printf(" -> %s", hbuf);
   2453       1.53    itojun 	}
   2454       1.53    itojun 
   2455       1.53    itojun 	(void) memset(&ifr6, 0, sizeof(ifr6));
   2456       1.53    itojun 	(void) strncpy(ifr6.ifr_name, name, sizeof(ifr6.ifr_name));
   2457       1.53    itojun 	ifr6.ifr_addr = creq->ifr_addr;
   2458      1.120    atatat 	if (ioctl(s, SIOCGIFNETMASK_IN6, (caddr_t)&ifr6) == -1) {
   2459       1.53    itojun 		if (errno != EADDRNOTAVAIL)
   2460       1.53    itojun 			warn("SIOCGIFNETMASK_IN6");
   2461       1.53    itojun 	} else {
   2462       1.53    itojun 		sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr;
   2463       1.53    itojun 		printf(" prefixlen %d", prefix(&sin6->sin6_addr,
   2464       1.53    itojun 					       sizeof(struct in6_addr)));
   2465       1.53    itojun 	}
   2466       1.53    itojun 
   2467       1.53    itojun 	(void) memset(&ifr6, 0, sizeof(ifr6));
   2468       1.53    itojun 	(void) strncpy(ifr6.ifr_name, name, sizeof(ifr6.ifr_name));
   2469       1.53    itojun 	ifr6.ifr_addr = creq->ifr_addr;
   2470      1.120    atatat 	if (ioctl(s, SIOCGIFAFLAG_IN6, (caddr_t)&ifr6) == -1) {
   2471       1.53    itojun 		if (errno != EADDRNOTAVAIL)
   2472       1.53    itojun 			warn("SIOCGIFAFLAG_IN6");
   2473       1.53    itojun 	} else {
   2474       1.53    itojun 		if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_ANYCAST)
   2475       1.53    itojun 			printf(" anycast");
   2476       1.53    itojun 		if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE)
   2477       1.53    itojun 			printf(" tentative");
   2478       1.53    itojun 		if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DUPLICATED)
   2479       1.53    itojun 			printf(" duplicated");
   2480       1.53    itojun 		if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DETACHED)
   2481       1.53    itojun 			printf(" detached");
   2482       1.91    itojun 		if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DEPRECATED)
   2483       1.91    itojun 			printf(" deprecated");
   2484       1.53    itojun 	}
   2485       1.53    itojun 
   2486       1.59    itojun 	if (scopeid)
   2487       1.59    itojun 		printf(" scopeid 0x%x", scopeid);
   2488       1.59    itojun 
   2489       1.53    itojun 	if (Lflag) {
   2490       1.53    itojun 		struct in6_addrlifetime *lifetime;
   2491       1.53    itojun 		(void) memset(&ifr6, 0, sizeof(ifr6));
   2492       1.53    itojun 		(void) strncpy(ifr6.ifr_name, name, sizeof(ifr6.ifr_name));
   2493       1.53    itojun 		ifr6.ifr_addr = creq->ifr_addr;
   2494       1.53    itojun 		lifetime = &ifr6.ifr_ifru.ifru_lifetime;
   2495      1.120    atatat 		if (ioctl(s, SIOCGIFALIFETIME_IN6, (caddr_t)&ifr6) == -1) {
   2496       1.53    itojun 			if (errno != EADDRNOTAVAIL)
   2497       1.53    itojun 				warn("SIOCGIFALIFETIME_IN6");
   2498       1.53    itojun 		} else if (lifetime->ia6t_preferred || lifetime->ia6t_expire) {
   2499       1.53    itojun 			time_t t = time(NULL);
   2500       1.53    itojun 			printf(" pltime ");
   2501       1.53    itojun 			if (lifetime->ia6t_preferred) {
   2502       1.53    itojun 				printf("%s", lifetime->ia6t_preferred < t
   2503       1.53    itojun 					? "0"
   2504       1.53    itojun 					: sec2str(lifetime->ia6t_preferred - t));
   2505       1.53    itojun 			} else
   2506       1.53    itojun 				printf("infty");
   2507       1.53    itojun 
   2508       1.53    itojun 			printf(" vltime ");
   2509       1.53    itojun 			if (lifetime->ia6t_expire) {
   2510       1.53    itojun 				printf("%s", lifetime->ia6t_expire < t
   2511       1.53    itojun 					? "0"
   2512       1.53    itojun 					: sec2str(lifetime->ia6t_expire - t));
   2513       1.53    itojun 			} else
   2514       1.53    itojun 				printf("infty");
   2515       1.53    itojun 		}
   2516       1.53    itojun 	}
   2517       1.53    itojun 
   2518       1.53    itojun 	printf("\n");
   2519       1.53    itojun }
   2520       1.53    itojun 
   2521       1.53    itojun void
   2522       1.53    itojun in6_status(force)
   2523       1.53    itojun 	int force;
   2524       1.53    itojun {
   2525       1.78    itojun 	struct ifaddrs *ifap, *ifa;
   2526      1.121     lukem 	struct in6_ifreq isifr;
   2527       1.78    itojun 
   2528       1.78    itojun 	if (getifaddrs(&ifap) != 0)
   2529      1.120    atatat 		err(EXIT_FAILURE, "getifaddrs");
   2530       1.78    itojun 	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
   2531       1.78    itojun 		if (strcmp(name, ifa->ifa_name) != 0)
   2532       1.78    itojun 			continue;
   2533       1.78    itojun 		if (ifa->ifa_addr->sa_family != AF_INET6)
   2534       1.78    itojun 			continue;
   2535      1.121     lukem 		if (sizeof(isifr.ifr_addr) < ifa->ifa_addr->sa_len)
   2536       1.78    itojun 			continue;
   2537       1.78    itojun 
   2538      1.121     lukem 		memset(&isifr, 0, sizeof(isifr));
   2539      1.121     lukem 		strncpy(isifr.ifr_name, ifa->ifa_name, sizeof(isifr.ifr_name));
   2540      1.121     lukem 		memcpy(&isifr.ifr_addr, ifa->ifa_addr, ifa->ifa_addr->sa_len);
   2541      1.121     lukem 		in6_alias(&isifr);
   2542       1.78    itojun 	}
   2543       1.78    itojun 	freeifaddrs(ifap);
   2544       1.53    itojun }
   2545       1.53    itojun #endif /*INET6*/
   2546       1.53    itojun 
   2547       1.21       gwr #ifndef INET_ONLY
   2548       1.21       gwr 
   2549       1.16       cgd void
   2550       1.32  christos at_status(force)
   2551       1.32  christos 	int force;
   2552       1.32  christos {
   2553       1.32  christos 	struct sockaddr_at *sat, null_sat;
   2554       1.32  christos 	struct netrange *nr;
   2555       1.32  christos 
   2556       1.32  christos 	getsock(AF_APPLETALK);
   2557       1.32  christos 	if (s < 0) {
   2558       1.32  christos 		if (errno == EPROTONOSUPPORT)
   2559       1.32  christos 			return;
   2560      1.120    atatat 		err(EXIT_FAILURE, "socket");
   2561       1.32  christos 	}
   2562       1.32  christos 	(void) memset(&ifr, 0, sizeof(ifr));
   2563       1.32  christos 	(void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
   2564      1.120    atatat 	if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) == -1) {
   2565       1.32  christos 		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
   2566       1.32  christos 			if (!force)
   2567       1.32  christos 				return;
   2568       1.32  christos 			(void) memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
   2569       1.32  christos 		} else
   2570       1.32  christos 			warn("SIOCGIFADDR");
   2571       1.32  christos 	}
   2572       1.32  christos 	(void) strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
   2573       1.32  christos 	sat = (struct sockaddr_at *)&ifr.ifr_addr;
   2574       1.32  christos 
   2575       1.32  christos 	(void) memset(&null_sat, 0, sizeof(null_sat));
   2576       1.32  christos 
   2577       1.32  christos 	nr = (struct netrange *) &sat->sat_zero;
   2578       1.32  christos 	printf("\tatalk %d.%d range %d-%d phase %d",
   2579       1.32  christos 	    ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node,
   2580       1.32  christos 	    ntohs(nr->nr_firstnet), ntohs(nr->nr_lastnet), nr->nr_phase);
   2581       1.32  christos 	if (flags & IFF_POINTOPOINT) {
   2582      1.120    atatat 		if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) == -1) {
   2583       1.32  christos 			if (errno == EADDRNOTAVAIL)
   2584       1.32  christos 			    (void) memset(&ifr.ifr_addr, 0,
   2585       1.32  christos 				sizeof(ifr.ifr_addr));
   2586       1.32  christos 			else
   2587       1.32  christos 			    warn("SIOCGIFDSTADDR");
   2588       1.32  christos 		}
   2589       1.32  christos 		(void) strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
   2590       1.32  christos 		sat = (struct sockaddr_at *)&ifr.ifr_dstaddr;
   2591       1.32  christos 		if (!sat)
   2592       1.32  christos 			sat = &null_sat;
   2593       1.32  christos 		printf("--> %d.%d",
   2594       1.32  christos 		    ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node);
   2595       1.32  christos 	}
   2596       1.32  christos 	if (flags & IFF_BROADCAST) {
   2597       1.32  christos 		/* note RTAX_BRD overlap with IFF_POINTOPOINT */
   2598       1.32  christos 		sat = (struct sockaddr_at *)&ifr.ifr_broadaddr;
   2599       1.32  christos 		if (sat)
   2600       1.32  christos 			printf(" broadcast %d.%d", ntohs(sat->sat_addr.s_net),
   2601       1.32  christos 			    sat->sat_addr.s_node);
   2602       1.32  christos 	}
   2603       1.32  christos 	putchar('\n');
   2604       1.32  christos }
   2605       1.32  christos 
   2606       1.32  christos void
   2607        1.1       cgd xns_status(force)
   2608        1.1       cgd 	int force;
   2609        1.1       cgd {
   2610        1.1       cgd 	struct sockaddr_ns *sns;
   2611        1.1       cgd 
   2612       1.13   mycroft 	getsock(AF_NS);
   2613       1.13   mycroft 	if (s < 0) {
   2614       1.13   mycroft 		if (errno == EPROTONOSUPPORT)
   2615        1.1       cgd 			return;
   2616      1.120    atatat 		err(EXIT_FAILURE, "socket");
   2617       1.13   mycroft 	}
   2618       1.32  christos 	(void) memset(&ifr, 0, sizeof(ifr));
   2619       1.32  christos 	(void) strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
   2620      1.120    atatat 	if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) == -1) {
   2621        1.1       cgd 		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
   2622        1.1       cgd 			if (!force)
   2623        1.1       cgd 				return;
   2624       1.14   mycroft 			memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
   2625        1.1       cgd 		} else
   2626       1.13   mycroft 			warn("SIOCGIFADDR");
   2627        1.1       cgd 	}
   2628       1.32  christos 	(void) strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
   2629        1.1       cgd 	sns = (struct sockaddr_ns *)&ifr.ifr_addr;
   2630        1.1       cgd 	printf("\tns %s ", ns_ntoa(sns->sns_addr));
   2631        1.1       cgd 	if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */
   2632      1.120    atatat 		if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) == -1) {
   2633        1.1       cgd 			if (errno == EADDRNOTAVAIL)
   2634       1.14   mycroft 			    memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
   2635        1.1       cgd 			else
   2636       1.13   mycroft 			    warn("SIOCGIFDSTADDR");
   2637        1.1       cgd 		}
   2638       1.32  christos 		(void) strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
   2639        1.1       cgd 		sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr;
   2640        1.1       cgd 		printf("--> %s ", ns_ntoa(sns->sns_addr));
   2641        1.1       cgd 	}
   2642        1.1       cgd 	putchar('\n');
   2643        1.1       cgd }
   2644        1.1       cgd 
   2645       1.16       cgd void
   2646        1.1       cgd iso_status(force)
   2647        1.1       cgd 	int force;
   2648        1.1       cgd {
   2649        1.1       cgd 	struct sockaddr_iso *siso;
   2650      1.121     lukem 	struct iso_ifreq isoifr;
   2651        1.1       cgd 
   2652       1.13   mycroft 	getsock(AF_ISO);
   2653       1.13   mycroft 	if (s < 0) {
   2654       1.13   mycroft 		if (errno == EPROTONOSUPPORT)
   2655        1.1       cgd 			return;
   2656      1.120    atatat 		err(EXIT_FAILURE, "socket");
   2657       1.13   mycroft 	}
   2658      1.121     lukem 	(void) memset(&isoifr, 0, sizeof(isoifr));
   2659      1.121     lukem 	(void) strncpy(isoifr.ifr_name, name, sizeof(isoifr.ifr_name));
   2660      1.121     lukem 	if (ioctl(s, SIOCGIFADDR_ISO, (caddr_t)&isoifr) == -1) {
   2661        1.1       cgd 		if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
   2662        1.1       cgd 			if (!force)
   2663        1.1       cgd 				return;
   2664      1.121     lukem 			(void) memset(&isoifr.ifr_Addr, 0,
   2665      1.121     lukem 			    sizeof(isoifr.ifr_Addr));
   2666       1.13   mycroft 		} else
   2667       1.50    chopps 			warn("SIOCGIFADDR_ISO");
   2668        1.1       cgd 	}
   2669      1.121     lukem 	(void) strncpy(isoifr.ifr_name, name, sizeof isoifr.ifr_name);
   2670      1.121     lukem 	siso = &isoifr.ifr_Addr;
   2671        1.1       cgd 	printf("\tiso %s ", iso_ntoa(&siso->siso_addr));
   2672      1.121     lukem 	if (ioctl(s, SIOCGIFNETMASK_ISO, (caddr_t)&isoifr) == -1) {
   2673       1.13   mycroft 		if (errno == EADDRNOTAVAIL)
   2674      1.121     lukem 			memset(&isoifr.ifr_Addr, 0, sizeof(isoifr.ifr_Addr));
   2675       1.13   mycroft 		else
   2676       1.50    chopps 			warn("SIOCGIFNETMASK_ISO");
   2677        1.1       cgd 	} else {
   2678       1.50    chopps 		if (siso->siso_len > offsetof(struct sockaddr_iso, siso_addr))
   2679       1.50    chopps 			siso->siso_addr.isoa_len = siso->siso_len
   2680       1.50    chopps 			    - offsetof(struct sockaddr_iso, siso_addr);
   2681       1.50    chopps 		printf("\n\t\tnetmask %s ", iso_ntoa(&siso->siso_addr));
   2682        1.1       cgd 	}
   2683        1.1       cgd 	if (flags & IFF_POINTOPOINT) {
   2684      1.121     lukem 		if (ioctl(s, SIOCGIFDSTADDR_ISO, (caddr_t)&isoifr) == -1) {
   2685        1.1       cgd 			if (errno == EADDRNOTAVAIL)
   2686      1.121     lukem 			    memset(&isoifr.ifr_Addr, 0,
   2687      1.121     lukem 				sizeof(isoifr.ifr_Addr));
   2688        1.1       cgd 			else
   2689       1.50    chopps 			    warn("SIOCGIFDSTADDR_ISO");
   2690        1.1       cgd 		}
   2691      1.121     lukem 		(void) strncpy(isoifr.ifr_name, name, sizeof (isoifr.ifr_name));
   2692      1.121     lukem 		siso = &isoifr.ifr_Addr;
   2693        1.1       cgd 		printf("--> %s ", iso_ntoa(&siso->siso_addr));
   2694        1.1       cgd 	}
   2695        1.1       cgd 	putchar('\n');
   2696        1.1       cgd }
   2697        1.1       cgd 
   2698       1.21       gwr #endif	/* INET_ONLY */
   2699       1.21       gwr 
   2700        1.1       cgd #define SIN(x) ((struct sockaddr_in *) &(x))
   2701        1.1       cgd struct sockaddr_in *sintab[] = {
   2702      1.122    itojun SIN(ridreq.ifr_addr), SIN(in_addreq.ifra_addr),
   2703      1.122    itojun SIN(in_addreq.ifra_mask), SIN(in_addreq.ifra_broadaddr)};
   2704        1.1       cgd 
   2705       1.16       cgd void
   2706      1.121     lukem in_getaddr(str, which)
   2707      1.121     lukem 	const char *str;
   2708       1.16       cgd 	int which;
   2709        1.1       cgd {
   2710      1.121     lukem 	struct sockaddr_in *gasin = sintab[which];
   2711        1.1       cgd 	struct hostent *hp;
   2712        1.1       cgd 	struct netent *np;
   2713        1.1       cgd 
   2714      1.121     lukem 	gasin->sin_len = sizeof(*gasin);
   2715        1.1       cgd 	if (which != MASK)
   2716      1.121     lukem 		gasin->sin_family = AF_INET;
   2717        1.1       cgd 
   2718       1.60      joda 	if (which == ADDR) {
   2719       1.60      joda 		char *p = NULL;
   2720      1.121     lukem 		if ((p = strrchr(str, '/')) != NULL) {
   2721       1.96    itojun 			*p = '\0';
   2722       1.96    itojun 			in_getprefix(p + 1, MASK);
   2723       1.96    itojun 		}
   2724       1.60      joda 	}
   2725       1.60      joda 
   2726      1.121     lukem 	if (inet_aton(str, &gasin->sin_addr) == 0) {
   2727      1.121     lukem 		if ((hp = gethostbyname(str)) != NULL)
   2728      1.121     lukem 			(void) memcpy(&gasin->sin_addr, hp->h_addr, hp->h_length);
   2729      1.121     lukem 		else if ((np = getnetbyname(str)) != NULL)
   2730      1.121     lukem 			gasin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
   2731       1.20   mycroft 		else
   2732      1.127    itojun 			errx(EXIT_FAILURE, "%s: bad value", str);
   2733       1.20   mycroft 	}
   2734       1.95    itojun }
   2735       1.95    itojun 
   2736       1.95    itojun void
   2737       1.95    itojun in_getprefix(plen, which)
   2738       1.95    itojun 	const char *plen;
   2739       1.95    itojun 	int which;
   2740       1.95    itojun {
   2741      1.121     lukem 	register struct sockaddr_in *igsin = sintab[which];
   2742       1.95    itojun 	register u_char *cp;
   2743       1.95    itojun 	int len = strtol(plen, (char **)NULL, 10);
   2744       1.95    itojun 
   2745       1.95    itojun 	if ((len < 0) || (len > 32))
   2746      1.127    itojun 		errx(EXIT_FAILURE, "%s: bad value", plen);
   2747      1.121     lukem 	igsin->sin_len = sizeof(*igsin);
   2748       1.95    itojun 	if (which != MASK)
   2749      1.121     lukem 		igsin->sin_family = AF_INET;
   2750       1.95    itojun 	if ((len == 0) || (len == 32)) {
   2751      1.121     lukem 		memset(&igsin->sin_addr, 0xff, sizeof(struct in_addr));
   2752       1.95    itojun 		return;
   2753       1.95    itojun 	}
   2754      1.121     lukem 	memset((void *)&igsin->sin_addr, 0x00, sizeof(igsin->sin_addr));
   2755      1.121     lukem 	for (cp = (u_char *)&igsin->sin_addr; len > 7; len -= 8)
   2756       1.95    itojun 		*cp++ = 0xff;
   2757      1.110    itojun 	if (len)
   2758      1.110    itojun 		*cp = 0xff << (8 - len);
   2759        1.1       cgd }
   2760        1.1       cgd 
   2761       1.53    itojun #ifdef INET6
   2762       1.53    itojun #define SIN6(x) ((struct sockaddr_in6 *) &(x))
   2763       1.53    itojun struct sockaddr_in6 *sin6tab[] = {
   2764       1.53    itojun SIN6(in6_ridreq.ifr_addr), SIN6(in6_addreq.ifra_addr),
   2765       1.53    itojun SIN6(in6_addreq.ifra_prefixmask), SIN6(in6_addreq.ifra_dstaddr)};
   2766       1.53    itojun 
   2767       1.53    itojun void
   2768      1.121     lukem in6_getaddr(str, which)
   2769      1.121     lukem 	const char *str;
   2770       1.53    itojun 	int which;
   2771       1.53    itojun {
   2772       1.59    itojun #if defined(__KAME__) && defined(KAME_SCOPEID)
   2773       1.59    itojun 	struct sockaddr_in6 *sin6 = sin6tab[which];
   2774       1.59    itojun 	struct addrinfo hints, *res;
   2775       1.59    itojun 	int error;
   2776      1.137  christos 	char *slash = NULL;
   2777      1.137  christos 
   2778      1.137  christos 	if (which == ADDR) {
   2779      1.137  christos 		if ((slash = strrchr(str, '/')) != NULL)
   2780      1.137  christos 			*slash = '\0';
   2781      1.137  christos 	}
   2782       1.59    itojun 
   2783       1.59    itojun 	memset(&hints, 0, sizeof(hints));
   2784       1.59    itojun 	hints.ai_family = AF_INET6;
   2785       1.59    itojun 	hints.ai_socktype = SOCK_DGRAM;
   2786       1.59    itojun #if 0 /* in_getaddr() allows FQDN */
   2787       1.59    itojun 	hints.ai_flags = AI_NUMERICHOST;
   2788       1.59    itojun #endif
   2789      1.121     lukem 	error = getaddrinfo(str, "0", &hints, &res);
   2790      1.137  christos 	if (error && slash) {
   2791      1.137  christos 		/* try again treating the '/' as part of the name */
   2792      1.137  christos 		*slash = '/';
   2793      1.137  christos 		slash = NULL;
   2794      1.137  christos 		error = getaddrinfo(str, "0", &hints, &res);
   2795      1.137  christos 	}
   2796       1.59    itojun 	if (error)
   2797      1.127    itojun 		errx(EXIT_FAILURE, "%s: %s", str, gai_strerror(error));
   2798       1.59    itojun 	if (res->ai_next)
   2799      1.137  christos 		errx(EXIT_FAILURE, "%s: resolved to multiple addresses", str);
   2800       1.59    itojun 	if (res->ai_addrlen != sizeof(struct sockaddr_in6))
   2801      1.127    itojun 		errx(EXIT_FAILURE, "%s: bad value", str);
   2802       1.59    itojun 	memcpy(sin6, res->ai_addr, res->ai_addrlen);
   2803       1.59    itojun 	freeaddrinfo(res);
   2804       1.59    itojun 	if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && sin6->sin6_scope_id) {
   2805       1.59    itojun 		*(u_int16_t *)&sin6->sin6_addr.s6_addr[2] =
   2806       1.59    itojun 			htons(sin6->sin6_scope_id);
   2807       1.59    itojun 		sin6->sin6_scope_id = 0;
   2808      1.137  christos 	}
   2809      1.137  christos 	if (slash) {
   2810      1.137  christos 		in6_getprefix(slash + 1, MASK);
   2811      1.137  christos 		explicit_prefix = 1;
   2812       1.59    itojun 	}
   2813       1.59    itojun #else
   2814      1.121     lukem 	struct sockaddr_in6 *gasin = sin6tab[which];
   2815       1.53    itojun 
   2816      1.121     lukem 	gasin->sin6_len = sizeof(*gasin);
   2817       1.53    itojun 	if (which != MASK)
   2818      1.121     lukem 		gasin->sin6_family = AF_INET6;
   2819       1.60      joda 
   2820       1.60      joda 	if (which == ADDR) {
   2821       1.60      joda 		char *p = NULL;
   2822      1.121     lukem 		if((p = strrchr(str, '/')) != NULL) {
   2823       1.60      joda 			*p = '\0';
   2824       1.60      joda 			in6_getprefix(p + 1, MASK);
   2825       1.60      joda 			explicit_prefix = 1;
   2826       1.60      joda 		}
   2827       1.60      joda 	}
   2828       1.53    itojun 
   2829      1.121     lukem 	if (inet_pton(AF_INET6, str, &gasin->sin6_addr) != 1)
   2830      1.127    itojun 		errx(EXIT_FAILURE, "%s: bad value", str);
   2831       1.59    itojun #endif
   2832       1.53    itojun }
   2833       1.53    itojun 
   2834       1.53    itojun void
   2835       1.53    itojun in6_getprefix(plen, which)
   2836       1.80   thorpej 	const char *plen;
   2837       1.53    itojun 	int which;
   2838       1.53    itojun {
   2839      1.121     lukem 	register struct sockaddr_in6 *gpsin = sin6tab[which];
   2840       1.53    itojun 	register u_char *cp;
   2841       1.53    itojun 	int len = strtol(plen, (char **)NULL, 10);
   2842       1.53    itojun 
   2843       1.53    itojun 	if ((len < 0) || (len > 128))
   2844      1.127    itojun 		errx(EXIT_FAILURE, "%s: bad value", plen);
   2845      1.121     lukem 	gpsin->sin6_len = sizeof(*gpsin);
   2846       1.53    itojun 	if (which != MASK)
   2847      1.121     lukem 		gpsin->sin6_family = AF_INET6;
   2848       1.53    itojun 	if ((len == 0) || (len == 128)) {
   2849      1.121     lukem 		memset(&gpsin->sin6_addr, 0xff, sizeof(struct in6_addr));
   2850       1.53    itojun 		return;
   2851       1.53    itojun 	}
   2852      1.121     lukem 	memset((void *)&gpsin->sin6_addr, 0x00, sizeof(gpsin->sin6_addr));
   2853      1.121     lukem 	for (cp = (u_char *)&gpsin->sin6_addr; len > 7; len -= 8)
   2854       1.53    itojun 		*cp++ = 0xff;
   2855      1.110    itojun 	if (len)
   2856      1.110    itojun 		*cp = 0xff << (8 - len);
   2857       1.53    itojun }
   2858       1.53    itojun 
   2859       1.53    itojun int
   2860       1.53    itojun prefix(val, size)
   2861       1.53    itojun 	void *val;
   2862       1.53    itojun 	int size;
   2863       1.53    itojun {
   2864      1.121     lukem 	register u_char *pname = (u_char *)val;
   2865       1.53    itojun 	register int byte, bit, plen = 0;
   2866       1.53    itojun 
   2867       1.53    itojun 	for (byte = 0; byte < size; byte++, plen += 8)
   2868      1.121     lukem 		if (pname[byte] != 0xff)
   2869       1.53    itojun 			break;
   2870       1.53    itojun 	if (byte == size)
   2871       1.53    itojun 		return (plen);
   2872       1.53    itojun 	for (bit = 7; bit != 0; bit--, plen++)
   2873      1.121     lukem 		if (!(pname[byte] & (1 << bit)))
   2874       1.53    itojun 			break;
   2875       1.53    itojun 	for (; bit != 0; bit--)
   2876      1.121     lukem 		if (pname[byte] & (1 << bit))
   2877       1.53    itojun 			return(0);
   2878       1.53    itojun 	byte++;
   2879       1.53    itojun 	for (; byte < size; byte++)
   2880      1.121     lukem 		if (pname[byte])
   2881       1.53    itojun 			return(0);
   2882       1.53    itojun 	return (plen);
   2883       1.53    itojun }
   2884       1.53    itojun #endif /*INET6*/
   2885       1.53    itojun 
   2886       1.21       gwr #ifndef INET_ONLY
   2887       1.32  christos void
   2888       1.32  christos at_getaddr(addr, which)
   2889       1.80   thorpej 	const char *addr;
   2890       1.32  christos 	int which;
   2891       1.32  christos {
   2892       1.32  christos 	struct sockaddr_at *sat = (struct sockaddr_at *) &addreq.ifra_addr;
   2893       1.32  christos 	u_int net, node;
   2894       1.32  christos 
   2895       1.32  christos 	sat->sat_family = AF_APPLETALK;
   2896       1.32  christos 	sat->sat_len = sizeof(*sat);
   2897       1.32  christos 	if (which == MASK)
   2898      1.129     grant 		errx(EXIT_FAILURE, "AppleTalk does not use netmasks");
   2899       1.32  christos 	if (sscanf(addr, "%u.%u", &net, &node) != 2
   2900       1.32  christos 	    || net == 0 || net > 0xffff || node == 0 || node > 0xfe)
   2901      1.127    itojun 		errx(EXIT_FAILURE, "%s: illegal address", addr);
   2902       1.32  christos 	sat->sat_addr.s_net = htons(net);
   2903       1.32  christos 	sat->sat_addr.s_node = node;
   2904       1.32  christos }
   2905       1.32  christos 
   2906       1.32  christos void
   2907       1.32  christos setatrange(range, d)
   2908       1.80   thorpej 	const char *range;
   2909       1.32  christos 	int d;
   2910       1.32  christos {
   2911       1.32  christos 	u_short	first = 123, last = 123;
   2912       1.32  christos 
   2913       1.32  christos 	if (sscanf(range, "%hu-%hu", &first, &last) != 2
   2914      1.123   thorpej 	    || first == 0 /* || first > 0xffff */
   2915      1.123   thorpej 	    || last == 0 /* || last > 0xffff */ || first > last)
   2916      1.127    itojun 		errx(EXIT_FAILURE, "%s: illegal net range: %u-%u", range,
   2917      1.127    itojun 		    first, last);
   2918       1.32  christos 	at_nr.nr_firstnet = htons(first);
   2919       1.32  christos 	at_nr.nr_lastnet = htons(last);
   2920       1.32  christos }
   2921       1.32  christos 
   2922       1.32  christos void
   2923       1.32  christos setatphase(phase, d)
   2924       1.80   thorpej 	const char *phase;
   2925       1.32  christos 	int d;
   2926       1.32  christos {
   2927       1.32  christos 	if (!strcmp(phase, "1"))
   2928       1.32  christos 		at_nr.nr_phase = 1;
   2929       1.32  christos 	else if (!strcmp(phase, "2"))
   2930       1.32  christos 		at_nr.nr_phase = 2;
   2931       1.32  christos 	else
   2932      1.127    itojun 		errx(EXIT_FAILURE, "%s: illegal phase", phase);
   2933       1.32  christos }
   2934       1.32  christos 
   2935       1.32  christos void
   2936       1.32  christos checkatrange(sat)
   2937       1.32  christos 	struct sockaddr_at *sat;
   2938       1.32  christos {
   2939       1.32  christos 	if (at_nr.nr_phase == 0)
   2940       1.32  christos 		at_nr.nr_phase = 2;	/* Default phase 2 */
   2941       1.32  christos 	if (at_nr.nr_firstnet == 0)
   2942       1.32  christos 		at_nr.nr_firstnet =	/* Default range of one */
   2943       1.32  christos 		at_nr.nr_lastnet = sat->sat_addr.s_net;
   2944       1.32  christos 	printf("\tatalk %d.%d range %d-%d phase %d\n",
   2945       1.32  christos 	ntohs(sat->sat_addr.s_net), sat->sat_addr.s_node,
   2946       1.32  christos 	ntohs(at_nr.nr_firstnet), ntohs(at_nr.nr_lastnet), at_nr.nr_phase);
   2947       1.32  christos 	if ((u_short) ntohs(at_nr.nr_firstnet) >
   2948       1.32  christos 			(u_short) ntohs(sat->sat_addr.s_net)
   2949       1.32  christos 		    || (u_short) ntohs(at_nr.nr_lastnet) <
   2950       1.32  christos 			(u_short) ntohs(sat->sat_addr.s_net))
   2951      1.127    itojun 		errx(EXIT_FAILURE, "AppleTalk address is not in range");
   2952       1.32  christos 	*((struct netrange *) &sat->sat_zero) = at_nr;
   2953       1.32  christos }
   2954       1.32  christos 
   2955        1.1       cgd #define SNS(x) ((struct sockaddr_ns *) &(x))
   2956        1.1       cgd struct sockaddr_ns *snstab[] = {
   2957        1.1       cgd SNS(ridreq.ifr_addr), SNS(addreq.ifra_addr),
   2958        1.1       cgd SNS(addreq.ifra_mask), SNS(addreq.ifra_broadaddr)};
   2959        1.1       cgd 
   2960       1.16       cgd void
   2961        1.1       cgd xns_getaddr(addr, which)
   2962       1.80   thorpej 	const char *addr;
   2963       1.16       cgd 	int which;
   2964        1.1       cgd {
   2965        1.1       cgd 	struct sockaddr_ns *sns = snstab[which];
   2966        1.1       cgd 
   2967        1.1       cgd 	sns->sns_family = AF_NS;
   2968        1.1       cgd 	sns->sns_len = sizeof(*sns);
   2969        1.1       cgd 	sns->sns_addr = ns_addr(addr);
   2970        1.1       cgd 	if (which == MASK)
   2971       1.34     lukem 		puts("Attempt to set XNS netmask will be ineffectual");
   2972        1.1       cgd }
   2973        1.1       cgd 
   2974        1.1       cgd #define SISO(x) ((struct sockaddr_iso *) &(x))
   2975        1.1       cgd struct sockaddr_iso *sisotab[] = {
   2976       1.50    chopps SISO(iso_ridreq.ifr_Addr), SISO(iso_addreq.ifra_addr),
   2977        1.1       cgd SISO(iso_addreq.ifra_mask), SISO(iso_addreq.ifra_dstaddr)};
   2978        1.1       cgd 
   2979       1.16       cgd void
   2980        1.1       cgd iso_getaddr(addr, which)
   2981       1.80   thorpej 	const char *addr;
   2982       1.16       cgd 	int which;
   2983        1.1       cgd {
   2984       1.39     lukem 	struct sockaddr_iso *siso = sisotab[which];
   2985        1.1       cgd 	siso->siso_addr = *iso_addr(addr);
   2986        1.1       cgd 
   2987        1.1       cgd 	if (which == MASK) {
   2988        1.1       cgd 		siso->siso_len = TSEL(siso) - (caddr_t)(siso);
   2989        1.1       cgd 		siso->siso_nlen = 0;
   2990        1.1       cgd 	} else {
   2991        1.1       cgd 		siso->siso_len = sizeof(*siso);
   2992        1.1       cgd 		siso->siso_family = AF_ISO;
   2993        1.1       cgd 	}
   2994        1.1       cgd }
   2995        1.1       cgd 
   2996       1.16       cgd void
   2997       1.32  christos setsnpaoffset(val, d)
   2998       1.80   thorpej 	const char *val;
   2999       1.32  christos 	int d;
   3000       1.21       gwr {
   3001       1.21       gwr 	iso_addreq.ifra_snpaoffset = atoi(val);
   3002       1.21       gwr }
   3003       1.21       gwr 
   3004       1.21       gwr void
   3005       1.32  christos setnsellength(val, d)
   3006       1.80   thorpej 	const char *val;
   3007       1.32  christos 	int d;
   3008        1.1       cgd {
   3009        1.1       cgd 	nsellength = atoi(val);
   3010       1.12       cgd 	if (nsellength < 0)
   3011      1.127    itojun 		errx(EXIT_FAILURE, "Negative NSEL length is absurd");
   3012       1.12       cgd 	if (afp == 0 || afp->af_af != AF_ISO)
   3013      1.127    itojun 		errx(EXIT_FAILURE, "Setting NSEL length valid only for iso");
   3014        1.1       cgd }
   3015        1.1       cgd 
   3016       1.16       cgd void
   3017      1.121     lukem fixnsel(siso)
   3018      1.121     lukem 	struct sockaddr_iso *siso;
   3019        1.1       cgd {
   3020      1.121     lukem 	if (siso->siso_family == 0)
   3021        1.1       cgd 		return;
   3022      1.121     lukem 	siso->siso_tlen = nsellength;
   3023        1.1       cgd }
   3024        1.1       cgd 
   3025       1.16       cgd void
   3026        1.1       cgd adjust_nsellength()
   3027        1.1       cgd {
   3028        1.1       cgd 	fixnsel(sisotab[RIDADDR]);
   3029        1.1       cgd 	fixnsel(sisotab[ADDR]);
   3030        1.1       cgd 	fixnsel(sisotab[DSTADDR]);
   3031       1.18     glass }
   3032       1.21       gwr 
   3033       1.21       gwr #endif	/* INET_ONLY */
   3034       1.18     glass 
   3035       1.18     glass void
   3036       1.18     glass usage()
   3037       1.18     glass {
   3038       1.99       cgd 	const char *progname = getprogname();
   3039       1.80   thorpej 
   3040       1.31   thorpej 	fprintf(stderr,
   3041      1.134     perry 	    "usage: %s [-m] [-v] [-z] "
   3042       1.53    itojun #ifdef INET6
   3043      1.134     perry 		"[-L] "
   3044       1.53    itojun #endif
   3045       1.80   thorpej 		"interface\n"
   3046      1.105    itojun 		"\t[ af [ address [ dest_addr ] ] [ netmask mask ] [ prefixlen n ]\n"
   3047      1.105    itojun 		"\t\t[ alias | -alias ] ]\n"
   3048      1.104    itojun 		"\t[ up ] [ down ] [ metric n ] [ mtu n ]\n"
   3049       1.93      onoe 		"\t[ nwid network_id ] [ nwkey network_key | -nwkey ]\n"
   3050       1.93      onoe 		"\t[ powersave | -powersave ] [ powersavesleep duration ]\n"
   3051       1.93      onoe 		"\t[ [ af ] tunnel src_addr dest_addr ] [ deletetunnel ]\n"
   3052       1.80   thorpej 		"\t[ arp | -arp ]\n"
   3053       1.93      onoe 		"\t[ media type ] [ mediaopt opts ] [ -mediaopt opts ] "
   3054       1.93      onoe 		"[ instance minst ]\n"
   3055       1.89   thorpej 		"\t[ vlan n vlanif i ]\n"
   3056      1.104    itojun 		"\t[ anycast | -anycast ] [ deprecated | -deprecated ]\n"
   3057      1.127    itojun 		"\t[ tentative | -tentative ] [ pltime n ] [ vltime n ] [ eui64 ]\n"
   3058       1.80   thorpej 		"\t[ link0 | -link0 ] [ link1 | -link1 ] [ link2 | -link2 ]\n"
   3059      1.134     perry 		"       %s -a [-b] [-m] [-d] [-u] [-v] [-z] [ af ]\n"
   3060      1.134     perry 		"       %s -l [-b] [-d] [-u] [-s]\n"
   3061      1.101  christos 		"       %s -C\n"
   3062       1.81   thorpej 		"       %s interface create\n"
   3063       1.81   thorpej 		"       %s interface destroy\n",
   3064      1.101  christos 		progname, progname, progname, progname, progname, progname);
   3065       1.18     glass 	exit(1);
   3066        1.1       cgd }
   3067       1.53    itojun 
   3068       1.53    itojun #ifdef INET6
   3069       1.53    itojun char *
   3070       1.53    itojun sec2str(total)
   3071       1.53    itojun 	time_t total;
   3072       1.53    itojun {
   3073       1.53    itojun 	static char result[256];
   3074       1.53    itojun 	int days, hours, mins, secs;
   3075       1.53    itojun 	int first = 1;
   3076       1.53    itojun 	char *p = result;
   3077      1.114    itojun 	char *end = &result[sizeof(result)];
   3078      1.114    itojun 	int n;
   3079       1.53    itojun 
   3080       1.53    itojun 	if (0) {	/*XXX*/
   3081       1.53    itojun 		days = total / 3600 / 24;
   3082       1.53    itojun 		hours = (total / 3600) % 24;
   3083       1.53    itojun 		mins = (total / 60) % 60;
   3084       1.53    itojun 		secs = total % 60;
   3085       1.53    itojun 
   3086       1.53    itojun 		if (days) {
   3087       1.53    itojun 			first = 0;
   3088      1.114    itojun 			n = snprintf(p, end - p, "%dd", days);
   3089      1.114    itojun 			if (n < 0 || n >= end - p)
   3090      1.114    itojun 				return(result);
   3091      1.114    itojun 			p += n;
   3092       1.53    itojun 		}
   3093       1.53    itojun 		if (!first || hours) {
   3094       1.53    itojun 			first = 0;
   3095      1.114    itojun 			n = snprintf(p, end - p, "%dh", hours);
   3096      1.114    itojun 			if (n < 0 || n >= end - p)
   3097      1.114    itojun 				return(result);
   3098      1.114    itojun 			p += n;
   3099       1.53    itojun 		}
   3100       1.53    itojun 		if (!first || mins) {
   3101       1.53    itojun 			first = 0;
   3102      1.114    itojun 			n = snprintf(p, end - p, "%dm", mins);
   3103      1.114    itojun 			if (n < 0 || n >= end - p)
   3104      1.114    itojun 				return(result);
   3105      1.114    itojun 			p += n;
   3106       1.53    itojun 		}
   3107      1.114    itojun 		snprintf(p, end - p, "%ds", secs);
   3108       1.53    itojun 	} else
   3109      1.114    itojun 		snprintf(p, end - p, "%lu", (u_long)total);
   3110       1.53    itojun 
   3111       1.53    itojun 	return(result);
   3112       1.53    itojun }
   3113       1.53    itojun #endif
   3114