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
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25 * Copyright (c) 1983, 1993
26 * The Regents of the University of California. All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 #include <proto/exec.h>
63 #include <sys/cdefs.h>
64 #include <sys/param.h>
65 #include <sys/socket.h>
66 #include <sys/sockio.h>
69 #include <net/if_dl.h>
70 #ifdef ENABLE_MEDIA_IOCTL
71 #include <net/if_media.h>
73 #include <netinet/in.h>
74 #include <arpa/inet.h>
75 #ifdef ENABLE_APPLETALK
76 #include <netatalk/at.h>
81 #include <netns/ns_if.h>
87 #include <netiso/iso.h>
88 #include <netiso/iso_var.h>
90 #if !defined(__AROS__)
91 #include <sys/protosw.h>
95 #if !defined(__AROS__)
101 #define inet_makeaddr(a,b) Inet_MakeAddr(a,b)
108 #include <proto/miami.h>
109 #include <proto/socket.h>
111 #if defined(__AROS__)
112 struct Library
*SocketBase
;
113 struct Library
*MiamiBase
;
116 #define SOCKET_VERSION 3
117 const TEXT version
[] = "$VER: ifconfig 5.0 (04.12.2005)";
118 const TEXT socket_name
[] = "bsdsocket.library";
120 struct ifreq ifr
, ridreq
;
121 struct ifaliasreq addreq
__attribute__((aligned(4)));
123 struct iso_aliasreq iso_addreq
;
125 struct sockaddr_in netmask
;
126 #ifdef ENABLE_APPLETALK
127 struct netrange at_nr
; /* AppleTalk net range */
130 int flags
, metric
, mtu
, setaddr
, setipdst
, doalias
;
135 int dflag
, mflag
, lflag
, uflag
;
138 void notealias
__P((char *, int));
139 void notrailers
__P((char *, int));
140 void setifaddr
__P((char *, int));
141 void setifdstaddr
__P((char *, int));
142 void setifflags
__P((char *, int));
143 void setifbroadaddr
__P((char *, int));
144 void setifipdst
__P((char *, int));
145 void setifmetric
__P((char *, int));
146 void setifmtu
__P((char *, int));
147 void setifnetmask
__P((char *, int));
148 void setnsellength
__P((char *, int));
149 void setsnpaoffset
__P((char *, int));
150 void setatrange
__P((char *, int));
151 void setatphase
__P((char *, int));
152 #ifdef ENABLE_APPLETALK
153 void checkatrange
__P ((struct sockaddr_at
*));
155 void setmedia
__P((char *, int));
156 void setmediaopt
__P((char *, int));
157 void unsetmediaopt
__P((char *, int));
159 void fixnsel
__P((struct sockaddr_iso
*));
161 int main
__P((int, char *[]));
163 #define NEXTARG 0xffffff
167 int c_parameter
; /* NEXTARG means next argv */
168 void (*c_func
) __P((char *, int));
170 { "up", IFF_UP
, setifflags
} ,
171 { "down", -IFF_UP
, setifflags
},
172 { "trailers", -1, notrailers
},
173 { "-trailers", 1, notrailers
},
174 { "arp", -IFF_NOARP
, setifflags
},
175 { "-arp", IFF_NOARP
, setifflags
},
176 { "debug", IFF_DEBUG
, setifflags
},
177 { "-debug", -IFF_DEBUG
, setifflags
},
178 { "alias", IFF_UP
, notealias
},
179 { "-alias", -IFF_UP
, notealias
},
180 { "delete", -IFF_UP
, notealias
},
182 #define EN_SWABIPS 0x1000
183 { "swabips", EN_SWABIPS
, setifflags
},
184 { "-swabips", -EN_SWABIPS
, setifflags
},
186 { "netmask", NEXTARG
, setifnetmask
},
187 { "metric", NEXTARG
, setifmetric
},
188 { "mtu", NEXTARG
, setifmtu
},
189 { "broadcast", NEXTARG
, setifbroadaddr
},
190 { "ipdst", NEXTARG
, setifipdst
},
192 { "range", NEXTARG
, setatrange
},
193 { "phase", NEXTARG
, setatphase
},
194 { "snpaoffset", NEXTARG
, setsnpaoffset
},
195 { "nsellength", NEXTARG
, setnsellength
},
196 #endif /* INET_ONLY */
197 { "link0", IFF_LINK0
, setifflags
} ,
198 { "-link0", -IFF_LINK0
, setifflags
} ,
199 { "link1", IFF_LINK1
, setifflags
} ,
200 { "-link1", -IFF_LINK1
, setifflags
} ,
201 { "link2", IFF_LINK2
, setifflags
} ,
202 { "-link2", -IFF_LINK2
, setifflags
} ,
203 #ifdef ENABLE_MEDIA_IOCTL
204 { "media", NEXTARG
, setmedia
},
205 { "mediaopt", NEXTARG
, setmediaopt
},
206 { "-mediaopt", NEXTARG
, unsetmediaopt
},
209 { 0, 0, setifdstaddr
},
212 void adjust_nsellength
__P((void));
213 int getinfo
__P((struct ifreq
*));
214 void getsock
__P((int));
215 void printall
__P((void));
216 void printb
__P((char *, unsigned short, char *));
217 void status
__P((const u_int8_t
*, int));
218 void usage
__P((void));
219 #ifdef ENABLE_MEDIA_IOCTL
220 void domediaopt
__P((char *, int));
221 int get_media_subtype
__P((int, char *));
222 int get_media_options
__P((int, char *));
223 int lookup_media_word
__P((struct ifmedia_description
*, char *));
224 void print_media_word
__P((int));
227 * XNS support liberally adapted from code written at the University of
228 * Maryland principally by James O'Toole and Chris Torek.
230 void in_status
__P((int));
231 void in_getaddr
__P((char *, int));
232 void at_status
__P((int));
233 void at_getaddr
__P((char *, int));
234 void xns_status
__P((int));
235 void xns_getaddr
__P((char *, int));
236 void iso_status
__P((int));
237 void iso_getaddr
__P((char *, int));
239 /* Known address families */
243 void (*af_status
) __P((int));
244 void (*af_getaddr
) __P((char *, int));
250 #define C(x) ((caddr_t) &x)
251 { "inet", AF_INET
, in_status
, in_getaddr
,
252 SIOCDIFADDR
, SIOCAIFADDR
, C(ridreq
), C(addreq
) },
253 #ifndef INET_ONLY /* small version, for boot media */
254 { "atalk", AF_APPLETALK
, at_status
, at_getaddr
,
255 SIOCDIFADDR
, SIOCAIFADDR
, C(addreq
), C(addreq
) },
256 { "ns", AF_NS
, xns_status
, xns_getaddr
,
257 SIOCDIFADDR
, SIOCAIFADDR
, C(ridreq
), C(addreq
) },
258 { "iso", AF_ISO
, iso_status
, iso_getaddr
,
259 SIOCDIFADDR
, SIOCAIFADDR
, C(ridreq
), C(iso_addreq
) },
260 #endif /* INET_ONLY */
264 struct afswtch
*afp
; /*the address family being set or asked about*/
266 struct afswtch
*lookup_af
__P((const char *));
268 static void __close_bsdsocket()
270 if (MiamiBase
!= NULL
)
272 CloseLibrary(MiamiBase
);
275 if (SocketBase
!= NULL
)
277 CloseLibrary(SocketBase
);
289 #if defined(__AROS__)
290 if (!(SocketBase
= OpenLibrary(socket_name
, SOCKET_VERSION
)))
294 if (!(MiamiBase
= OpenLibrary("miami.library", 0)))
298 atexit(__close_bsdsocket
);
301 /* Parse command-line options */
303 while ((ch
= getopt(argc
, argv
, "adlmu")) != -1) {
334 * -l means "list all interfaces", and is mutally exclusive with
335 * all other flags/commands.
337 * -a means "print status of all interfaces".
339 if (lflag
&& (aflag
|| mflag
|| argc
))
341 if (aflag
|| lflag
) {
344 else if (argc
== 1) {
345 afp
= lookup_af(argv
[0]);
350 af
= ifr
.ifr_addr
.sa_family
= afp
->af_af
;
352 af
= ifr
.ifr_addr
.sa_family
= afs
[0].af_af
;
357 /* Make sure there's an interface name. */
360 (void) strncpy(name
, argv
[0], sizeof(name
));
363 /* Check for address family. */
366 afp
= lookup_af(argv
[0]);
375 af
= ifr
.ifr_addr
.sa_family
= afp
->af_af
;
377 /* Get information about the interface. */
378 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
379 if (getinfo(&ifr
) < 0)
382 /* No more arguments means interface status. */
388 /* Process commands. */
392 for (p
= cmds
; p
->c_name
; p
++)
393 if (strcmp(argv
[0], p
->c_name
) == 0)
395 if (p
->c_name
== 0 && setaddr
)
396 p
++; /* got src, do dst */
398 if (p
->c_parameter
== NEXTARG
) {
400 errx(1, "'%s' requires argument",
402 (*p
->c_func
)(argv
[1], 0);
405 (*p
->c_func
)(argv
[0], p
->c_parameter
);
415 if (af
== AF_APPLETALK
)
416 checkatrange((struct sockaddr_at
*) &addreq
.ifra_addr
);
418 if (setipdst
&& af
==AF_NS
) {
420 int size
= sizeof(rq
);
422 rq
.rq_ns
= addreq
.ifra_addr
;
423 rq
.rq_ip
= addreq
.ifra_dstaddr
;
425 if (setsockopt(s
, 0, SO_NSIP_ROUTE
, &rq
, size
) < 0)
426 warn("encapsulation routing");
429 #endif /* INET_ONLY */
433 (void) strncpy(afp
->af_ridreq
, name
, sizeof ifr
.ifr_name
);
434 if ((ret
= IoctlSocket(s
, afp
->af_difaddr
, afp
->af_ridreq
)) < 0) {
435 if (errno
== EADDRNOTAVAIL
&& (doalias
>= 0)) {
436 /* means no previous address for interface */
442 (void) strncpy(afp
->af_addreq
, name
, sizeof ifr
.ifr_name
);
443 if (IoctlSocket(s
, afp
->af_aifaddr
, afp
->af_addreq
) < 0)
446 if (reset_if_flags
&& IoctlSocket(s
, SIOCSIFFLAGS
, (caddr_t
)&ifr
) < 0)
447 err(1, "SIOCSIFFLAGS");
457 for (a
= afs
; a
->af_name
!= NULL
; a
++)
458 if (strcmp(a
->af_name
, cp
) == 0)
473 s
= socket(naf
, SOCK_DGRAM
, 0);
488 if (IoctlSocket(s
, SIOCGIFFLAGS
, (caddr_t
)ifr
) < 0) {
489 #if !defined(__AROS__)
490 warn("SIOCGIFFLAGS %s", ifr
->ifr_name
);
494 flags
= ifr
->ifr_flags
;
495 if (IoctlSocket(s
, SIOCGIFMETRIC
, (caddr_t
)ifr
) < 0) {
496 #if !defined(__AROS__)
497 warn("SIOCGIFMETRIC %s", ifr
->ifr_name
);
501 metric
= ifr
->ifr_metric
;
502 if (IoctlSocket(s
, SIOCGIFMTU
, (caddr_t
)ifr
) < 0)
513 const struct sockaddr_dl
*sdl
= NULL
;
515 struct ifreq ifreq
, *ifr
;
518 ifc
.ifc_len
= sizeof(inbuf
);
523 if (IoctlSocket(s
, SIOCGIFCONF
, (char *)&ifc
) < 0)
524 err(1, "SIOCGIFCONF");
526 ifreq
.ifr_name
[0] = '\0';
527 for (i
= 0, idx
= 0; i
< ifc
.ifc_len
; ) {
528 ifr
= (struct ifreq
*)((caddr_t
)ifc
.ifc_req
+ i
);
529 i
+= sizeof(ifr
->ifr_name
) +
530 (ifr
->ifr_addr
.sa_len
> sizeof(struct sockaddr
)
531 ? ifr
->ifr_addr
.sa_len
532 : sizeof(struct sockaddr
));
533 if (ifr
->ifr_addr
.sa_family
== AF_LINK
)
534 sdl
= (const struct sockaddr_dl
*) &ifr
->ifr_addr
;
535 if (!strncmp(ifreq
.ifr_name
, ifr
->ifr_name
,
536 sizeof(ifr
->ifr_name
)))
538 (void) strncpy(name
, ifr
->ifr_name
, sizeof(ifr
->ifr_name
));
541 if (getinfo(&ifreq
) < 0)
543 if (dflag
&& (flags
& IFF_UP
) != 0)
545 if (uflag
&& (flags
& IFF_UP
) == 0)
550 * Are we just listing the interfaces?
562 status(LLADDR(sdl
), sdl
->sdl_alen
);
577 setifaddr(addr
, param
)
582 * Delay the IoctlSocket to set the interface addr until flags are all set.
583 * The address interpretation may depend on the flags,
584 * and the flags may change when the address is set.
591 (*afp
->af_getaddr
)(addr
, (doalias
>= 0 ? ADDR
: RIDADDR
));
595 setifnetmask(addr
, d
)
599 (*afp
->af_getaddr
)(addr
, MASK
);
603 setifbroadaddr(addr
, d
)
607 (*afp
->af_getaddr
)(addr
, DSTADDR
);
615 in_getaddr(addr
, DSTADDR
);
621 #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
624 notealias(addr
, param
)
628 if (setaddr
&& doalias
== 0 && param
< 0)
629 (void) memcpy(rqtosa(af_ridreq
), rqtosa(af_addreq
),
630 rqtosa(af_addreq
)->sa_len
);
641 notrailers(vname
, value
)
645 puts("Note: trailers are no longer sent, but always received");
650 setifdstaddr(addr
, param
)
654 (*afp
->af_getaddr
)(addr
, DSTADDR
);
658 setifflags(vname
, value
)
662 if (IoctlSocket(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) < 0)
663 err(1, "SIOCGIFFLAGS");
664 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
665 flags
= ifr
.ifr_flags
;
672 ifr
.ifr_flags
= flags
;
673 /* if (IoctlSocket(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
674 err(1, "SIOCSIFFLAGS");*/
684 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
685 ifr
.ifr_metric
= atoi(val
);
686 if (IoctlSocket(s
, SIOCSIFMETRIC
, (caddr_t
)&ifr
) < 0)
687 warn("SIOCSIFMETRIC");
695 (void)strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
696 ifr
.ifr_mtu
= atoi(val
);
697 if (IoctlSocket(s
, SIOCSIFMTU
, (caddr_t
)&ifr
) < 0)
700 #ifdef ENABLE_MEDIA_IOCTL
706 struct ifmediareq ifmr
;
707 int first_type
, subtype
;
709 (void) memset(&ifmr
, 0, sizeof(ifmr
));
710 (void) strncpy(ifmr
.ifm_name
, name
, sizeof(ifmr
.ifm_name
));
713 ifmr
.ifm_ulist
= &first_type
;
714 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0) {
716 * If we get E2BIG, the kernel is telling us
717 * that there are more, so we can ignore it.
720 err(1, "SIOCGIFMEDIA");
723 if (ifmr
.ifm_count
== 0)
724 errx(1, "%s: no media types?", name
);
727 * We are primarily concerned with the top-level type.
728 * However, "current" may be only IFM_NONE, so we just look
729 * for the top-level type in the first "supported type"
732 * (I'm assuming that all supported media types for a given
733 * interface will be the same top-level type..)
735 subtype
= get_media_subtype(IFM_TYPE(first_type
), val
);
737 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
738 ifr
.ifr_media
= (ifmr
.ifm_current
& ~(IFM_NMASK
|IFM_TMASK
)) |
739 IFM_TYPE(first_type
) | subtype
;
741 if (IoctlSocket(s
, SIOCSIFMEDIA
, (caddr_t
)&ifr
) < 0)
742 err(1, "SIOCSIFMEDIA");
755 unsetmediaopt(val
, d
)
764 domediaopt(val
, clear
)
768 struct ifmediareq ifmr
;
769 int *mwords
, options
;
771 (void) memset(&ifmr
, 0, sizeof(ifmr
));
772 (void) strncpy(ifmr
.ifm_name
, name
, sizeof(ifmr
.ifm_name
));
775 * We must go through the motions of reading all
776 * supported media because we need to know both
777 * the current media type and the top-level type.
780 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0)
781 err(1, "SIOCGIFMEDIA");
783 if (ifmr
.ifm_count
== 0)
784 errx(1, "%s: no media types?", name
);
786 mwords
= (int *)malloc(ifmr
.ifm_count
* sizeof(int));
790 ifmr
.ifm_ulist
= mwords
;
791 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0)
792 err(1, "SIOCGIFMEDIA");
794 options
= get_media_options(IFM_TYPE(mwords
[0]), val
);
798 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
799 ifr
.ifr_media
= ifmr
.ifm_current
;
801 ifr
.ifr_media
&= ~options
;
803 ifr
.ifr_media
|= options
;
805 if (IoctlSocket(s
, SIOCSIFMEDIA
, (caddr_t
)&ifr
) < 0)
806 err(1, "SIOCSIFMEDIA");
809 /**********************************************************************
810 * A good chunk of this is duplicated from sys/net/ifmedia.c
811 **********************************************************************/
813 struct ifmedia_description ifm_type_descriptions
[] =
814 IFM_TYPE_DESCRIPTIONS
;
816 struct ifmedia_description ifm_subtype_ethernet_descriptions
[] =
817 IFM_SUBTYPE_ETHERNET_DESCRIPTIONS
;
819 struct ifmedia_description ifm_subtype_ethernet_aliases
[] =
820 IFM_SUBTYPE_ETHERNET_ALIASES
;
822 struct ifmedia_description ifm_subtype_ethernet_option_descriptions
[] =
823 IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS
;
825 struct ifmedia_description ifm_subtype_tokenring_descriptions
[] =
826 IFM_SUBTYPE_TOKENRING_DESCRIPTIONS
;
828 struct ifmedia_description ifm_subtype_tokenring_aliases
[] =
829 IFM_SUBTYPE_TOKENRING_ALIASES
;
831 struct ifmedia_description ifm_subtype_tokenring_option_descriptions
[] =
832 IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS
;
834 struct ifmedia_description ifm_subtype_fddi_descriptions
[] =
835 IFM_SUBTYPE_FDDI_DESCRIPTIONS
;
837 struct ifmedia_description ifm_subtype_fddi_aliases
[] =
838 IFM_SUBTYPE_FDDI_ALIASES
;
840 struct ifmedia_description ifm_subtype_fddi_option_descriptions
[] =
841 IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS
;
843 struct ifmedia_description ifm_subtype_shared_descriptions
[] =
844 IFM_SUBTYPE_SHARED_DESCRIPTIONS
;
846 struct ifmedia_description ifm_subtype_shared_aliases
[] =
847 IFM_SUBTYPE_SHARED_ALIASES
;
849 struct ifmedia_description ifm_shared_option_descriptions
[] =
850 IFM_SHARED_OPTION_DESCRIPTIONS
;
852 struct ifmedia_type_to_subtype
{
854 struct ifmedia_description
*desc
;
858 struct ifmedia_description
*desc
;
863 /* must be in the same order as IFM_TYPE_DESCRIPTIONS */
864 struct ifmedia_type_to_subtype ifmedia_types_to_subtypes
[] = {
867 { &ifm_subtype_shared_descriptions
[0], 0 },
868 { &ifm_subtype_shared_aliases
[0], 1 },
869 { &ifm_subtype_ethernet_descriptions
[0], 0 },
870 { &ifm_subtype_ethernet_aliases
[0], 1 },
874 { &ifm_shared_option_descriptions
[0], 0 },
875 { &ifm_subtype_ethernet_option_descriptions
[0], 1 },
881 { &ifm_subtype_shared_descriptions
[0], 0 },
882 { &ifm_subtype_shared_aliases
[0], 1 },
883 { &ifm_subtype_tokenring_descriptions
[0], 0 },
884 { &ifm_subtype_tokenring_aliases
[0], 1 },
888 { &ifm_shared_option_descriptions
[0], 0 },
889 { &ifm_subtype_tokenring_option_descriptions
[0], 1 },
895 { &ifm_subtype_shared_descriptions
[0], 0 },
896 { &ifm_subtype_shared_aliases
[0], 1 },
897 { &ifm_subtype_fddi_descriptions
[0], 0 },
898 { &ifm_subtype_fddi_aliases
[0], 1 },
902 { &ifm_shared_option_descriptions
[0], 0 },
903 { &ifm_subtype_fddi_option_descriptions
[0], 1 },
910 get_media_subtype(type
, val
)
914 struct ifmedia_description
*desc
;
915 struct ifmedia_type_to_subtype
*ttos
;
918 /* Find the top-level interface type. */
919 for (desc
= ifm_type_descriptions
, ttos
= ifmedia_types_to_subtypes
;
920 desc
->ifmt_string
!= NULL
; desc
++, ttos
++)
921 if (type
== desc
->ifmt_word
)
923 if (desc
->ifmt_string
== NULL
)
924 errx(1, "unknown media type 0x%x", type
);
926 for (i
= 0; ttos
->subtypes
[i
].desc
!= NULL
; i
++) {
927 rval
= lookup_media_word(ttos
->subtypes
[i
].desc
, val
);
931 errx(1, "unknown media subtype: %s", val
);
936 get_media_options(type
, val
)
940 struct ifmedia_description
*desc
;
941 struct ifmedia_type_to_subtype
*ttos
;
943 int option
= 0, i
, rval
= 0;
945 /* We muck with the string, so copy it. */
946 optlist
= strdup(val
);
951 /* Find the top-level interface type. */
952 for (desc
= ifm_type_descriptions
, ttos
= ifmedia_types_to_subtypes
;
953 desc
->ifmt_string
!= NULL
; desc
++, ttos
++)
954 if (type
== desc
->ifmt_word
)
956 if (desc
->ifmt_string
== NULL
)
957 errx(1, "unknown media type 0x%x", type
);
960 * Look up the options in the user-provided comma-separated
963 for (; (val
= strtok(val
, ",")) != NULL
; val
= NULL
) {
964 for (i
= 0; ttos
->options
[i
].desc
!= NULL
; i
++) {
965 option
= lookup_media_word(ttos
->options
[i
].desc
, val
);
970 errx(1, "unknown option: %s", val
);
979 lookup_media_word(desc
, val
)
980 struct ifmedia_description
*desc
;
984 for (; desc
->ifmt_string
!= NULL
; desc
++)
985 if (strcasecmp(desc
->ifmt_string
, val
) == 0)
986 return (desc
->ifmt_word
);
992 print_media_word(ifmw
)
995 struct ifmedia_description
*desc
;
996 struct ifmedia_type_to_subtype
*ttos
;
997 int seen_option
= 0, i
;
999 /* Find the top-level interface type. */
1000 for (desc
= ifm_type_descriptions
, ttos
= ifmedia_types_to_subtypes
;
1001 desc
->ifmt_string
!= NULL
; desc
++, ttos
++)
1002 if (IFM_TYPE(ifmw
) == desc
->ifmt_word
)
1004 if (desc
->ifmt_string
== NULL
) {
1005 printf("<unknown type>");
1010 * Don't print the top-level type; it's not like we can
1011 * change it, or anything.
1015 for (i
= 0; ttos
->subtypes
[i
].desc
!= NULL
; i
++) {
1016 if (ttos
->subtypes
[i
].alias
)
1018 for (desc
= ttos
->subtypes
[i
].desc
;
1019 desc
->ifmt_string
!= NULL
; desc
++) {
1020 if (IFM_SUBTYPE(ifmw
) == desc
->ifmt_word
)
1025 /* Falling to here means unknown subtype. */
1026 printf("<unknown subtype>");
1030 printf("%s", desc
->ifmt_string
);
1033 for (i
= 0; ttos
->options
[i
].desc
!= NULL
; i
++) {
1034 if (ttos
->options
[i
].alias
)
1036 for (desc
= ttos
->options
[i
].desc
;
1037 desc
->ifmt_string
!= NULL
; desc
++) {
1038 if (ifmw
& desc
->ifmt_word
) {
1039 if (seen_option
== 0)
1041 printf("%s%s", seen_option
++ ? "," : "",
1046 printf("%s", seen_option
? ">" : "");
1049 /**********************************************************************
1051 **********************************************************************/
1054 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
1055 \11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST"
1058 * Print the status of the interface. If an address family was
1059 * specified, show it and it only; otherwise, show them all.
1066 struct afswtch
*p
= afp
;
1067 #ifdef ENABLE_MEDIA_IOCTL
1068 struct ifmediareq ifmr
;
1073 printf("%s: ", name
);
1074 printb("flags", flags
, IFFBITS
);
1076 printf(" metric %d", metric
);
1078 printf(" mtu %d", mtu
);
1080 if (ap
&& alen
> 0) {
1081 printf("\taddress:");
1082 for (i
= 0; i
< alen
; i
++, ap
++)
1083 printf("%c%02x", i
> 0 ? ':' : ' ', *ap
);
1086 #ifdef ENABLE_MEDIA_IOCTL
1087 (void) memset(&ifmr
, 0, sizeof(ifmr
));
1088 (void) strncpy(ifmr
.ifm_name
, name
, sizeof(ifmr
.ifm_name
));
1090 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0) {
1092 * Interface doesn't support SIOC{G,S}IFMEDIA.
1097 if (ifmr
.ifm_count
== 0) {
1098 warnx("%s: no media types?", name
);
1102 media_list
= (int *)malloc(ifmr
.ifm_count
* sizeof(int));
1103 if (media_list
== NULL
)
1105 ifmr
.ifm_ulist
= media_list
;
1107 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0)
1108 err(1, "SIOCGIFMEDIA");
1110 printf("\tmedia: ");
1111 print_media_word(ifmr
.ifm_current
);
1112 if (ifmr
.ifm_active
!= ifmr
.ifm_current
) {
1115 print_media_word(ifmr
.ifm_active
);
1119 if (ifmr
.ifm_status
& IFM_AVALID
) {
1120 printf(" status: ");
1121 switch (IFM_TYPE(ifmr
.ifm_active
)) {
1123 if (ifmr
.ifm_status
& IFM_ACTIVE
)
1126 printf("no carrier");
1131 if (ifmr
.ifm_status
& IFM_ACTIVE
)
1142 printf("\tsupported media:");
1143 for (i
= 0; i
< ifmr
.ifm_count
; i
++) {
1145 print_media_word(media_list
[i
]);
1153 if ((p
= afp
) != NULL
) {
1155 } else for (p
= afs
; p
->af_name
; p
++) {
1156 ifr
.ifr_addr
.sa_family
= p
->af_af
;
1165 struct sockaddr_in
*sin
;
1169 if (errno
== EPROTONOSUPPORT
)
1173 (void) memset(&ifr
, 0, sizeof(ifr
));
1174 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1175 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1176 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1179 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1181 warn("SIOCGIFADDR");
1183 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1184 sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
1185 printf("\tinet %s ", inet_ntoa(sin
->sin_addr
));
1186 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1187 if (IoctlSocket(s
, SIOCGIFNETMASK
, (caddr_t
)&ifr
) < 0) {
1188 if (errno
!= EADDRNOTAVAIL
)
1189 warn("SIOCGIFNETMASK");
1190 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1192 struct sockaddr_in
*nm_sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
1193 netmask
.sin_addr
= nm_sin
->sin_addr
;
1195 if (flags
& IFF_POINTOPOINT
) {
1196 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1197 if (errno
== EADDRNOTAVAIL
)
1198 (void) memset(&ifr
.ifr_addr
, 0,
1199 sizeof(ifr
.ifr_addr
));
1201 warn("SIOCGIFDSTADDR");
1203 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1204 sin
= (struct sockaddr_in
*)&ifr
.ifr_dstaddr
;
1205 printf("--> %s ", inet_ntoa(sin
->sin_addr
));
1207 printf("netmask 0x%x ", (unsigned int)ntohl(netmask
.sin_addr
.s_addr
));
1208 if (flags
& IFF_BROADCAST
) {
1209 if (IoctlSocket(s
, SIOCGIFBRDADDR
, (caddr_t
)&ifr
) < 0) {
1210 if (errno
== EADDRNOTAVAIL
)
1211 (void) memset(&ifr
.ifr_addr
, 0,
1212 sizeof(ifr
.ifr_addr
));
1214 warn("SIOCGIFBRDADDR");
1216 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1217 sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
1218 if (sin
->sin_addr
.s_addr
!= 0)
1219 printf("broadcast %s", inet_ntoa(sin
->sin_addr
));
1230 struct sockaddr_at
*sat
, null_sat
;
1231 struct netrange
*nr
;
1233 getsock(AF_APPLETALK
);
1235 if (errno
== EPROTONOSUPPORT
)
1239 (void) memset(&ifr
, 0, sizeof(ifr
));
1240 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1241 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1242 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1245 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1247 warn("SIOCGIFADDR");
1249 (void) strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
1250 sat
= (struct sockaddr_at
*)&ifr
.ifr_addr
;
1252 (void) memset(&null_sat
, 0, sizeof(null_sat
));
1254 nr
= (struct netrange
*) &sat
->sat_zero
;
1255 printf("\tatalk %d.%d range %d-%d phase %d",
1256 ntohs(sat
->sat_addr
.s_net
), sat
->sat_addr
.s_node
,
1257 ntohs(nr
->nr_firstnet
), ntohs(nr
->nr_lastnet
), nr
->nr_phase
);
1258 if (flags
& IFF_POINTOPOINT
) {
1259 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1260 if (errno
== EADDRNOTAVAIL
)
1261 (void) memset(&ifr
.ifr_addr
, 0,
1262 sizeof(ifr
.ifr_addr
));
1264 warn("SIOCGIFDSTADDR");
1266 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1267 sat
= (struct sockaddr_at
*)&ifr
.ifr_dstaddr
;
1271 ntohs(sat
->sat_addr
.s_net
), sat
->sat_addr
.s_node
);
1273 if (flags
& IFF_BROADCAST
) {
1274 /* note RTAX_BRD overlap with IFF_POINTOPOINT */
1275 sat
= (struct sockaddr_at
*)&ifr
.ifr_broadaddr
;
1277 printf(" broadcast %d.%d", ntohs(sat
->sat_addr
.s_net
),
1278 sat
->sat_addr
.s_node
);
1287 struct sockaddr_ns
*sns
;
1291 if (errno
== EPROTONOSUPPORT
)
1295 (void) memset(&ifr
, 0, sizeof(ifr
));
1296 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1297 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1298 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1301 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1303 warn("SIOCGIFADDR");
1305 (void) strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
1306 sns
= (struct sockaddr_ns
*)&ifr
.ifr_addr
;
1307 printf("\tns %s ", ns_ntoa(sns
->sns_addr
));
1308 if (flags
& IFF_POINTOPOINT
) { /* by W. Nesheim@Cornell */
1309 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1310 if (errno
== EADDRNOTAVAIL
)
1311 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1313 warn("SIOCGIFDSTADDR");
1315 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1316 sns
= (struct sockaddr_ns
*)&ifr
.ifr_dstaddr
;
1317 printf("--> %s ", ns_ntoa(sns
->sns_addr
));
1326 struct sockaddr_iso
*siso
;
1330 if (errno
== EPROTONOSUPPORT
)
1334 (void) memset(&ifr
, 0, sizeof(ifr
));
1335 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1336 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1337 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1340 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1342 warn("SIOCGIFADDR");
1344 (void) strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
1345 siso
= (struct sockaddr_iso
*)&ifr
.ifr_addr
;
1346 printf("\tiso %s ", iso_ntoa(&siso
->siso_addr
));
1347 if (IoctlSocket(s
, SIOCGIFNETMASK
, (caddr_t
)&ifr
) < 0) {
1348 if (errno
== EADDRNOTAVAIL
)
1349 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1351 warn("SIOCGIFNETMASK");
1353 printf(" netmask %s ", iso_ntoa(&siso
->siso_addr
));
1355 if (flags
& IFF_POINTOPOINT
) {
1356 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1357 if (errno
== EADDRNOTAVAIL
)
1358 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1360 warn("SIOCGIFDSTADDR");
1362 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1363 siso
= (struct sockaddr_iso
*)&ifr
.ifr_addr
;
1364 printf("--> %s ", iso_ntoa(&siso
->siso_addr
));
1369 #endif /* INET_ONLY */
1371 #define SIN(x) ((struct sockaddr_in *) &(x))
1372 struct sockaddr_in
*sintab
[] = {
1373 SIN(ridreq
.ifr_addr
), SIN(addreq
.ifra_addr
),
1374 SIN(addreq
.ifra_mask
), SIN(addreq
.ifra_broadaddr
)};
1377 in_getaddr(s
, which
)
1381 struct sockaddr_in
*sin
= sintab
[which
];
1385 sin
->sin_len
= sizeof(*sin
);
1387 sin
->sin_family
= AF_INET
;
1389 if (inet_aton(s
, &sin
->sin_addr
) == 0) {
1390 if ((hp
= gethostbyname(s
)) != NULL
)
1391 (void) memcpy(&sin
->sin_addr
, hp
->h_addr
, hp
->h_length
);
1392 else if ((np
= getnetbyname(s
)) != NULL
)
1394 sin
->sin_addr
.s_addr
= inet_makeaddr(np
->n_net
, INADDR_ANY
);
1397 errx(1, "%s: bad value", s
);
1402 * Print a value a la the %b format of the kernel's printf
1413 if (bits
&& *bits
== 8)
1414 printf("%s=%o", s
, v
);
1416 printf("%s=%x", s
, v
);
1420 while ((i
= *bits
++) != 0) {
1421 if (v
& (1 << (i
-1))) {
1425 for (; (c
= *bits
) > 32; bits
++)
1428 for (; *bits
> 32; bits
++)
1438 at_getaddr(addr
, which
)
1442 struct sockaddr_at
*sat
= (struct sockaddr_at
*) &addreq
.ifra_addr
;
1445 sat
->sat_family
= AF_APPLETALK
;
1446 sat
->sat_len
= sizeof(*sat
);
1448 errx(1, "AppleTalk does not use netmasks\n");
1449 if (sscanf(addr
, "%u.%u", &net
, &node
) != 2
1450 || net
== 0 || net
> 0xffff || node
== 0 || node
> 0xfe)
1451 errx(1, "%s: illegal address", addr
);
1452 sat
->sat_addr
.s_net
= htons(net
);
1453 sat
->sat_addr
.s_node
= node
;
1457 setatrange(range
, d
)
1461 u_short first
= 123, last
= 123;
1463 if (sscanf(range
, "%hu-%hu", &first
, &last
) != 2
1464 || first
== 0 || first
> 0xffff
1465 || last
== 0 || last
> 0xffff || first
> last
)
1466 errx(1, "%s: illegal net range: %u-%u", range
, first
, last
);
1467 at_nr
.nr_firstnet
= htons(first
);
1468 at_nr
.nr_lastnet
= htons(last
);
1472 setatphase(phase
, d
)
1476 if (!strcmp(phase
, "1"))
1478 else if (!strcmp(phase
, "2"))
1481 errx(1, "%s: illegal phase", phase
);
1486 struct sockaddr_at
*sat
;
1488 if (at_nr
.nr_phase
== 0)
1489 at_nr
.nr_phase
= 2; /* Default phase 2 */
1490 if (at_nr
.nr_firstnet
== 0)
1491 at_nr
.nr_firstnet
= /* Default range of one */
1492 at_nr
.nr_lastnet
= sat
->sat_addr
.s_net
;
1493 printf("\tatalk %d.%d range %d-%d phase %d\n",
1494 ntohs(sat
->sat_addr
.s_net
), sat
->sat_addr
.s_node
,
1495 ntohs(at_nr
.nr_firstnet
), ntohs(at_nr
.nr_lastnet
), at_nr
.nr_phase
);
1496 if ((u_short
) ntohs(at_nr
.nr_firstnet
) >
1497 (u_short
) ntohs(sat
->sat_addr
.s_net
)
1498 || (u_short
) ntohs(at_nr
.nr_lastnet
) <
1499 (u_short
) ntohs(sat
->sat_addr
.s_net
))
1500 errx(1, "AppleTalk address is not in range");
1501 *((struct netrange
*) &sat
->sat_zero
) = at_nr
;
1504 #define SNS(x) ((struct sockaddr_ns *) &(x))
1505 struct sockaddr_ns
*snstab
[] = {
1506 SNS(ridreq
.ifr_addr
), SNS(addreq
.ifra_addr
),
1507 SNS(addreq
.ifra_mask
), SNS(addreq
.ifra_broadaddr
)};
1510 xns_getaddr(addr
, which
)
1514 struct sockaddr_ns
*sns
= snstab
[which
];
1516 sns
->sns_family
= AF_NS
;
1517 sns
->sns_len
= sizeof(*sns
);
1518 sns
->sns_addr
= ns_addr(addr
);
1520 puts("Attempt to set XNS netmask will be ineffectual");
1523 #define SISO(x) ((struct sockaddr_iso *) &(x))
1524 struct sockaddr_iso
*sisotab
[] = {
1525 SISO(ridreq
.ifr_addr
), SISO(iso_addreq
.ifra_addr
),
1526 SISO(iso_addreq
.ifra_mask
), SISO(iso_addreq
.ifra_dstaddr
)};
1529 iso_getaddr(addr
, which
)
1533 struct sockaddr_iso
*siso
= sisotab
[which
];
1534 siso
->siso_addr
= *iso_addr(addr
);
1536 if (which
== MASK
) {
1537 siso
->siso_len
= TSEL(siso
) - (caddr_t
)(siso
);
1538 siso
->siso_nlen
= 0;
1540 siso
->siso_len
= sizeof(*siso
);
1541 siso
->siso_family
= AF_ISO
;
1546 setsnpaoffset(val
, d
)
1550 iso_addreq
.ifra_snpaoffset
= atoi(val
);
1554 setnsellength(val
, d
)
1558 nsellength
= atoi(val
);
1560 errx(1, "Negative NSEL length is absurd");
1561 if (afp
== 0 || afp
->af_af
!= AF_ISO
)
1562 errx(1, "Setting NSEL length valid only for iso");
1567 struct sockaddr_iso
*s
;
1569 if (s
->siso_family
== 0)
1571 s
->siso_tlen
= nsellength
;
1577 fixnsel(sisotab
[RIDADDR
]);
1578 fixnsel(sisotab
[ADDR
]);
1579 fixnsel(sisotab
[DSTADDR
]);
1582 #endif /* INET_ONLY */
1588 "usage: ifconfig [ -m ] interface\n%s%s%s%s%s%s%s%s%s%s%s",
1589 "\t[ af [alias | -alias | delete] [ address [ dest_addr ] ] [ up ] [ down ] ",
1590 "[ netmask mask ] ]\n",
1593 "\t[ arp | -arp ]\n",
1594 #ifdef ENABLE_MEDIA_IOCTL
1595 "\t[ media mtype ]\n",
1596 "\t[ mediaopt mopts ]\n",
1597 "\t[ -mediaopt mopts ]\n",
1601 "\t[ link0 | -link0 ] [ link1 | -link1 ] [ link2 | -link2 ]\n",
1602 " ifconfig -a [ -m ] [ -d ] [ -u ] [ af ]\n",
1603 " ifconfig -l [ -d ] [ -u ]\n");