2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 static const char copyright
[] =
36 "@(#) Copyright (c) 1983, 1993\n\
37 The Regents of the University of California. All rights reserved.\n";
42 static char sccsid
[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94";
44 static const char rcsid
[] =
45 "$Id: ifconfig.c,v 1.8 2004/08/26 23:55:21 lindak Exp $";
49 #include <sys/param.h>
50 #define KERNEL_PRIVATE
51 #include <sys/ioctl.h>
53 #include <sys/socket.h>
54 #include <sys/sysctl.h>
57 #include <net/ethernet.h>
59 #include <net/if_var.h>
60 #include <net/if_dl.h>
61 #include <net/if_types.h>
62 #include <net/route.h>
65 #include <netinet/in.h>
66 #include <netinet/in_var.h>
67 #include <arpa/inet.h>
71 #include <netinet6/nd6.h> /* Define ND6_INFINITE_LIFETIME */
87 /* wrapper for KAME-special getnameinfo() */
88 #ifndef NI_WITHSCOPEID
89 #define NI_WITHSCOPEID 0
92 struct ifreq ifr
, ridreq
;
93 struct ifaliasreq addreq
;
95 struct in6_ifreq in6_ridreq
;
96 struct in6_aliasreq in6_addreq
=
102 { 0, 0, ND6_INFINITE_LIFETIME
, ND6_INFINITE_LIFETIME
} };
104 struct sockaddr_in netmask
;
118 static int ip6lifetime
;
123 int bond_details
= 0;
128 char addr_buf
[MAXHOSTNAMELEN
*2 + 1]; /*for getnameinfo()*/
131 void Perror
__P((const char *cmd
));
133 int ifconfig
__P((int argc
, char *const *argv
, const struct afswtch
*afp
));
134 void notealias
__P((const char *, int, int, const struct afswtch
*afp
));
135 void printb
__P((const char *s
, unsigned value
, const char *bits
));
136 void rt_xaddrs
__P((caddr_t
, caddr_t
, struct rt_addrinfo
*));
137 void status
__P((const struct afswtch
*afp
, int addrcount
,
138 struct sockaddr_dl
*sdl
, struct if_msghdr
*ifm
,
139 struct ifa_msghdr
*ifam
));
140 void tunnel_status
__P((int s
));
141 void usage
__P((void));
144 void in6_fillscopeid
__P((struct sockaddr_in6
*sin6
));
145 int prefix
__P((void *, int));
146 static char *sec2str
__P((time_t));
147 int explicit_prefix
= 0;
150 typedef void c_func
__P((const char *cmd
, int arg
, int s
, const struct afswtch
*afp
));
151 typedef void c_func2
__P((const char *arg
, const char *arg2
, int s
, const struct afswtch
*afp
));
152 c_func setifaddr
, setifbroadaddr
, setifdstaddr
, setifnetmask
;
156 c_func setifprefixlen
;
160 c_func2 setip6lifetime
;
163 c_func setifflags
, setifmetric
, setifmtu
, setiflladdr
;
164 c_func clone_destroy
;
167 void clone_create(void);
168 #define NEXTARG 0xffffff
169 #define NEXTARG2 0xfffffe
174 int c_parameter
; /* NEXTARG means next argv */
175 void (*c_func
) __P((const char *, int, int, const struct afswtch
*afp
));
176 void (*c_func2
) __P((const char *, const char *, int, const struct afswtch
*afp
));
178 { "up", IFF_UP
, setifflags
} ,
179 { "down", -IFF_UP
, setifflags
},
180 { "arp", -IFF_NOARP
, setifflags
},
181 { "-arp", IFF_NOARP
, setifflags
},
182 { "debug", IFF_DEBUG
, setifflags
},
183 { "-debug", -IFF_DEBUG
, setifflags
},
184 { "add", IFF_UP
, notealias
},
185 { "alias", IFF_UP
, notealias
},
186 { "-alias", -IFF_UP
, notealias
},
187 { "delete", -IFF_UP
, notealias
},
188 { "remove", -IFF_UP
, notealias
},
190 #define EN_SWABIPS 0x1000
191 { "swabips", EN_SWABIPS
, setifflags
},
192 { "-swabips", -EN_SWABIPS
, setifflags
},
194 { "netmask", NEXTARG
, setifnetmask
},
196 { "prefixlen", NEXTARG
, setifprefixlen
},
197 { "anycast", IN6_IFF_ANYCAST
, setip6flags
},
198 { "tentative", IN6_IFF_TENTATIVE
, setip6flags
},
199 { "-tentative", -IN6_IFF_TENTATIVE
, setip6flags
},
200 { "deprecated", IN6_IFF_DEPRECATED
, setip6flags
},
201 { "-deprecated", -IN6_IFF_DEPRECATED
, setip6flags
},
202 { "autoconf", IN6_IFF_AUTOCONF
, setip6flags
},
203 { "-autoconf", -IN6_IFF_AUTOCONF
, setip6flags
},
204 { "pltime", NEXTARG
, setip6pltime
},
205 { "vltime", NEXTARG
, setip6vltime
},
207 { "metric", NEXTARG
, setifmetric
},
208 { "broadcast", NEXTARG
, setifbroadaddr
},
209 { "ipdst", NEXTARG
, setifipdst
},
210 { "tunnel", NEXTARG2
, NULL
, settunnel
},
211 { "deletetunnel", 0, deletetunnel
},
212 { "link0", IFF_LINK0
, setifflags
},
213 { "-link0", -IFF_LINK0
, setifflags
},
214 { "link1", IFF_LINK1
, setifflags
},
215 { "-link1", -IFF_LINK1
, setifflags
},
216 { "link2", IFF_LINK2
, setifflags
},
217 { "-link2", -IFF_LINK2
, setifflags
},
219 { "media", NEXTARG
, setmedia
},
220 { "mediaopt", NEXTARG
, setmediaopt
},
221 { "-mediaopt", NEXTARG
, unsetmediaopt
},
224 { "vlan", NEXTARG
, setvlantag
},
225 { "vlandev", NEXTARG
, setvlandev
},
226 { "-vlandev", NEXTARG
, unsetvlandev
},
229 { "bonddev", NEXTARG
, setbonddev
},
230 { "-bonddev", NEXTARG
, unsetbonddev
},
231 { "bondmode", NEXTARG
, setbondmode
},
234 /* XXX `create' special-cased below */
235 {"create", 0, clone_create
},
236 {"plumb", 0, clone_create
},
238 {"destroy", 0, clone_destroy
},
239 {"unplumb", 0, clone_destroy
},
241 { "ssid", NEXTARG
, set80211ssid
},
242 { "nwid", NEXTARG
, set80211ssid
},
243 { "stationname", NEXTARG
, set80211stationname
},
244 { "station", NEXTARG
, set80211stationname
}, /* BSD/OS */
245 { "channel", NEXTARG
, set80211channel
},
246 { "authmode", NEXTARG
, set80211authmode
},
247 { "powersavemode", NEXTARG
, set80211powersavemode
},
248 { "powersave", 1, set80211powersave
},
249 { "-powersave", 0, set80211powersave
},
250 { "powersavesleep", NEXTARG
, set80211powersavesleep
},
251 { "wepmode", NEXTARG
, set80211wepmode
},
252 { "wep", 1, set80211wep
},
253 { "-wep", 0, set80211wep
},
254 { "weptxkey", NEXTARG
, set80211weptxkey
},
255 { "wepkey", NEXTARG
, set80211wepkey
},
256 { "nwkey", NEXTARG
, set80211nwkey
}, /* NetBSD */
257 { "-nwkey", 0, set80211wep
}, /* NetBSD */
259 { "normal", -IFF_LINK0
, setifflags
},
260 { "compress", IFF_LINK0
, setifflags
},
261 { "noicmp", IFF_LINK1
, setifflags
},
262 { "mtu", NEXTARG
, setifmtu
},
263 { "lladdr", NEXTARG
, setiflladdr
},
265 { 0, 0, setifdstaddr
},
269 * XNS support liberally adapted from code written at the University of
270 * Maryland principally by James O'Toole and Chris Torek.
272 typedef void af_status
__P((int, struct rt_addrinfo
*));
273 typedef void af_getaddr
__P((const char *, int));
274 typedef void af_getprefix
__P((const char *, int));
276 af_status in_status
, at_status
, ether_status
;
277 af_getaddr in_getaddr
, at_getaddr
, ether_getaddr
;
281 af_status in6_status
;
282 af_getaddr in6_getaddr
;
283 af_getprefix in6_getprefix
;
286 /* Known address families */
291 af_status
*af_status
;
292 af_getaddr
*af_getaddr
;
293 af_getprefix
*af_getprefix
;
299 #define C(x) ((caddr_t) &x)
300 { "inet", AF_INET
, in_status
, in_getaddr
, NULL
,
301 SIOCDIFADDR
, SIOCAIFADDR
, C(ridreq
), C(addreq
) },
303 { "inet6", AF_INET6
, in6_status
, in6_getaddr
, in6_getprefix
,
304 SIOCDIFADDR_IN6
, SIOCAIFADDR_IN6
,
305 C(in6_ridreq
), C(in6_addreq
) },
307 { "ether", AF_LINK
, ether_status
, ether_getaddr
, NULL
,
308 0, SIOCSIFLLADDR
, NULL
, C(ridreq
) },
309 #if 0 /* XXX conflicts with the media command */
311 { "media", AF_UNSPEC
, media_status
, NULL
, NULL
, }, /* XXX not real!! */
314 { "vlan", AF_UNSPEC
, vlan_status
, NULL
, NULL
, }, /* XXX not real!! */
317 { "bond", AF_UNSPEC
, bond_status
, NULL
, NULL
, }, /* XXX not real!! */
320 { "ieee80211", AF_UNSPEC
, ieee80211_status
, NULL
, NULL
, }, /* XXX not real!! */
327 * Expand the compacted form of addresses as returned via the
328 * configuration read via sysctl().
332 ((a) > 0 ? (1 + (((a) - 1) | (sizeof(uint32_t) - 1))) : sizeof(uint32_t))
333 #define ADVANCE(x, n) (x += ROUNDUP((n)->sa_len))
336 rt_xaddrs(cp
, cplim
, rtinfo
)
338 struct rt_addrinfo
*rtinfo
;
343 memset(rtinfo
->rti_info
, 0, sizeof(rtinfo
->rti_info
));
344 for (i
= 0; (i
< RTAX_MAX
) && (cp
< cplim
); i
++) {
345 if ((rtinfo
->rti_addrs
& (1 << i
)) == 0)
347 rtinfo
->rti_info
[i
] = sa
= (struct sockaddr
*)cp
;
357 fprintf(stderr
, "%s",
358 "usage: ifconfig interface address_family [address [dest_address]]\n"
360 " ifconfig interface create\n"
361 " ifconfig -a [-d] [-m] [-u] [address_family]\n"
362 " ifconfig -l [-d] [-u] [address_family]\n"
363 " ifconfig [-d] [-m] [-u]\n");
365 fprintf(stderr
, "%s",
366 "usage: ifconfig [-L] interface address_family [address [dest_address]]\n"
368 " ifconfig interface create\n"
369 " ifconfig -a [-L] [-d] [-m] [-u] [address_family]\n"
370 " ifconfig -l [-d] [-u] [address_family]\n"
371 " ifconfig [-L] [-d] [-m] [-u]\n");
382 int all
, namesonly
, downonly
, uponly
;
383 int foundit
= 0, need_nl
= 0;
384 const struct afswtch
*afp
= 0;
386 struct if_msghdr
*ifm
, *nextifm
;
387 struct ifa_msghdr
*ifam
;
388 struct sockaddr_dl
*sdl
;
389 char *buf
, *lim
, *next
;
395 /* Parse leading line options */
396 all
= downonly
= uponly
= namesonly
= 0;
397 while ((c
= getopt(argc
, argv
, "abdlmu"
403 case 'a': /* scan all interfaces */
406 case 'b': /* bond detailed output */
409 case 'd': /* restrict scan to "down" interfaces */
412 case 'l': /* scan interface names only */
415 case 'm': /* show media choices in status */
418 case 'u': /* restrict scan to "up" interfaces */
423 ip6lifetime
++; /* print IPv6 address lifetime */
434 /* -l cannot be used with -a or -m or -b */
435 if (namesonly
&& (all
|| supmedia
|| bond_details
))
439 if (uponly
&& downonly
)
442 /* no arguments is equivalent to '-a' */
443 if (!namesonly
&& argc
< 1)
446 /* -a and -l allow an address family arg to limit the output */
447 if (all
|| namesonly
) {
452 for (afp
= afs
; afp
->af_name
; afp
++)
453 if (strcmp(afp
->af_name
, *argv
) == 0) {
457 if (afp
->af_name
== NULL
)
459 /* leave with afp non-zero */
462 /* not listing, need an argument */
466 strncpy(name
, *argv
, sizeof(name
));
470 * NOTE: We must special-case the `create' command right
471 * here as we would otherwise fail when trying to find
474 if (argc
> 0 && (strcmp(argv
[0], "create") == 0 ||
475 strcmp(argv
[0], "plumb") == 0)) {
483 /* Check for address family */
485 for (afp
= afs
; afp
->af_name
; afp
++)
486 if (strcmp(afp
->af_name
, *argv
) == 0) {
490 if (afp
->af_name
== NULL
)
491 afp
= NULL
; /* not a family, NULL */
497 mib
[3] = 0; /* address family */
498 mib
[4] = NET_RT_IFLIST
;
501 /* if particular family specified, only ask about it */
505 if (sysctl(mib
, 6, NULL
, &needed
, NULL
, 0) < 0)
506 errx(1, "iflist-sysctl-estimate");
507 if ((buf
= malloc(needed
)) == NULL
)
509 if (sysctl(mib
, 6, buf
, &needed
, NULL
, 0) < 0)
510 errx(1, "actual retrieval of interface table");
516 ifm
= (struct if_msghdr
*)next
;
518 if (ifm
->ifm_type
== RTM_IFINFO
) {
519 sdl
= (struct sockaddr_dl
*)(ifm
+ 1);
520 flags
= ifm
->ifm_flags
;
522 fprintf(stderr
, "out of sync parsing NET_RT_IFLIST\n");
523 fprintf(stderr
, "expected %d, got %d\n", RTM_IFINFO
,
525 fprintf(stderr
, "msglen = %d\n", ifm
->ifm_msglen
);
526 fprintf(stderr
, "buf:%p, next:%p, lim:%p\n", buf
, next
,
531 next
+= ifm
->ifm_msglen
;
536 nextifm
= (struct if_msghdr
*)next
;
538 if (nextifm
->ifm_type
!= RTM_NEWADDR
)
542 ifam
= (struct ifa_msghdr
*)nextifm
;
545 next
+= nextifm
->ifm_msglen
;
548 if (all
|| namesonly
) {
550 if ((flags
& IFF_UP
) == 0)
551 continue; /* not up */
554 continue; /* not down */
555 strncpy(name
, sdl
->sdl_data
, sdl
->sdl_nlen
);
556 name
[sdl
->sdl_nlen
] = '\0';
559 afp
->af_status
!= ether_status
||
560 sdl
->sdl_type
== IFT_ETHER
) {
569 if (strlen(name
) != sdl
->sdl_nlen
)
570 continue; /* not same len */
571 if (strncmp(name
, sdl
->sdl_data
, sdl
->sdl_nlen
) != 0)
572 continue; /* not same name */
576 ifconfig(argc
, argv
, afp
);
578 status(afp
, addrcount
, sdl
, ifm
, ifam
);
580 if (all
== 0 && namesonly
== 0) {
581 foundit
++; /* flag it as 'done' */
587 if (namesonly
&& need_nl
> 0)
590 if (all
== 0 && namesonly
== 0 && foundit
== 0)
591 errx(1, "interface %s does not exist", name
);
599 ifconfig(argc
, argv
, afp
)
602 const struct afswtch
*afp
;
608 ifr
.ifr_addr
.sa_family
= afp
->af_af
== AF_LINK
? AF_INET
: afp
->af_af
;
609 strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
611 if ((s
= socket(ifr
.ifr_addr
.sa_family
, SOCK_DGRAM
, 0)) < 0)
615 register const struct cmd
*p
;
617 for (p
= cmds
; p
->c_name
; p
++)
618 if (strcmp(*argv
, p
->c_name
) == 0)
620 if (p
->c_name
== 0 && setaddr
)
621 p
++; /* got src, do dst */
622 if (p
->c_func
|| p
->c_func2
) {
623 if (p
->c_parameter
== NEXTARG
) {
625 errx(1, "'%s' requires argument",
627 (*p
->c_func
)(argv
[1], 0, s
, afp
);
629 } else if (p
->c_parameter
== NEXTARG2
) {
631 errx(1, "'%s' requires 2 arguments",
633 (*p
->c_func2
)(argv
[1], argv
[2], s
, afp
);
634 argc
-= 2, argv
+= 2;
636 (*p
->c_func
)(*argv
, p
->c_parameter
, s
, afp
);
641 if (ifr
.ifr_addr
.sa_family
== AF_INET6
&& explicit_prefix
== 0) {
642 /* Aggregatable address architecture defines all prefixes
643 are 64. So, it is convenient to set prefixlen to 64 if
644 it is not specified. */
645 setifprefixlen("64", 0, s
, afp
);
646 /* in6_getprefix("64", MASK) if MASK is available here... */
650 if (afp
->af_ridreq
== NULL
|| afp
->af_difaddr
== 0) {
651 warnx("interface %s cannot change %s addresses!",
658 strncpy(afp
->af_ridreq
, name
, sizeof ifr
.ifr_name
);
659 if ((ret
= ioctl(s
, afp
->af_difaddr
, afp
->af_ridreq
)) < 0) {
660 if (errno
== EADDRNOTAVAIL
&& (doalias
>= 0)) {
661 /* means no previous address for interface */
663 Perror("ioctl (SIOCDIFADDR)");
667 if (afp
->af_addreq
== NULL
|| afp
->af_aifaddr
== 0) {
668 warnx("interface %s cannot change %s addresses!",
673 if (newaddr
&& (setaddr
|| setmask
)) {
674 strncpy(afp
->af_addreq
, name
, sizeof ifr
.ifr_name
);
675 if (ioctl(s
, afp
->af_aifaddr
, afp
->af_addreq
) < 0)
676 Perror("ioctl (SIOCAIFADDR)");
688 setifaddr(addr
, param
, s
, afp
)
692 const struct afswtch
*afp
;
694 if (*afp
->af_getaddr
== NULL
)
697 * Delay the ioctl to set the interface addr until flags are all set.
698 * The address interpretation may depend on the flags,
699 * and the flags may change when the address is set.
702 if (doalias
== 0 && afp
->af_af
!= AF_LINK
)
704 (*afp
->af_getaddr
)(addr
, (doalias
>= 0 ? ADDR
: RIDADDR
));
708 settunnel(src
, dst
, s
, afp
)
709 const char *src
, *dst
;
711 const struct afswtch
*afp
;
713 struct addrinfo hints
, *srcres
, *dstres
;
714 struct ifaliasreq addreq
;
717 struct in6_aliasreq in6_addreq
;
720 memset(&hints
, 0, sizeof(hints
));
721 hints
.ai_family
= afp
->af_af
;
723 if ((ecode
= getaddrinfo(src
, NULL
, NULL
, &srcres
)) != 0)
724 errx(1, "error in parsing address string: %s",
725 gai_strerror(ecode
));
727 if ((ecode
= getaddrinfo(dst
, NULL
, NULL
, &dstres
)) != 0)
728 errx(1, "error in parsing address string: %s",
729 gai_strerror(ecode
));
731 if (srcres
->ai_addr
->sa_family
!= dstres
->ai_addr
->sa_family
)
733 "source and destination address families do not match");
735 switch (srcres
->ai_addr
->sa_family
) {
737 memset(&addreq
, 0, sizeof(addreq
));
738 strncpy(addreq
.ifra_name
, name
, IFNAMSIZ
);
739 memcpy(&addreq
.ifra_addr
, srcres
->ai_addr
,
740 srcres
->ai_addr
->sa_len
);
741 memcpy(&addreq
.ifra_dstaddr
, dstres
->ai_addr
,
742 dstres
->ai_addr
->sa_len
);
744 if (ioctl(s
, SIOCSIFPHYADDR
, &addreq
) < 0)
745 warn("SIOCSIFPHYADDR");
750 memset(&in6_addreq
, 0, sizeof(in6_addreq
));
751 strncpy(in6_addreq
.ifra_name
, name
, IFNAMSIZ
);
752 memcpy(&in6_addreq
.ifra_addr
, srcres
->ai_addr
,
753 srcres
->ai_addr
->sa_len
);
754 memcpy(&in6_addreq
.ifra_dstaddr
, dstres
->ai_addr
,
755 dstres
->ai_addr
->sa_len
);
757 if (ioctl(s
, SIOCSIFPHYADDR_IN6
, &in6_addreq
) < 0)
758 warn("SIOCSIFPHYADDR_IN6");
763 warn("address family not supported");
766 freeaddrinfo(srcres
);
767 freeaddrinfo(dstres
);
772 deletetunnel(vname
, param
, s
, afp
)
776 const struct afswtch
*afp
;
779 if (ioctl(s
, SIOCDIFPHYADDR
, &ifr
) < 0)
780 err(1, "SIOCDIFPHYADDR");
784 setifnetmask(addr
, dummy
, s
, afp
)
788 const struct afswtch
*afp
;
790 if (*afp
->af_getaddr
== NULL
)
793 (*afp
->af_getaddr
)(addr
, NMASK
);
798 setifprefixlen(addr
, dummy
, s
, afp
)
802 const struct afswtch
*afp
;
804 if (*afp
->af_getprefix
)
805 (*afp
->af_getprefix
)(addr
, NMASK
);
810 setip6flags(dummyaddr
, flag
, dummysoc
, afp
)
811 const char *dummyaddr
;
814 const struct afswtch
*afp
;
816 if (afp
->af_af
!= AF_INET6
)
817 err(1, "address flags can be set only for inet6 addresses");
820 in6_addreq
.ifra_flags
&= ~(-flag
);
822 in6_addreq
.ifra_flags
|= flag
;
826 setip6pltime(seconds
, dummy
, s
, afp
)
830 const struct afswtch
*afp
;
832 setip6lifetime("pltime", seconds
, s
, afp
);
836 setip6vltime(seconds
, dummy
, s
, afp
)
840 const struct afswtch
*afp
;
842 setip6lifetime("vltime", seconds
, s
, afp
);
846 setip6lifetime(cmd
, val
, s
, afp
)
850 const struct afswtch
*afp
;
856 newval
= (time_t)strtoul(val
, &ep
, 0);
858 errx(1, "invalid %s", cmd
);
859 if (afp
->af_af
!= AF_INET6
)
860 errx(1, "%s not allowed for the AF", cmd
);
861 if (strcmp(cmd
, "vltime") == 0) {
862 in6_addreq
.ifra_lifetime
.ia6t_expire
= t
+ newval
;
863 in6_addreq
.ifra_lifetime
.ia6t_vltime
= newval
;
864 } else if (strcmp(cmd
, "pltime") == 0) {
865 in6_addreq
.ifra_lifetime
.ia6t_preferred
= t
+ newval
;
866 in6_addreq
.ifra_lifetime
.ia6t_pltime
= newval
;
872 setifbroadaddr(addr
, dummy
, s
, afp
)
876 const struct afswtch
*afp
;
879 (*afp
->af_getaddr
)(addr
, DSTADDR
);
883 setifipdst(addr
, dummy
, s
, afp
)
887 const struct afswtch
*afp
;
889 in_getaddr(addr
, DSTADDR
);
894 #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
897 notealias(addr
, param
, s
, afp
)
901 const struct afswtch
*afp
;
903 if (setaddr
&& doalias
== 0 && param
< 0)
904 bcopy((caddr_t
)rqtosa(af_addreq
),
905 (caddr_t
)rqtosa(af_ridreq
),
906 rqtosa(af_addreq
)->sa_len
);
917 setifdstaddr(addr
, param
, s
, afp
)
921 const struct afswtch
*afp
;
923 if (*afp
->af_getaddr
== NULL
)
925 (*afp
->af_getaddr
)(addr
, DSTADDR
);
929 * Note: doing an SIOCIGIFFLAGS scribbles on the union portion
930 * of the ifreq structure, which may confuse other parts of ifconfig.
931 * Make a private copy so we can avoid that.
934 setifflags(vname
, value
, s
, afp
)
938 const struct afswtch
*afp
;
942 bcopy((char *)&ifr
, (char *)&my_ifr
, sizeof(struct ifreq
));
944 if (ioctl(s
, SIOCGIFFLAGS
, (caddr_t
)&my_ifr
) < 0) {
945 Perror("ioctl (SIOCGIFFLAGS)");
948 strncpy(my_ifr
.ifr_name
, name
, sizeof (my_ifr
.ifr_name
));
949 flags
= my_ifr
.ifr_flags
;
956 my_ifr
.ifr_flags
= flags
;
957 if (ioctl(s
, SIOCSIFFLAGS
, (caddr_t
)&my_ifr
) < 0)
962 setifmetric(val
, dummy
, s
, afp
)
966 const struct afswtch
*afp
;
968 strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
969 ifr
.ifr_metric
= atoi(val
);
970 if (ioctl(s
, SIOCSIFMETRIC
, (caddr_t
)&ifr
) < 0)
971 warn("ioctl (set metric)");
975 setifmtu(val
, dummy
, s
, afp
)
979 const struct afswtch
*afp
;
981 strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
982 ifr
.ifr_mtu
= atoi(val
);
983 if (ioctl(s
, SIOCSIFMTU
, (caddr_t
)&ifr
) < 0)
984 warn("ioctl (set mtu)");
988 setiflladdr(val
, dummy
, s
, afp
)
992 const struct afswtch
*afp
;
994 struct ether_addr
*ea
;
996 ea
= ether_aton(val
);
998 warn("malformed link-level address");
1001 strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1002 ifr
.ifr_addr
.sa_len
= ETHER_ADDR_LEN
;
1003 ifr
.ifr_addr
.sa_family
= AF_LINK
;
1004 bcopy(ea
, ifr
.ifr_addr
.sa_data
, ETHER_ADDR_LEN
);
1005 if (ioctl(s
, SIOCSIFLLADDR
, (caddr_t
)&ifr
) < 0)
1006 warn("ioctl (set lladdr)");
1012 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \
1013 "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \
1017 * Print the status of the interface. If an address family was
1018 * specified, show it and it only; otherwise, show them all.
1021 status(afp
, addrcount
, sdl
, ifm
, ifam
)
1022 const struct afswtch
*afp
;
1024 struct sockaddr_dl
*sdl
;
1025 struct if_msghdr
*ifm
;
1026 struct ifa_msghdr
*ifam
;
1028 const struct afswtch
*p
= NULL
;
1029 struct rt_addrinfo info
;
1039 ifr
.ifr_addr
.sa_family
= afp
->af_af
== AF_LINK
? AF_INET
: afp
->af_af
;
1040 strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
1042 if ((s
= socket(ifr
.ifr_addr
.sa_family
, SOCK_DGRAM
, 0)) < 0)
1046 * XXX is it we are doing a SIOCGIFMETRIC etc for one family.
1047 * is it possible that the metric and mtu can be different for
1048 * each family? If so, we have a format problem, because the
1049 * metric and mtu is printed on the global the flags line.
1051 if (ioctl(s
, SIOCGIFMETRIC
, (caddr_t
)&ifr
) < 0)
1052 warn("ioctl (SIOCGIFMETRIC)");
1054 metric
= ifr
.ifr_metric
;
1056 if (ioctl(s
, SIOCGIFMTU
, (caddr_t
)&ifr
) < 0)
1057 warn("ioctl (SIOCGIFMTU)");
1061 printf("%s: ", name
);
1062 printb("flags", flags
, IFFBITS
);
1064 printf(" metric %d", metric
);
1066 printf(" mtu %d", mtu
);
1071 while (addrcount
> 0) {
1073 info
.rti_addrs
= ifam
->ifam_addrs
;
1075 /* Expand the compacted addresses */
1076 rt_xaddrs((char *)(ifam
+ 1), ifam
->ifam_msglen
+ (char *)ifam
,
1080 if (afp
->af_af
== info
.rti_info
[RTAX_IFA
]->sa_family
) {
1082 (*p
->af_status
)(s
, &info
);
1084 } else for (p
= afs
; p
->af_name
; p
++) {
1085 if (p
->af_af
== info
.rti_info
[RTAX_IFA
]->sa_family
)
1086 (*p
->af_status
)(s
, &info
);
1089 ifam
= (struct ifa_msghdr
*)((char *)ifam
+ ifam
->ifam_msglen
);
1091 if (allfamilies
|| afp
->af_status
== ether_status
)
1092 ether_status(s
, (struct rt_addrinfo
*)sdl
);
1094 if (allfamilies
|| afp
->af_status
== media_status
)
1095 media_status(s
, NULL
);
1098 if (allfamilies
|| afp
->af_status
== vlan_status
)
1099 vlan_status(s
, NULL
);
1102 if (allfamilies
|| afp
->af_status
== bond_status
)
1103 bond_status(s
, NULL
);
1105 #ifdef USE_IEEE80211
1106 if (allfamilies
|| afp
->af_status
== ieee80211_status
)
1107 ieee80211_status(s
, NULL
);
1109 strncpy(ifs
.ifs_name
, name
, sizeof ifs
.ifs_name
);
1110 if (ioctl(s
, SIOCGIFSTATUS
, &ifs
) == 0)
1111 printf("%s", ifs
.ascii
);
1113 if (!allfamilies
&& !p
&& afp
->af_status
!= media_status
&&
1114 afp
->af_status
!= ether_status
1116 && afp
->af_status
!= vlan_status
1119 warnx("%s has no %s interface address!", name
, afp
->af_name
);
1129 char psrcaddr
[NI_MAXHOST
];
1130 char pdstaddr
[NI_MAXHOST
];
1131 uint32_t srccmd
, dstcmd
;
1133 const char *ver
= "";
1134 #ifdef NI_WITHSCOPEID
1135 const int niflag
= NI_NUMERICHOST
| NI_WITHSCOPEID
;
1137 const int niflag
= NI_NUMERICHOST
;
1140 struct in6_ifreq in6_ifr
;
1144 psrcaddr
[0] = pdstaddr
[0] = '\0';
1147 memset(&in6_ifr
, 0, sizeof(in6_ifr
));
1148 strncpy(in6_ifr
.ifr_name
, name
, IFNAMSIZ
);
1149 s6
= socket(AF_INET6
, SOCK_DGRAM
, 0);
1151 srccmd
= SIOCGIFPSRCADDR
;
1152 dstcmd
= SIOCGIFPDSTADDR
;
1156 srccmd
= SIOCGIFPSRCADDR_IN6
;
1157 dstcmd
= SIOCGIFPDSTADDR_IN6
;
1158 ifrp
= (struct ifreq
*)&in6_ifr
;
1161 srccmd
= SIOCGIFPSRCADDR
;
1162 dstcmd
= SIOCGIFPDSTADDR
;
1166 if (ioctl(s
, srccmd
, (caddr_t
)ifrp
) < 0)
1169 if (ifrp
->ifr_addr
.sa_family
== AF_INET6
)
1170 in6_fillscopeid((struct sockaddr_in6
*)&ifrp
->ifr_addr
);
1172 getnameinfo(&ifrp
->ifr_addr
, ifrp
->ifr_addr
.sa_len
,
1173 psrcaddr
, sizeof(psrcaddr
), 0, 0, niflag
);
1175 if (ifrp
->ifr_addr
.sa_family
== AF_INET6
)
1179 if (ioctl(s
, dstcmd
, (caddr_t
)ifrp
) < 0)
1182 if (ifrp
->ifr_addr
.sa_family
== AF_INET6
)
1183 in6_fillscopeid((struct sockaddr_in6
*)&ifrp
->ifr_addr
);
1185 getnameinfo(&ifrp
->ifr_addr
, ifrp
->ifr_addr
.sa_len
,
1186 pdstaddr
, sizeof(pdstaddr
), 0, 0, niflag
);
1188 printf("\ttunnel inet%s %s --> %s\n", ver
,
1189 psrcaddr
, pdstaddr
);
1195 struct rt_addrinfo
* info
;
1197 struct sockaddr_in
*sin
, null_sin
;
1199 memset(&null_sin
, 0, sizeof(null_sin
));
1201 sin
= (struct sockaddr_in
*)info
->rti_info
[RTAX_IFA
];
1202 printf("\tinet %s ", inet_ntoa(sin
->sin_addr
));
1204 if (flags
& IFF_POINTOPOINT
) {
1205 /* note RTAX_BRD overlap with IFF_BROADCAST */
1206 sin
= (struct sockaddr_in
*)info
->rti_info
[RTAX_BRD
];
1209 printf("--> %s ", inet_ntoa(sin
->sin_addr
));
1212 sin
= (struct sockaddr_in
*)info
->rti_info
[RTAX_NETMASK
];
1215 printf("netmask 0x%0x ", (uint32_t)ntohl(sin
->sin_addr
.s_addr
));
1217 if (flags
& IFF_BROADCAST
) {
1218 /* note RTAX_BRD overlap with IFF_POINTOPOINT */
1219 sin
= (struct sockaddr_in
*)info
->rti_info
[RTAX_BRD
];
1220 if (sin
&& sin
->sin_addr
.s_addr
!= 0)
1221 printf("broadcast %s", inet_ntoa(sin
->sin_addr
));
1228 in6_fillscopeid(sin6
)
1229 struct sockaddr_in6
*sin6
;
1231 #if defined(__KAME__) && defined(KAME_SCOPEID)
1232 if (IN6_IS_ADDR_LINKLOCAL(&sin6
->sin6_addr
)) {
1233 sin6
->sin6_scope_id
=
1234 ntohs(*(u_int16_t
*)&sin6
->sin6_addr
.s6_addr
[2]);
1235 sin6
->sin6_addr
.s6_addr
[2] = sin6
->sin6_addr
.s6_addr
[3] = 0;
1243 struct rt_addrinfo
* info
;
1245 struct sockaddr_in6
*sin
, null_sin
;
1246 struct in6_ifreq ifr6
;
1249 struct in6_addrlifetime lifetime
;
1250 time_t t
= time(NULL
);
1254 memset(&null_sin
, 0, sizeof(null_sin
));
1256 sin
= (struct sockaddr_in6
*)info
->rti_info
[RTAX_IFA
];
1257 strncpy(ifr6
.ifr_name
, ifr
.ifr_name
, sizeof(ifr
.ifr_name
));
1258 if ((s6
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) {
1259 perror("ifconfig: socket");
1262 ifr6
.ifr_addr
= *sin
;
1263 if (ioctl(s6
, SIOCGIFAFLAG_IN6
, &ifr6
) < 0) {
1264 perror("ifconfig: ioctl(SIOCGIFAFLAG_IN6)");
1268 flags6
= ifr6
.ifr_ifru
.ifru_flags6
;
1269 memset(&lifetime
, 0, sizeof(lifetime
));
1270 ifr6
.ifr_addr
= *sin
;
1271 if (ioctl(s6
, SIOCGIFALIFETIME_IN6
, &ifr6
) < 0) {
1272 perror("ifconfig: ioctl(SIOCGIFALIFETIME_IN6)");
1276 lifetime
= ifr6
.ifr_ifru
.ifru_lifetime
;
1279 /* XXX: embedded link local addr check */
1280 if (IN6_IS_ADDR_LINKLOCAL(&sin
->sin6_addr
) &&
1281 *(u_short
*)&sin
->sin6_addr
.s6_addr
[2] != 0) {
1284 index
= *(u_short
*)&sin
->sin6_addr
.s6_addr
[2];
1285 *(u_short
*)&sin
->sin6_addr
.s6_addr
[2] = 0;
1286 if (sin
->sin6_scope_id
== 0)
1287 sin
->sin6_scope_id
= ntohs(index
);
1289 scopeid
= sin
->sin6_scope_id
;
1291 error
= getnameinfo((struct sockaddr
*)sin
, sin
->sin6_len
, addr_buf
,
1292 sizeof(addr_buf
), NULL
, 0,
1293 NI_NUMERICHOST
|NI_WITHSCOPEID
);
1295 inet_ntop(AF_INET6
, &sin
->sin6_addr
, addr_buf
,
1297 printf("\tinet6 %s ", addr_buf
);
1299 if (flags
& IFF_POINTOPOINT
) {
1300 /* note RTAX_BRD overlap with IFF_BROADCAST */
1301 sin
= (struct sockaddr_in6
*)info
->rti_info
[RTAX_BRD
];
1303 * some of the interfaces do not have valid destination
1306 if (sin
&& sin
->sin6_family
== AF_INET6
) {
1309 /* XXX: embedded link local addr check */
1310 if (IN6_IS_ADDR_LINKLOCAL(&sin
->sin6_addr
) &&
1311 *(u_short
*)&sin
->sin6_addr
.s6_addr
[2] != 0) {
1314 index
= *(u_short
*)&sin
->sin6_addr
.s6_addr
[2];
1315 *(u_short
*)&sin
->sin6_addr
.s6_addr
[2] = 0;
1316 if (sin
->sin6_scope_id
== 0)
1317 sin
->sin6_scope_id
= ntohs(index
);
1320 error
= getnameinfo((struct sockaddr
*)sin
,
1321 sin
->sin6_len
, addr_buf
,
1322 sizeof(addr_buf
), NULL
, 0,
1323 NI_NUMERICHOST
|NI_WITHSCOPEID
);
1325 inet_ntop(AF_INET6
, &sin
->sin6_addr
, addr_buf
,
1327 printf("--> %s ", addr_buf
);
1331 sin
= (struct sockaddr_in6
*)info
->rti_info
[RTAX_NETMASK
];
1334 printf("prefixlen %d ", prefix(&sin
->sin6_addr
,
1335 sizeof(struct in6_addr
)));
1337 if ((flags6
& IN6_IFF_ANYCAST
) != 0)
1339 if ((flags6
& IN6_IFF_TENTATIVE
) != 0)
1340 printf("tentative ");
1341 if ((flags6
& IN6_IFF_DUPLICATED
) != 0)
1342 printf("duplicated ");
1343 if ((flags6
& IN6_IFF_DETACHED
) != 0)
1344 printf("detached ");
1345 if ((flags6
& IN6_IFF_DEPRECATED
) != 0)
1346 printf("deprecated ");
1347 if ((flags6
& IN6_IFF_AUTOCONF
) != 0)
1348 printf("autoconf ");
1349 if ((flags6
& IN6_IFF_TEMPORARY
) != 0)
1350 printf("temporary ");
1353 printf("scopeid 0x%x ", scopeid
);
1355 if (ip6lifetime
&& (lifetime
.ia6t_preferred
|| lifetime
.ia6t_expire
)) {
1357 if (lifetime
.ia6t_preferred
) {
1358 printf("%s ", lifetime
.ia6t_preferred
< t
1359 ? "0" : sec2str(lifetime
.ia6t_preferred
- t
));
1364 if (lifetime
.ia6t_expire
) {
1365 printf("%s ", lifetime
.ia6t_expire
< t
1366 ? "0" : sec2str(lifetime
.ia6t_expire
- t
));
1376 ether_status(s
, info
)
1378 struct rt_addrinfo
*info
;
1382 struct sockaddr_dl
*sdl
= (struct sockaddr_dl
*)info
;
1384 cp
= (char *)LLADDR(sdl
);
1385 if ((n
= sdl
->sdl_alen
) > 0) {
1386 if (sdl
->sdl_type
== IFT_ETHER
)
1387 printf ("\tether ");
1389 printf ("\tlladdr ");
1391 printf("%02x%c",*cp
++ & 0xff, n
>0? ':' : ' ');
1403 errx(1, "%s: no such interface", cmd
);
1407 errx(1, "%s: permission denied", cmd
);
1415 #define SIN(x) ((struct sockaddr_in *) &(x))
1416 struct sockaddr_in
*sintab
[] = {
1417 SIN(ridreq
.ifr_addr
), SIN(addreq
.ifra_addr
),
1418 SIN(addreq
.ifra_mask
), SIN(addreq
.ifra_broadaddr
)};
1421 in_getaddr(s
, which
)
1425 register struct sockaddr_in
*sin
= sintab
[which
];
1429 sin
->sin_len
= sizeof(*sin
);
1431 sin
->sin_family
= AF_INET
;
1433 if (which
== ADDR
) {
1436 if((p
= strrchr(s
, '/')) != NULL
) {
1437 /* address is `name/masklen' */
1440 struct sockaddr_in
*min
= sintab
[NMASK
];
1442 ret
= sscanf(p
+1, "%u", &masklen
);
1443 if(ret
!= 1 || (masklen
< 0 || masklen
> 32)) {
1445 errx(1, "%s: bad value", s
);
1447 min
->sin_len
= sizeof(*min
);
1448 min
->sin_addr
.s_addr
= htonl(~((1LL << (32 - masklen
)) - 1) &
1453 if (inet_aton(s
, &sin
->sin_addr
))
1455 if ((hp
= gethostbyname(s
)) != 0)
1456 bcopy(hp
->h_addr
, (char *)&sin
->sin_addr
,
1457 MIN(hp
->h_length
, sizeof(sin
->sin_addr
)));
1458 else if ((np
= getnetbyname(s
)) != 0)
1459 sin
->sin_addr
= inet_makeaddr(np
->n_net
, INADDR_ANY
);
1461 errx(1, "%s: bad value", s
);
1465 #define SIN6(x) ((struct sockaddr_in6 *) &(x))
1466 struct sockaddr_in6
*sin6tab
[] = {
1467 SIN6(in6_ridreq
.ifr_addr
), SIN6(in6_addreq
.ifra_addr
),
1468 SIN6(in6_addreq
.ifra_prefixmask
), SIN6(in6_addreq
.ifra_dstaddr
)};
1471 in6_getaddr(s
, which
)
1475 register struct sockaddr_in6
*sin
= sin6tab
[which
];
1476 struct addrinfo hints
, *res
;
1481 sin
->sin6_len
= sizeof(*sin
);
1483 sin
->sin6_family
= AF_INET6
;
1485 if (which
== ADDR
) {
1487 if((p
= strrchr(s
, '/')) != NULL
) {
1489 in6_getprefix(p
+ 1, NMASK
);
1490 explicit_prefix
= 1;
1494 if (sin
->sin6_family
== AF_INET6
) {
1495 bzero(&hints
, sizeof(struct addrinfo
));
1496 hints
.ai_family
= AF_INET6
;
1497 error
= getaddrinfo(s
, NULL
, &hints
, &res
);
1500 if (inet_pton(AF_INET6
, s
, &sin
->sin6_addr
) != 1)
1501 errx(1, "%s: bad value", s
);
1503 bcopy(res
->ai_addr
, sin
, res
->ai_addrlen
);
1507 in6_getprefix(plen
, which
)
1511 register struct sockaddr_in6
*sin
= sin6tab
[which
];
1512 register u_char
*cp
;
1513 int len
= atoi(plen
);
1515 if ((len
< 0) || (len
> 128))
1516 errx(1, "%s: bad value", plen
);
1517 sin
->sin6_len
= sizeof(*sin
);
1519 sin
->sin6_family
= AF_INET6
;
1520 if ((len
== 0) || (len
== 128)) {
1521 memset(&sin
->sin6_addr
, 0xff, sizeof(struct in6_addr
));
1524 memset((void *)&sin
->sin6_addr
, 0x00, sizeof(sin
->sin6_addr
));
1525 for (cp
= (u_char
*)&sin
->sin6_addr
; len
> 7; len
-= 8)
1527 *cp
= 0xff << (8 - len
);
1532 * Print a value a la the %b format of the kernel's printf
1537 register unsigned v
;
1538 register const char *bits
;
1540 register int i
, any
= 0;
1543 if (bits
&& *bits
== 8)
1544 printf("%s=%o", s
, v
);
1546 printf("%s=%x", s
, v
);
1550 while ((i
= *bits
++) != '\0') {
1551 if (v
& (1 << (i
-1))) {
1555 for (; (c
= *bits
) > 32; bits
++)
1558 for (; *bits
> 32; bits
++)
1566 ether_getaddr(addr
, which
)
1570 struct ether_addr
*ea
;
1571 struct sockaddr
*sea
= &ridreq
.ifr_addr
;
1573 ea
= ether_aton(addr
);
1575 errx(1, "malformed ether address");
1577 errx(1, "Ethernet does not use netmasks");
1578 sea
->sa_family
= AF_LINK
;
1579 sea
->sa_len
= ETHER_ADDR_LEN
;
1580 bcopy(ea
, sea
->sa_data
, ETHER_ADDR_LEN
);
1589 register u_char
*name
= (u_char
*)val
;
1590 register int byte
, bit
, plen
= 0;
1592 for (byte
= 0; byte
< size
; byte
++, plen
+= 8)
1593 if (name
[byte
] != 0xff)
1597 for (bit
= 7; bit
!= 0; bit
--, plen
++)
1598 if (!(name
[byte
] & (1 << bit
)))
1600 for (; bit
!= 0; bit
--)
1601 if (name
[byte
] & (1 << bit
))
1604 for (; byte
< size
; byte
++)
1614 static char result
[256];
1615 int days
, hours
, mins
, secs
;
1620 days
= total
/ 3600 / 24;
1621 hours
= (total
/ 3600) % 24;
1622 mins
= (total
/ 60) % 60;
1627 p
+= sprintf(p
, "%dd", days
);
1629 if (!first
|| hours
) {
1631 p
+= sprintf(p
, "%dh", hours
);
1633 if (!first
|| mins
) {
1635 p
+= sprintf(p
, "%dm", mins
);
1637 sprintf(p
, "%ds", secs
);
1639 sprintf(result
, "%lu", (unsigned long)total
);
1650 s
= socket(AF_INET
, SOCK_DGRAM
, 0);
1654 memset(&ifr
, 0, sizeof(ifr
));
1655 (void) strlcpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1656 if (ioctl(s
, SIOCIFCREATE
, &ifr
) < 0)
1657 err(1, "SIOCIFCREATE");
1659 if (strcmp(name
, ifr
.ifr_name
) != 0) {
1660 printf("%s\n", ifr
.ifr_name
);
1661 strlcpy(name
, ifr
.ifr_name
, sizeof(name
));
1668 clone_destroy(const char *val
, int d
, int s
, const struct afswtch
*rafp
)
1671 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1672 if (ioctl(s
, SIOCIFDESTROY
, &ifr
) < 0)
1673 err(1, "SIOCIFDESTROY");