2 * Copyright (C) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
3 * Helsinki University of Technology, Finland.
5 * Copyright (C) 2005 Neil Cafferkey
6 * Copyright (c) 2005 Pavel Fedin
7 * Copyright (c) 2006-2019 The AROS Dev Team
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
26 * Copyright (c) 1983, 1993
27 * The Regents of the University of California. All rights reserved.
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer.
34 * 2. Redistributions in binary form must reproduce the above copyright
35 * notice, this list of conditions and the following disclaimer in the
36 * documentation and/or other materials provided with the distribution.
37 * 3. All advertising materials mentioning features or use of this software
38 * must display the following acknowledgement:
39 * This product includes software developed by the University of
40 * California, Berkeley and its contributors.
41 * 4. Neither the name of the University nor the names of its contributors
42 * may be used to endorse or promote products derived from this software
43 * without specific prior written permission.
45 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 #include <proto/exec.h>
64 #include <sys/cdefs.h>
65 #include <sys/param.h>
66 #include <sys/socket.h>
67 #include <sys/sockio.h>
70 #include <net/if_dl.h>
71 #ifdef ENABLE_MEDIA_IOCTL
72 #include <net/if_media.h>
74 #include <netinet/in.h>
75 #include <arpa/inet.h>
76 #ifdef ENABLE_APPLETALK
77 #include <netatalk/at.h>
82 #include <netns/ns_if.h>
88 #include <netiso/iso.h>
89 #include <netiso/iso_var.h>
91 #if !defined(__AROS__)
92 #include <sys/protosw.h>
96 #if !defined(__AROS__)
102 #define inet_makeaddr(a,b) Inet_MakeAddr(a,b)
109 #include <proto/miami.h>
110 #include <proto/socket.h>
112 #if defined(__AROS__)
113 struct Library
*SocketBase
;
114 struct Library
*MiamiBase
;
117 #define SOCKET_VERSION 3
118 const TEXT version
[] = "$VER: ifconfig 5.0 (04.12.2005)";
119 const TEXT socket_name
[] = "bsdsocket.library";
121 struct ifreq ifr
, ridreq
;
122 struct ifaliasreq addreq
__attribute__((aligned(4)));
124 struct iso_aliasreq iso_addreq
;
126 struct sockaddr_in netmask
;
127 #ifdef ENABLE_APPLETALK
128 struct netrange at_nr
; /* AppleTalk net range */
131 int flags
, metric
, mtu
, setaddr
, setipdst
, doalias
;
136 int dflag
, mflag
, lflag
, uflag
;
139 void notealias
__P((char *, int));
140 void notrailers
__P((char *, int));
141 void setifaddr
__P((char *, int));
142 void setifdstaddr
__P((char *, int));
143 void setifflags
__P((char *, int));
144 void setifbroadaddr
__P((char *, int));
145 void setifipdst
__P((char *, int));
146 void setifmetric
__P((char *, int));
147 void setifmtu
__P((char *, int));
148 void setifnetmask
__P((char *, int));
149 void setnsellength
__P((char *, int));
150 void setsnpaoffset
__P((char *, int));
151 void setatrange
__P((char *, int));
152 void setatphase
__P((char *, int));
153 #ifdef ENABLE_APPLETALK
154 void checkatrange
__P ((struct sockaddr_at
*));
156 void setmedia
__P((char *, int));
157 void setmediaopt
__P((char *, int));
158 void unsetmediaopt
__P((char *, int));
160 void fixnsel
__P((struct sockaddr_iso
*));
162 int main
__P((int, char *[]));
164 #define NEXTARG 0xffffff
168 int c_parameter
; /* NEXTARG means next argv */
169 void (*c_func
) __P((char *, int));
171 { "up", IFF_UP
, setifflags
} ,
172 { "down", -IFF_UP
, setifflags
},
173 { "trailers", -1, notrailers
},
174 { "-trailers", 1, notrailers
},
175 { "arp", -IFF_NOARP
, setifflags
},
176 { "-arp", IFF_NOARP
, setifflags
},
177 { "debug", IFF_DEBUG
, setifflags
},
178 { "-debug", -IFF_DEBUG
, setifflags
},
179 { "alias", IFF_UP
, notealias
},
180 { "-alias", -IFF_UP
, notealias
},
181 { "delete", -IFF_UP
, notealias
},
183 #define EN_SWABIPS 0x1000
184 { "swabips", EN_SWABIPS
, setifflags
},
185 { "-swabips", -EN_SWABIPS
, setifflags
},
187 { "netmask", NEXTARG
, setifnetmask
},
188 { "metric", NEXTARG
, setifmetric
},
189 { "mtu", NEXTARG
, setifmtu
},
190 { "broadcast", NEXTARG
, setifbroadaddr
},
191 { "ipdst", NEXTARG
, setifipdst
},
193 { "range", NEXTARG
, setatrange
},
194 { "phase", NEXTARG
, setatphase
},
195 { "snpaoffset", NEXTARG
, setsnpaoffset
},
196 { "nsellength", NEXTARG
, setnsellength
},
197 #endif /* INET_ONLY */
198 { "link0", IFF_LINK0
, setifflags
} ,
199 { "-link0", -IFF_LINK0
, setifflags
} ,
200 { "link1", IFF_LINK1
, setifflags
} ,
201 { "-link1", -IFF_LINK1
, setifflags
} ,
202 { "link2", IFF_LINK2
, setifflags
} ,
203 { "-link2", -IFF_LINK2
, setifflags
} ,
204 #ifdef ENABLE_MEDIA_IOCTL
205 { "media", NEXTARG
, setmedia
},
206 { "mediaopt", NEXTARG
, setmediaopt
},
207 { "-mediaopt", NEXTARG
, unsetmediaopt
},
210 { 0, 0, setifdstaddr
},
213 void adjust_nsellength
__P((void));
214 int getinfo
__P((struct ifreq
*));
215 void getsock
__P((int));
216 void printall
__P((void));
217 void printb
__P((char *, unsigned short, char *));
218 void status
__P((const u_int8_t
*, int));
219 void usage
__P((void));
220 #ifdef ENABLE_MEDIA_IOCTL
221 void domediaopt
__P((char *, int));
222 int get_media_subtype
__P((int, char *));
223 int get_media_options
__P((int, char *));
224 int lookup_media_word
__P((struct ifmedia_description
*, char *));
225 void print_media_word
__P((int));
228 * XNS support liberally adapted from code written at the University of
229 * Maryland principally by James O'Toole and Chris Torek.
231 void in_status
__P((int));
232 void in_getaddr
__P((char *, int));
233 void at_status
__P((int));
234 void at_getaddr
__P((char *, int));
235 void xns_status
__P((int));
236 void xns_getaddr
__P((char *, int));
237 void iso_status
__P((int));
238 void iso_getaddr
__P((char *, int));
240 /* Known address families */
244 void (*af_status
) __P((int));
245 void (*af_getaddr
) __P((char *, int));
251 #define C(x) ((caddr_t) &x)
252 { "inet", AF_INET
, in_status
, in_getaddr
,
253 SIOCDIFADDR
, SIOCAIFADDR
, C(ridreq
), C(addreq
) },
254 #ifndef INET_ONLY /* small version, for boot media */
255 { "atalk", AF_APPLETALK
, at_status
, at_getaddr
,
256 SIOCDIFADDR
, SIOCAIFADDR
, C(addreq
), C(addreq
) },
257 { "ns", AF_NS
, xns_status
, xns_getaddr
,
258 SIOCDIFADDR
, SIOCAIFADDR
, C(ridreq
), C(addreq
) },
259 { "iso", AF_ISO
, iso_status
, iso_getaddr
,
260 SIOCDIFADDR
, SIOCAIFADDR
, C(ridreq
), C(iso_addreq
) },
261 #endif /* INET_ONLY */
265 struct afswtch
*afp
; /*the address family being set or asked about*/
267 struct afswtch
*lookup_af
__P((const char *));
269 static void __close_bsdsocket()
271 if (MiamiBase
!= NULL
)
273 CloseLibrary(MiamiBase
);
276 if (SocketBase
!= NULL
)
278 CloseLibrary(SocketBase
);
290 #if defined(__AROS__)
291 if (!(SocketBase
= OpenLibrary(socket_name
, SOCKET_VERSION
)))
295 if (!(MiamiBase
= OpenLibrary("miami.library", 0)))
299 atexit(__close_bsdsocket
);
302 /* Parse command-line options */
304 while ((ch
= getopt(argc
, argv
, "adlmu")) != -1) {
335 * -l means "list all interfaces", and is mutally exclusive with
336 * all other flags/commands.
338 * -a means "print status of all interfaces".
340 if (lflag
&& (aflag
|| mflag
|| argc
))
342 if (aflag
|| lflag
) {
345 else if (argc
== 1) {
346 afp
= lookup_af(argv
[0]);
351 af
= ifr
.ifr_addr
.sa_family
= afp
->af_af
;
353 af
= ifr
.ifr_addr
.sa_family
= afs
[0].af_af
;
358 /* Make sure there's an interface name. */
361 (void) strncpy(name
, argv
[0], sizeof(name
) - 1);
364 /* Check for address family. */
367 afp
= lookup_af(argv
[0]);
376 af
= ifr
.ifr_addr
.sa_family
= afp
->af_af
;
378 /* Get information about the interface. */
379 CopyMem(name
, ifr
.ifr_name
, sizeof (ifr
.ifr_name
));
380 ifr
.ifr_name
[sizeof(ifr
.ifr_name
) - 1] = '\0';
381 if (getinfo(&ifr
) < 0)
384 /* No more arguments means interface status. */
390 /* Process commands. */
394 for (p
= cmds
; p
->c_name
; p
++)
395 if (strcmp(argv
[0], p
->c_name
) == 0)
397 if (p
->c_name
== 0 && setaddr
)
398 p
++; /* got src, do dst */
400 if (p
->c_parameter
== NEXTARG
) {
402 errx(1, "'%s' requires argument",
404 (*p
->c_func
)(argv
[1], 0);
407 (*p
->c_func
)(argv
[0], p
->c_parameter
);
417 if (af
== AF_APPLETALK
)
418 checkatrange((struct sockaddr_at
*) &addreq
.ifra_addr
);
420 if (setipdst
&& af
==AF_NS
) {
422 int size
= sizeof(rq
);
424 rq
.rq_ns
= addreq
.ifra_addr
;
425 rq
.rq_ip
= addreq
.ifra_dstaddr
;
427 if (setsockopt(s
, 0, SO_NSIP_ROUTE
, &rq
, size
) < 0)
428 warn("encapsulation routing");
431 #endif /* INET_ONLY */
435 CopyMem(name
, afp
->af_ridreq
, sizeof (ifr
.ifr_name
));
436 afp
->af_ridreq
[sizeof(ifr
.ifr_name
) - 1] = '\0';
437 if ((ret
= IoctlSocket(s
, afp
->af_difaddr
, afp
->af_ridreq
)) < 0) {
438 if (errno
== EADDRNOTAVAIL
&& (doalias
>= 0)) {
439 /* means no previous address for interface */
445 CopyMem(name
, afp
->af_addreq
, sizeof (ifr
.ifr_name
));
446 afp
->af_addreq
[sizeof(ifr
.ifr_name
) - 1] = '\0';
447 if (IoctlSocket(s
, afp
->af_aifaddr
, afp
->af_addreq
) < 0)
450 if (reset_if_flags
&& IoctlSocket(s
, SIOCSIFFLAGS
, (caddr_t
)&ifr
) < 0)
451 err(1, "SIOCSIFFLAGS");
461 for (a
= afs
; a
->af_name
!= NULL
; a
++)
462 if (strcmp(a
->af_name
, cp
) == 0)
477 s
= socket(naf
, SOCK_DGRAM
, 0);
492 if (IoctlSocket(s
, SIOCGIFFLAGS
, (caddr_t
)ifr
) < 0) {
493 #if !defined(__AROS__)
494 warn("SIOCGIFFLAGS %s", ifr
->ifr_name
);
498 flags
= ifr
->ifr_flags
;
499 if (IoctlSocket(s
, SIOCGIFMETRIC
, (caddr_t
)ifr
) < 0) {
500 #if !defined(__AROS__)
501 warn("SIOCGIFMETRIC %s", ifr
->ifr_name
);
505 metric
= ifr
->ifr_metric
;
506 if (IoctlSocket(s
, SIOCGIFMTU
, (caddr_t
)ifr
) < 0)
517 const struct sockaddr_dl
*sdl
= NULL
;
519 struct ifreq ifreq
, *ifr
;
522 ifc
.ifc_len
= sizeof(inbuf
);
527 if (IoctlSocket(s
, SIOCGIFCONF
, (char *)&ifc
) < 0)
528 err(1, "SIOCGIFCONF");
530 ifreq
.ifr_name
[0] = '\0';
531 for (i
= 0, idx
= 0; i
< ifc
.ifc_len
; ) {
532 ifr
= (struct ifreq
*)((caddr_t
)ifc
.ifc_req
+ i
);
533 i
+= sizeof(ifr
->ifr_name
) +
534 (ifr
->ifr_addr
.sa_len
> sizeof(struct sockaddr
)
535 ? ifr
->ifr_addr
.sa_len
536 : sizeof(struct sockaddr
));
537 if (ifr
->ifr_addr
.sa_family
== AF_LINK
)
538 sdl
= (const struct sockaddr_dl
*) &ifr
->ifr_addr
;
539 if (!strncmp(ifreq
.ifr_name
, ifr
->ifr_name
,
540 sizeof(ifr
->ifr_name
)))
542 (void) strncpy(name
, ifr
->ifr_name
, sizeof(name
));
545 if (getinfo(&ifreq
) < 0)
547 if (dflag
&& (flags
& IFF_UP
) != 0)
549 if (uflag
&& (flags
& IFF_UP
) == 0)
554 * Are we just listing the interfaces?
566 status(LLADDR(sdl
), sdl
->sdl_alen
);
581 setifaddr(addr
, param
)
586 * Delay the IoctlSocket to set the interface addr until flags are all set.
587 * The address interpretation may depend on the flags,
588 * and the flags may change when the address is set.
595 (*afp
->af_getaddr
)(addr
, (doalias
>= 0 ? ADDR
: RIDADDR
));
599 setifnetmask(addr
, d
)
603 (*afp
->af_getaddr
)(addr
, MASK
);
607 setifbroadaddr(addr
, d
)
611 (*afp
->af_getaddr
)(addr
, DSTADDR
);
619 in_getaddr(addr
, DSTADDR
);
625 #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
628 notealias(addr
, param
)
632 if (setaddr
&& doalias
== 0 && param
< 0)
633 (void) memcpy(rqtosa(af_ridreq
), rqtosa(af_addreq
),
634 rqtosa(af_addreq
)->sa_len
);
645 notrailers(vname
, value
)
649 puts("Note: trailers are no longer sent, but always received");
654 setifdstaddr(addr
, param
)
658 (*afp
->af_getaddr
)(addr
, DSTADDR
);
662 setifflags(vname
, value
)
666 if (IoctlSocket(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) < 0)
667 err(1, "SIOCGIFFLAGS");
668 CopyMem(name
, ifr
.ifr_name
, sizeof (ifr
.ifr_name
));
669 ifr
.ifr_name
[sizeof(ifr
.ifr_name
) - 1] = '\0';
670 flags
= ifr
.ifr_flags
;
677 ifr
.ifr_flags
= flags
;
678 /* if (IoctlSocket(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
679 err(1, "SIOCSIFFLAGS");*/
689 CopyMem(name
, ifr
.ifr_name
, sizeof (ifr
.ifr_name
));
690 ifr
.ifr_name
[sizeof(ifr
.ifr_name
) - 1] = '\0';
691 ifr
.ifr_metric
= atoi(val
);
692 if (IoctlSocket(s
, SIOCSIFMETRIC
, (caddr_t
)&ifr
) < 0)
693 warn("SIOCSIFMETRIC");
701 CopyMem(name
, ifr
.ifr_name
, sizeof (ifr
.ifr_name
));
702 ifr
.ifr_name
[sizeof(ifr
.ifr_name
) - 1] = '\0';
703 ifr
.ifr_mtu
= atoi(val
);
704 if (IoctlSocket(s
, SIOCSIFMTU
, (caddr_t
)&ifr
) < 0)
707 #ifdef ENABLE_MEDIA_IOCTL
713 struct ifmediareq ifmr
;
714 int first_type
, subtype
;
716 (void) memset(&ifmr
, 0, sizeof(ifmr
));
717 CopyMem(name
, ifmr
.ifm_name
, sizeof (ifmr
.ifm_name
));
718 ifr
.ifr_name
[sizeof(ifmr
.ifm_name
) - 1] = '\0';
721 ifmr
.ifm_ulist
= &first_type
;
722 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0) {
724 * If we get E2BIG, the kernel is telling us
725 * that there are more, so we can ignore it.
728 err(1, "SIOCGIFMEDIA");
731 if (ifmr
.ifm_count
== 0)
732 errx(1, "%s: no media types?", name
);
735 * We are primarily concerned with the top-level type.
736 * However, "current" may be only IFM_NONE, so we just look
737 * for the top-level type in the first "supported type"
740 * (I'm assuming that all supported media types for a given
741 * interface will be the same top-level type..)
743 subtype
= get_media_subtype(IFM_TYPE(first_type
), val
);
745 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
746 ifr
.ifr_media
= (ifmr
.ifm_current
& ~(IFM_NMASK
|IFM_TMASK
)) |
747 IFM_TYPE(first_type
) | subtype
;
749 if (IoctlSocket(s
, SIOCSIFMEDIA
, (caddr_t
)&ifr
) < 0)
750 err(1, "SIOCSIFMEDIA");
763 unsetmediaopt(val
, d
)
772 domediaopt(val
, clear
)
776 struct ifmediareq ifmr
;
777 int *mwords
, options
;
779 (void) memset(&ifmr
, 0, sizeof(ifmr
));
780 (void) strncpy(ifmr
.ifm_name
, name
, sizeof(ifmr
.ifm_name
));
783 * We must go through the motions of reading all
784 * supported media because we need to know both
785 * the current media type and the top-level type.
788 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0)
789 err(1, "SIOCGIFMEDIA");
791 if (ifmr
.ifm_count
== 0)
792 errx(1, "%s: no media types?", name
);
794 mwords
= (int *)malloc(ifmr
.ifm_count
* sizeof(int));
798 ifmr
.ifm_ulist
= mwords
;
799 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0)
800 err(1, "SIOCGIFMEDIA");
802 options
= get_media_options(IFM_TYPE(mwords
[0]), val
);
806 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
807 ifr
.ifr_media
= ifmr
.ifm_current
;
809 ifr
.ifr_media
&= ~options
;
811 ifr
.ifr_media
|= options
;
813 if (IoctlSocket(s
, SIOCSIFMEDIA
, (caddr_t
)&ifr
) < 0)
814 err(1, "SIOCSIFMEDIA");
817 /**********************************************************************
818 * A good chunk of this is duplicated from sys/net/ifmedia.c
819 **********************************************************************/
821 struct ifmedia_description ifm_type_descriptions
[] =
822 IFM_TYPE_DESCRIPTIONS
;
824 struct ifmedia_description ifm_subtype_ethernet_descriptions
[] =
825 IFM_SUBTYPE_ETHERNET_DESCRIPTIONS
;
827 struct ifmedia_description ifm_subtype_ethernet_aliases
[] =
828 IFM_SUBTYPE_ETHERNET_ALIASES
;
830 struct ifmedia_description ifm_subtype_ethernet_option_descriptions
[] =
831 IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS
;
833 struct ifmedia_description ifm_subtype_tokenring_descriptions
[] =
834 IFM_SUBTYPE_TOKENRING_DESCRIPTIONS
;
836 struct ifmedia_description ifm_subtype_tokenring_aliases
[] =
837 IFM_SUBTYPE_TOKENRING_ALIASES
;
839 struct ifmedia_description ifm_subtype_tokenring_option_descriptions
[] =
840 IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS
;
842 struct ifmedia_description ifm_subtype_fddi_descriptions
[] =
843 IFM_SUBTYPE_FDDI_DESCRIPTIONS
;
845 struct ifmedia_description ifm_subtype_fddi_aliases
[] =
846 IFM_SUBTYPE_FDDI_ALIASES
;
848 struct ifmedia_description ifm_subtype_fddi_option_descriptions
[] =
849 IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS
;
851 struct ifmedia_description ifm_subtype_shared_descriptions
[] =
852 IFM_SUBTYPE_SHARED_DESCRIPTIONS
;
854 struct ifmedia_description ifm_subtype_shared_aliases
[] =
855 IFM_SUBTYPE_SHARED_ALIASES
;
857 struct ifmedia_description ifm_shared_option_descriptions
[] =
858 IFM_SHARED_OPTION_DESCRIPTIONS
;
860 struct ifmedia_type_to_subtype
{
862 struct ifmedia_description
*desc
;
866 struct ifmedia_description
*desc
;
871 /* must be in the same order as IFM_TYPE_DESCRIPTIONS */
872 struct ifmedia_type_to_subtype ifmedia_types_to_subtypes
[] = {
875 { &ifm_subtype_shared_descriptions
[0], 0 },
876 { &ifm_subtype_shared_aliases
[0], 1 },
877 { &ifm_subtype_ethernet_descriptions
[0], 0 },
878 { &ifm_subtype_ethernet_aliases
[0], 1 },
882 { &ifm_shared_option_descriptions
[0], 0 },
883 { &ifm_subtype_ethernet_option_descriptions
[0], 1 },
889 { &ifm_subtype_shared_descriptions
[0], 0 },
890 { &ifm_subtype_shared_aliases
[0], 1 },
891 { &ifm_subtype_tokenring_descriptions
[0], 0 },
892 { &ifm_subtype_tokenring_aliases
[0], 1 },
896 { &ifm_shared_option_descriptions
[0], 0 },
897 { &ifm_subtype_tokenring_option_descriptions
[0], 1 },
903 { &ifm_subtype_shared_descriptions
[0], 0 },
904 { &ifm_subtype_shared_aliases
[0], 1 },
905 { &ifm_subtype_fddi_descriptions
[0], 0 },
906 { &ifm_subtype_fddi_aliases
[0], 1 },
910 { &ifm_shared_option_descriptions
[0], 0 },
911 { &ifm_subtype_fddi_option_descriptions
[0], 1 },
918 get_media_subtype(type
, val
)
922 struct ifmedia_description
*desc
;
923 struct ifmedia_type_to_subtype
*ttos
;
926 /* Find the top-level interface type. */
927 for (desc
= ifm_type_descriptions
, ttos
= ifmedia_types_to_subtypes
;
928 desc
->ifmt_string
!= NULL
; desc
++, ttos
++)
929 if (type
== desc
->ifmt_word
)
931 if (desc
->ifmt_string
== NULL
)
932 errx(1, "unknown media type 0x%x", type
);
934 for (i
= 0; ttos
->subtypes
[i
].desc
!= NULL
; i
++) {
935 rval
= lookup_media_word(ttos
->subtypes
[i
].desc
, val
);
939 errx(1, "unknown media subtype: %s", val
);
944 get_media_options(type
, val
)
948 struct ifmedia_description
*desc
;
949 struct ifmedia_type_to_subtype
*ttos
;
951 int option
= 0, i
, rval
= 0;
953 /* We muck with the string, so copy it. */
954 optlist
= strdup(val
);
959 /* Find the top-level interface type. */
960 for (desc
= ifm_type_descriptions
, ttos
= ifmedia_types_to_subtypes
;
961 desc
->ifmt_string
!= NULL
; desc
++, ttos
++)
962 if (type
== desc
->ifmt_word
)
964 if (desc
->ifmt_string
== NULL
)
965 errx(1, "unknown media type 0x%x", type
);
968 * Look up the options in the user-provided comma-separated
971 for (; (val
= strtok(val
, ",")) != NULL
; val
= NULL
) {
972 for (i
= 0; ttos
->options
[i
].desc
!= NULL
; i
++) {
973 option
= lookup_media_word(ttos
->options
[i
].desc
, val
);
978 errx(1, "unknown option: %s", val
);
987 lookup_media_word(desc
, val
)
988 struct ifmedia_description
*desc
;
992 for (; desc
->ifmt_string
!= NULL
; desc
++)
993 if (strcasecmp(desc
->ifmt_string
, val
) == 0)
994 return (desc
->ifmt_word
);
1000 print_media_word(ifmw
)
1003 struct ifmedia_description
*desc
;
1004 struct ifmedia_type_to_subtype
*ttos
;
1005 int seen_option
= 0, i
;
1007 /* Find the top-level interface type. */
1008 for (desc
= ifm_type_descriptions
, ttos
= ifmedia_types_to_subtypes
;
1009 desc
->ifmt_string
!= NULL
; desc
++, ttos
++)
1010 if (IFM_TYPE(ifmw
) == desc
->ifmt_word
)
1012 if (desc
->ifmt_string
== NULL
) {
1013 printf("<unknown type>");
1018 * Don't print the top-level type; it's not like we can
1019 * change it, or anything.
1023 for (i
= 0; ttos
->subtypes
[i
].desc
!= NULL
; i
++) {
1024 if (ttos
->subtypes
[i
].alias
)
1026 for (desc
= ttos
->subtypes
[i
].desc
;
1027 desc
->ifmt_string
!= NULL
; desc
++) {
1028 if (IFM_SUBTYPE(ifmw
) == desc
->ifmt_word
)
1033 /* Falling to here means unknown subtype. */
1034 printf("<unknown subtype>");
1038 printf("%s", desc
->ifmt_string
);
1041 for (i
= 0; ttos
->options
[i
].desc
!= NULL
; i
++) {
1042 if (ttos
->options
[i
].alias
)
1044 for (desc
= ttos
->options
[i
].desc
;
1045 desc
->ifmt_string
!= NULL
; desc
++) {
1046 if (ifmw
& desc
->ifmt_word
) {
1047 if (seen_option
== 0)
1049 printf("%s%s", seen_option
++ ? "," : "",
1054 printf("%s", seen_option
? ">" : "");
1057 /**********************************************************************
1059 **********************************************************************/
1062 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
1063 \11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST"
1066 * Print the status of the interface. If an address family was
1067 * specified, show it and it only; otherwise, show them all.
1074 struct afswtch
*p
= afp
;
1075 #ifdef ENABLE_MEDIA_IOCTL
1076 struct ifmediareq ifmr
;
1081 printf("%s: ", name
);
1082 printb("flags", flags
, IFFBITS
);
1084 printf(" metric %d", metric
);
1086 printf(" mtu %d", mtu
);
1088 if (ap
&& alen
> 0) {
1089 printf("\taddress:");
1090 for (i
= 0; i
< alen
; i
++, ap
++)
1091 printf("%c%02x", i
> 0 ? ':' : ' ', *ap
);
1094 #ifdef ENABLE_MEDIA_IOCTL
1095 (void) memset(&ifmr
, 0, sizeof(ifmr
));
1096 (void) strncpy(ifmr
.ifm_name
, name
, sizeof(ifmr
.ifm_name
));
1098 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0) {
1100 * Interface doesn't support SIOC{G,S}IFMEDIA.
1105 if (ifmr
.ifm_count
== 0) {
1106 warnx("%s: no media types?", name
);
1110 media_list
= (int *)malloc(ifmr
.ifm_count
* sizeof(int));
1111 if (media_list
== NULL
)
1113 ifmr
.ifm_ulist
= media_list
;
1115 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0)
1116 err(1, "SIOCGIFMEDIA");
1118 printf("\tmedia: ");
1119 print_media_word(ifmr
.ifm_current
);
1120 if (ifmr
.ifm_active
!= ifmr
.ifm_current
) {
1123 print_media_word(ifmr
.ifm_active
);
1127 if (ifmr
.ifm_status
& IFM_AVALID
) {
1128 printf(" status: ");
1129 switch (IFM_TYPE(ifmr
.ifm_active
)) {
1131 if (ifmr
.ifm_status
& IFM_ACTIVE
)
1134 printf("no carrier");
1139 if (ifmr
.ifm_status
& IFM_ACTIVE
)
1150 printf("\tsupported media:");
1151 for (i
= 0; i
< ifmr
.ifm_count
; i
++) {
1153 print_media_word(media_list
[i
]);
1161 if ((p
= afp
) != NULL
) {
1163 } else for (p
= afs
; p
->af_name
; p
++) {
1164 ifr
.ifr_addr
.sa_family
= p
->af_af
;
1173 struct sockaddr_in
*sin
;
1177 if (errno
== EPROTONOSUPPORT
)
1181 (void) memset(&ifr
, 0, sizeof(ifr
));
1182 CopyMem(name
, ifr
.ifr_name
, sizeof (ifr
.ifr_name
));
1183 ifr
.ifr_name
[sizeof(ifr
.ifr_name
) - 1] = '\0';
1184 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1185 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1188 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1190 warn("SIOCGIFADDR");
1192 CopyMem(name
, ifr
.ifr_name
, sizeof (ifr
.ifr_name
));
1193 ifr
.ifr_name
[sizeof(ifr
.ifr_name
) - 1] = '\0';
1194 sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
1195 printf("\tinet %s ", inet_ntoa(sin
->sin_addr
));
1196 CopyMem(name
, ifr
.ifr_name
, sizeof (ifr
.ifr_name
));
1197 ifr
.ifr_name
[sizeof(ifr
.ifr_name
) - 1] = '\0';
1198 if (IoctlSocket(s
, SIOCGIFNETMASK
, (caddr_t
)&ifr
) < 0) {
1199 if (errno
!= EADDRNOTAVAIL
)
1200 warn("SIOCGIFNETMASK");
1201 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1203 struct sockaddr_in
*nm_sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
1204 netmask
.sin_addr
= nm_sin
->sin_addr
;
1206 if (flags
& IFF_POINTOPOINT
) {
1207 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1208 if (errno
== EADDRNOTAVAIL
)
1209 (void) memset(&ifr
.ifr_addr
, 0,
1210 sizeof(ifr
.ifr_addr
));
1212 warn("SIOCGIFDSTADDR");
1214 CopyMem(name
, ifr
.ifr_name
, sizeof (ifr
.ifr_name
));
1215 ifr
.ifr_name
[sizeof(ifr
.ifr_name
) - 1] = '\0';
1216 sin
= (struct sockaddr_in
*)&ifr
.ifr_dstaddr
;
1217 printf("--> %s ", inet_ntoa(sin
->sin_addr
));
1219 printf("netmask 0x%x ", (unsigned int)ntohl(netmask
.sin_addr
.s_addr
));
1220 if (flags
& IFF_BROADCAST
) {
1221 if (IoctlSocket(s
, SIOCGIFBRDADDR
, (caddr_t
)&ifr
) < 0) {
1222 if (errno
== EADDRNOTAVAIL
)
1223 (void) memset(&ifr
.ifr_addr
, 0,
1224 sizeof(ifr
.ifr_addr
));
1226 warn("SIOCGIFBRDADDR");
1228 CopyMem(name
, ifr
.ifr_name
, sizeof (ifr
.ifr_name
));
1229 ifr
.ifr_name
[sizeof(ifr
.ifr_name
) - 1] = '\0';
1230 sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
1231 if (sin
->sin_addr
.s_addr
!= 0)
1232 printf("broadcast %s", inet_ntoa(sin
->sin_addr
));
1243 struct sockaddr_at
*sat
, null_sat
;
1244 struct netrange
*nr
;
1246 getsock(AF_APPLETALK
);
1248 if (errno
== EPROTONOSUPPORT
)
1252 (void) memset(&ifr
, 0, sizeof(ifr
));
1253 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1254 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1255 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1258 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1260 warn("SIOCGIFADDR");
1262 (void) strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
1263 sat
= (struct sockaddr_at
*)&ifr
.ifr_addr
;
1265 (void) memset(&null_sat
, 0, sizeof(null_sat
));
1267 nr
= (struct netrange
*) &sat
->sat_zero
;
1268 printf("\tatalk %d.%d range %d-%d phase %d",
1269 ntohs(sat
->sat_addr
.s_net
), sat
->sat_addr
.s_node
,
1270 ntohs(nr
->nr_firstnet
), ntohs(nr
->nr_lastnet
), nr
->nr_phase
);
1271 if (flags
& IFF_POINTOPOINT
) {
1272 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1273 if (errno
== EADDRNOTAVAIL
)
1274 (void) memset(&ifr
.ifr_addr
, 0,
1275 sizeof(ifr
.ifr_addr
));
1277 warn("SIOCGIFDSTADDR");
1279 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1280 sat
= (struct sockaddr_at
*)&ifr
.ifr_dstaddr
;
1284 ntohs(sat
->sat_addr
.s_net
), sat
->sat_addr
.s_node
);
1286 if (flags
& IFF_BROADCAST
) {
1287 /* note RTAX_BRD overlap with IFF_POINTOPOINT */
1288 sat
= (struct sockaddr_at
*)&ifr
.ifr_broadaddr
;
1290 printf(" broadcast %d.%d", ntohs(sat
->sat_addr
.s_net
),
1291 sat
->sat_addr
.s_node
);
1300 struct sockaddr_ns
*sns
;
1304 if (errno
== EPROTONOSUPPORT
)
1308 (void) memset(&ifr
, 0, sizeof(ifr
));
1309 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1310 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1311 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1314 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1316 warn("SIOCGIFADDR");
1318 (void) strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
1319 sns
= (struct sockaddr_ns
*)&ifr
.ifr_addr
;
1320 printf("\tns %s ", ns_ntoa(sns
->sns_addr
));
1321 if (flags
& IFF_POINTOPOINT
) { /* by W. Nesheim@Cornell */
1322 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1323 if (errno
== EADDRNOTAVAIL
)
1324 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1326 warn("SIOCGIFDSTADDR");
1328 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1329 sns
= (struct sockaddr_ns
*)&ifr
.ifr_dstaddr
;
1330 printf("--> %s ", ns_ntoa(sns
->sns_addr
));
1339 struct sockaddr_iso
*siso
;
1343 if (errno
== EPROTONOSUPPORT
)
1347 (void) memset(&ifr
, 0, sizeof(ifr
));
1348 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1349 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1350 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1353 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1355 warn("SIOCGIFADDR");
1357 (void) strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
1358 siso
= (struct sockaddr_iso
*)&ifr
.ifr_addr
;
1359 printf("\tiso %s ", iso_ntoa(&siso
->siso_addr
));
1360 if (IoctlSocket(s
, SIOCGIFNETMASK
, (caddr_t
)&ifr
) < 0) {
1361 if (errno
== EADDRNOTAVAIL
)
1362 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1364 warn("SIOCGIFNETMASK");
1366 printf(" netmask %s ", iso_ntoa(&siso
->siso_addr
));
1368 if (flags
& IFF_POINTOPOINT
) {
1369 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1370 if (errno
== EADDRNOTAVAIL
)
1371 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1373 warn("SIOCGIFDSTADDR");
1375 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1376 siso
= (struct sockaddr_iso
*)&ifr
.ifr_addr
;
1377 printf("--> %s ", iso_ntoa(&siso
->siso_addr
));
1382 #endif /* INET_ONLY */
1384 #define SIN(x) ((struct sockaddr_in *) &(x))
1385 struct sockaddr_in
*sintab
[] = {
1386 SIN(ridreq
.ifr_addr
), SIN(addreq
.ifra_addr
),
1387 SIN(addreq
.ifra_mask
), SIN(addreq
.ifra_broadaddr
)};
1390 in_getaddr(s
, which
)
1394 struct sockaddr_in
*sin
= sintab
[which
];
1398 sin
->sin_len
= sizeof(*sin
);
1400 sin
->sin_family
= AF_INET
;
1402 if (inet_aton(s
, &sin
->sin_addr
) == 0) {
1403 if ((hp
= gethostbyname(s
)) != NULL
)
1404 (void) memcpy(&sin
->sin_addr
, hp
->h_addr
, hp
->h_length
);
1405 else if ((np
= getnetbyname(s
)) != NULL
)
1407 sin
->sin_addr
.s_addr
= inet_makeaddr(np
->n_net
, INADDR_ANY
);
1410 errx(1, "%s: bad value", s
);
1415 * Print a value a la the %b format of the kernel's printf
1426 if (bits
&& *bits
== 8)
1427 printf("%s=%o", s
, v
);
1429 printf("%s=%x", s
, v
);
1433 while ((i
= *bits
++) != 0) {
1434 if (v
& (1 << (i
-1))) {
1438 for (; (c
= *bits
) > 32; bits
++)
1441 for (; *bits
> 32; bits
++)
1451 at_getaddr(addr
, which
)
1455 struct sockaddr_at
*sat
= (struct sockaddr_at
*) &addreq
.ifra_addr
;
1458 sat
->sat_family
= AF_APPLETALK
;
1459 sat
->sat_len
= sizeof(*sat
);
1461 errx(1, "AppleTalk does not use netmasks\n");
1462 if (sscanf(addr
, "%u.%u", &net
, &node
) != 2
1463 || net
== 0 || net
> 0xffff || node
== 0 || node
> 0xfe)
1464 errx(1, "%s: illegal address", addr
);
1465 sat
->sat_addr
.s_net
= htons(net
);
1466 sat
->sat_addr
.s_node
= node
;
1470 setatrange(range
, d
)
1474 u_short first
= 123, last
= 123;
1476 if (sscanf(range
, "%hu-%hu", &first
, &last
) != 2
1477 || first
== 0 || first
> 0xffff
1478 || last
== 0 || last
> 0xffff || first
> last
)
1479 errx(1, "%s: illegal net range: %u-%u", range
, first
, last
);
1480 at_nr
.nr_firstnet
= htons(first
);
1481 at_nr
.nr_lastnet
= htons(last
);
1485 setatphase(phase
, d
)
1489 if (!strcmp(phase
, "1"))
1491 else if (!strcmp(phase
, "2"))
1494 errx(1, "%s: illegal phase", phase
);
1499 struct sockaddr_at
*sat
;
1501 if (at_nr
.nr_phase
== 0)
1502 at_nr
.nr_phase
= 2; /* Default phase 2 */
1503 if (at_nr
.nr_firstnet
== 0)
1504 at_nr
.nr_firstnet
= /* Default range of one */
1505 at_nr
.nr_lastnet
= sat
->sat_addr
.s_net
;
1506 printf("\tatalk %d.%d range %d-%d phase %d\n",
1507 ntohs(sat
->sat_addr
.s_net
), sat
->sat_addr
.s_node
,
1508 ntohs(at_nr
.nr_firstnet
), ntohs(at_nr
.nr_lastnet
), at_nr
.nr_phase
);
1509 if ((u_short
) ntohs(at_nr
.nr_firstnet
) >
1510 (u_short
) ntohs(sat
->sat_addr
.s_net
)
1511 || (u_short
) ntohs(at_nr
.nr_lastnet
) <
1512 (u_short
) ntohs(sat
->sat_addr
.s_net
))
1513 errx(1, "AppleTalk address is not in range");
1514 *((struct netrange
*) &sat
->sat_zero
) = at_nr
;
1517 #define SNS(x) ((struct sockaddr_ns *) &(x))
1518 struct sockaddr_ns
*snstab
[] = {
1519 SNS(ridreq
.ifr_addr
), SNS(addreq
.ifra_addr
),
1520 SNS(addreq
.ifra_mask
), SNS(addreq
.ifra_broadaddr
)};
1523 xns_getaddr(addr
, which
)
1527 struct sockaddr_ns
*sns
= snstab
[which
];
1529 sns
->sns_family
= AF_NS
;
1530 sns
->sns_len
= sizeof(*sns
);
1531 sns
->sns_addr
= ns_addr(addr
);
1533 puts("Attempt to set XNS netmask will be ineffectual");
1536 #define SISO(x) ((struct sockaddr_iso *) &(x))
1537 struct sockaddr_iso
*sisotab
[] = {
1538 SISO(ridreq
.ifr_addr
), SISO(iso_addreq
.ifra_addr
),
1539 SISO(iso_addreq
.ifra_mask
), SISO(iso_addreq
.ifra_dstaddr
)};
1542 iso_getaddr(addr
, which
)
1546 struct sockaddr_iso
*siso
= sisotab
[which
];
1547 siso
->siso_addr
= *iso_addr(addr
);
1549 if (which
== MASK
) {
1550 siso
->siso_len
= TSEL(siso
) - (caddr_t
)(siso
);
1551 siso
->siso_nlen
= 0;
1553 siso
->siso_len
= sizeof(*siso
);
1554 siso
->siso_family
= AF_ISO
;
1559 setsnpaoffset(val
, d
)
1563 iso_addreq
.ifra_snpaoffset
= atoi(val
);
1567 setnsellength(val
, d
)
1571 nsellength
= atoi(val
);
1573 errx(1, "Negative NSEL length is absurd");
1574 if (afp
== 0 || afp
->af_af
!= AF_ISO
)
1575 errx(1, "Setting NSEL length valid only for iso");
1580 struct sockaddr_iso
*s
;
1582 if (s
->siso_family
== 0)
1584 s
->siso_tlen
= nsellength
;
1590 fixnsel(sisotab
[RIDADDR
]);
1591 fixnsel(sisotab
[ADDR
]);
1592 fixnsel(sisotab
[DSTADDR
]);
1595 #endif /* INET_ONLY */
1601 "usage: ifconfig [ -m ] interface\n%s%s%s%s%s%s%s%s%s%s%s",
1602 "\t[ af [alias | -alias | delete] [ address [ dest_addr ] ] [ up ] [ down ] ",
1603 "[ netmask mask ] ]\n",
1606 "\t[ arp | -arp ]\n",
1607 #ifdef ENABLE_MEDIA_IOCTL
1608 "\t[ media mtype ]\n",
1609 "\t[ mediaopt mopts ]\n",
1610 "\t[ -mediaopt mopts ]\n",
1614 "\t[ link0 | -link0 ] [ link1 | -link1 ] [ link2 | -link2 ]\n",
1615 " ifconfig -a [ -m ] [ -d ] [ -u ] [ af ]\n",
1616 " ifconfig -l [ -d ] [ -u ]\n");