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 *));
275 #if defined(__AROS__)
276 if (!(SocketBase
= OpenLibrary(socket_name
, SOCKET_VERSION
)))
280 if (!(MiamiBase
= OpenLibrary("miami.library", 0)))
286 /* Parse command-line options */
288 while ((ch
= getopt(argc
, argv
, "adlmu")) != -1) {
319 * -l means "list all interfaces", and is mutally exclusive with
320 * all other flags/commands.
322 * -a means "print status of all interfaces".
324 if (lflag
&& (aflag
|| mflag
|| argc
))
326 if (aflag
|| lflag
) {
329 else if (argc
== 1) {
330 afp
= lookup_af(argv
[0]);
335 af
= ifr
.ifr_addr
.sa_family
= afp
->af_af
;
337 af
= ifr
.ifr_addr
.sa_family
= afs
[0].af_af
;
342 /* Make sure there's an interface name. */
345 (void) strncpy(name
, argv
[0], sizeof(name
));
348 /* Check for address family. */
351 afp
= lookup_af(argv
[0]);
360 af
= ifr
.ifr_addr
.sa_family
= afp
->af_af
;
362 /* Get information about the interface. */
363 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
364 if (getinfo(&ifr
) < 0)
367 /* No more arguments means interface status. */
373 /* Process commands. */
377 for (p
= cmds
; p
->c_name
; p
++)
378 if (strcmp(argv
[0], p
->c_name
) == 0)
380 if (p
->c_name
== 0 && setaddr
)
381 p
++; /* got src, do dst */
383 if (p
->c_parameter
== NEXTARG
) {
385 errx(1, "'%s' requires argument",
387 (*p
->c_func
)(argv
[1], 0);
390 (*p
->c_func
)(argv
[0], p
->c_parameter
);
400 if (af
== AF_APPLETALK
)
401 checkatrange((struct sockaddr_at
*) &addreq
.ifra_addr
);
403 if (setipdst
&& af
==AF_NS
) {
405 int size
= sizeof(rq
);
407 rq
.rq_ns
= addreq
.ifra_addr
;
408 rq
.rq_ip
= addreq
.ifra_dstaddr
;
410 if (setsockopt(s
, 0, SO_NSIP_ROUTE
, &rq
, size
) < 0)
411 warn("encapsulation routing");
414 #endif /* INET_ONLY */
418 (void) strncpy(afp
->af_ridreq
, name
, sizeof ifr
.ifr_name
);
419 if ((ret
= IoctlSocket(s
, afp
->af_difaddr
, afp
->af_ridreq
)) < 0) {
420 if (errno
== EADDRNOTAVAIL
&& (doalias
>= 0)) {
421 /* means no previous address for interface */
427 (void) strncpy(afp
->af_addreq
, name
, sizeof ifr
.ifr_name
);
428 if (IoctlSocket(s
, afp
->af_aifaddr
, afp
->af_addreq
) < 0)
431 if (reset_if_flags
&& IoctlSocket(s
, SIOCSIFFLAGS
, (caddr_t
)&ifr
) < 0)
432 err(1, "SIOCSIFFLAGS");
442 for (a
= afs
; a
->af_name
!= NULL
; a
++)
443 if (strcmp(a
->af_name
, cp
) == 0)
458 s
= socket(naf
, SOCK_DGRAM
, 0);
473 if (IoctlSocket(s
, SIOCGIFFLAGS
, (caddr_t
)ifr
) < 0) {
474 #if !defined(__AROS__)
475 warn("SIOCGIFFLAGS %s", ifr
->ifr_name
);
479 flags
= ifr
->ifr_flags
;
480 if (IoctlSocket(s
, SIOCGIFMETRIC
, (caddr_t
)ifr
) < 0) {
481 #if !defined(__AROS__)
482 warn("SIOCGIFMETRIC %s", ifr
->ifr_name
);
486 metric
= ifr
->ifr_metric
;
487 if (IoctlSocket(s
, SIOCGIFMTU
, (caddr_t
)ifr
) < 0)
498 const struct sockaddr_dl
*sdl
= NULL
;
500 struct ifreq ifreq
, *ifr
;
503 ifc
.ifc_len
= sizeof(inbuf
);
508 if (IoctlSocket(s
, SIOCGIFCONF
, &ifc
) < 0)
509 err(1, "SIOCGIFCONF");
511 ifreq
.ifr_name
[0] = '\0';
512 for (i
= 0, idx
= 0; i
< ifc
.ifc_len
; ) {
513 ifr
= (struct ifreq
*)((caddr_t
)ifc
.ifc_req
+ i
);
514 i
+= sizeof(ifr
->ifr_name
) +
515 (ifr
->ifr_addr
.sa_len
> sizeof(struct sockaddr
)
516 ? ifr
->ifr_addr
.sa_len
517 : sizeof(struct sockaddr
));
518 if (ifr
->ifr_addr
.sa_family
== AF_LINK
)
519 sdl
= (const struct sockaddr_dl
*) &ifr
->ifr_addr
;
520 if (!strncmp(ifreq
.ifr_name
, ifr
->ifr_name
,
521 sizeof(ifr
->ifr_name
)))
523 (void) strncpy(name
, ifr
->ifr_name
, sizeof(ifr
->ifr_name
));
526 if (getinfo(&ifreq
) < 0)
528 if (dflag
&& (flags
& IFF_UP
) != 0)
530 if (uflag
&& (flags
& IFF_UP
) == 0)
535 * Are we just listing the interfaces?
547 status(LLADDR(sdl
), sdl
->sdl_alen
);
562 setifaddr(addr
, param
)
567 * Delay the IoctlSocket to set the interface addr until flags are all set.
568 * The address interpretation may depend on the flags,
569 * and the flags may change when the address is set.
576 (*afp
->af_getaddr
)(addr
, (doalias
>= 0 ? ADDR
: RIDADDR
));
580 setifnetmask(addr
, d
)
584 (*afp
->af_getaddr
)(addr
, MASK
);
588 setifbroadaddr(addr
, d
)
592 (*afp
->af_getaddr
)(addr
, DSTADDR
);
600 in_getaddr(addr
, DSTADDR
);
606 #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
609 notealias(addr
, param
)
613 if (setaddr
&& doalias
== 0 && param
< 0)
614 (void) memcpy(rqtosa(af_ridreq
), rqtosa(af_addreq
),
615 rqtosa(af_addreq
)->sa_len
);
626 notrailers(vname
, value
)
630 puts("Note: trailers are no longer sent, but always received");
635 setifdstaddr(addr
, param
)
639 (*afp
->af_getaddr
)(addr
, DSTADDR
);
643 setifflags(vname
, value
)
647 if (IoctlSocket(s
, SIOCGIFFLAGS
, (caddr_t
)&ifr
) < 0)
648 err(1, "SIOCGIFFLAGS");
649 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
650 flags
= ifr
.ifr_flags
;
657 ifr
.ifr_flags
= flags
;
658 /* if (IoctlSocket(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
659 err(1, "SIOCSIFFLAGS");*/
669 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
670 ifr
.ifr_metric
= atoi(val
);
671 if (IoctlSocket(s
, SIOCSIFMETRIC
, (caddr_t
)&ifr
) < 0)
672 warn("SIOCSIFMETRIC");
680 (void)strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
681 ifr
.ifr_mtu
= atoi(val
);
682 if (IoctlSocket(s
, SIOCSIFMTU
, (caddr_t
)&ifr
) < 0)
685 #ifdef ENABLE_MEDIA_IOCTL
691 struct ifmediareq ifmr
;
692 int first_type
, subtype
;
694 (void) memset(&ifmr
, 0, sizeof(ifmr
));
695 (void) strncpy(ifmr
.ifm_name
, name
, sizeof(ifmr
.ifm_name
));
698 ifmr
.ifm_ulist
= &first_type
;
699 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0) {
701 * If we get E2BIG, the kernel is telling us
702 * that there are more, so we can ignore it.
705 err(1, "SIOCGIFMEDIA");
708 if (ifmr
.ifm_count
== 0)
709 errx(1, "%s: no media types?", name
);
712 * We are primarily concerned with the top-level type.
713 * However, "current" may be only IFM_NONE, so we just look
714 * for the top-level type in the first "supported type"
717 * (I'm assuming that all supported media types for a given
718 * interface will be the same top-level type..)
720 subtype
= get_media_subtype(IFM_TYPE(first_type
), val
);
722 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
723 ifr
.ifr_media
= (ifmr
.ifm_current
& ~(IFM_NMASK
|IFM_TMASK
)) |
724 IFM_TYPE(first_type
) | subtype
;
726 if (IoctlSocket(s
, SIOCSIFMEDIA
, (caddr_t
)&ifr
) < 0)
727 err(1, "SIOCSIFMEDIA");
740 unsetmediaopt(val
, d
)
749 domediaopt(val
, clear
)
753 struct ifmediareq ifmr
;
754 int *mwords
, options
;
756 (void) memset(&ifmr
, 0, sizeof(ifmr
));
757 (void) strncpy(ifmr
.ifm_name
, name
, sizeof(ifmr
.ifm_name
));
760 * We must go through the motions of reading all
761 * supported media because we need to know both
762 * the current media type and the top-level type.
765 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0)
766 err(1, "SIOCGIFMEDIA");
768 if (ifmr
.ifm_count
== 0)
769 errx(1, "%s: no media types?", name
);
771 mwords
= (int *)malloc(ifmr
.ifm_count
* sizeof(int));
775 ifmr
.ifm_ulist
= mwords
;
776 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0)
777 err(1, "SIOCGIFMEDIA");
779 options
= get_media_options(IFM_TYPE(mwords
[0]), val
);
783 strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
784 ifr
.ifr_media
= ifmr
.ifm_current
;
786 ifr
.ifr_media
&= ~options
;
788 ifr
.ifr_media
|= options
;
790 if (IoctlSocket(s
, SIOCSIFMEDIA
, (caddr_t
)&ifr
) < 0)
791 err(1, "SIOCSIFMEDIA");
794 /**********************************************************************
795 * A good chunk of this is duplicated from sys/net/ifmedia.c
796 **********************************************************************/
798 struct ifmedia_description ifm_type_descriptions
[] =
799 IFM_TYPE_DESCRIPTIONS
;
801 struct ifmedia_description ifm_subtype_ethernet_descriptions
[] =
802 IFM_SUBTYPE_ETHERNET_DESCRIPTIONS
;
804 struct ifmedia_description ifm_subtype_ethernet_aliases
[] =
805 IFM_SUBTYPE_ETHERNET_ALIASES
;
807 struct ifmedia_description ifm_subtype_ethernet_option_descriptions
[] =
808 IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS
;
810 struct ifmedia_description ifm_subtype_tokenring_descriptions
[] =
811 IFM_SUBTYPE_TOKENRING_DESCRIPTIONS
;
813 struct ifmedia_description ifm_subtype_tokenring_aliases
[] =
814 IFM_SUBTYPE_TOKENRING_ALIASES
;
816 struct ifmedia_description ifm_subtype_tokenring_option_descriptions
[] =
817 IFM_SUBTYPE_TOKENRING_OPTION_DESCRIPTIONS
;
819 struct ifmedia_description ifm_subtype_fddi_descriptions
[] =
820 IFM_SUBTYPE_FDDI_DESCRIPTIONS
;
822 struct ifmedia_description ifm_subtype_fddi_aliases
[] =
823 IFM_SUBTYPE_FDDI_ALIASES
;
825 struct ifmedia_description ifm_subtype_fddi_option_descriptions
[] =
826 IFM_SUBTYPE_FDDI_OPTION_DESCRIPTIONS
;
828 struct ifmedia_description ifm_subtype_shared_descriptions
[] =
829 IFM_SUBTYPE_SHARED_DESCRIPTIONS
;
831 struct ifmedia_description ifm_subtype_shared_aliases
[] =
832 IFM_SUBTYPE_SHARED_ALIASES
;
834 struct ifmedia_description ifm_shared_option_descriptions
[] =
835 IFM_SHARED_OPTION_DESCRIPTIONS
;
837 struct ifmedia_type_to_subtype
{
839 struct ifmedia_description
*desc
;
843 struct ifmedia_description
*desc
;
848 /* must be in the same order as IFM_TYPE_DESCRIPTIONS */
849 struct ifmedia_type_to_subtype ifmedia_types_to_subtypes
[] = {
852 { &ifm_subtype_shared_descriptions
[0], 0 },
853 { &ifm_subtype_shared_aliases
[0], 1 },
854 { &ifm_subtype_ethernet_descriptions
[0], 0 },
855 { &ifm_subtype_ethernet_aliases
[0], 1 },
859 { &ifm_shared_option_descriptions
[0], 0 },
860 { &ifm_subtype_ethernet_option_descriptions
[0], 1 },
866 { &ifm_subtype_shared_descriptions
[0], 0 },
867 { &ifm_subtype_shared_aliases
[0], 1 },
868 { &ifm_subtype_tokenring_descriptions
[0], 0 },
869 { &ifm_subtype_tokenring_aliases
[0], 1 },
873 { &ifm_shared_option_descriptions
[0], 0 },
874 { &ifm_subtype_tokenring_option_descriptions
[0], 1 },
880 { &ifm_subtype_shared_descriptions
[0], 0 },
881 { &ifm_subtype_shared_aliases
[0], 1 },
882 { &ifm_subtype_fddi_descriptions
[0], 0 },
883 { &ifm_subtype_fddi_aliases
[0], 1 },
887 { &ifm_shared_option_descriptions
[0], 0 },
888 { &ifm_subtype_fddi_option_descriptions
[0], 1 },
895 get_media_subtype(type
, val
)
899 struct ifmedia_description
*desc
;
900 struct ifmedia_type_to_subtype
*ttos
;
903 /* Find the top-level interface type. */
904 for (desc
= ifm_type_descriptions
, ttos
= ifmedia_types_to_subtypes
;
905 desc
->ifmt_string
!= NULL
; desc
++, ttos
++)
906 if (type
== desc
->ifmt_word
)
908 if (desc
->ifmt_string
== NULL
)
909 errx(1, "unknown media type 0x%x", type
);
911 for (i
= 0; ttos
->subtypes
[i
].desc
!= NULL
; i
++) {
912 rval
= lookup_media_word(ttos
->subtypes
[i
].desc
, val
);
916 errx(1, "unknown media subtype: %s", val
);
921 get_media_options(type
, val
)
925 struct ifmedia_description
*desc
;
926 struct ifmedia_type_to_subtype
*ttos
;
928 int option
= 0, i
, rval
= 0;
930 /* We muck with the string, so copy it. */
931 optlist
= strdup(val
);
936 /* Find the top-level interface type. */
937 for (desc
= ifm_type_descriptions
, ttos
= ifmedia_types_to_subtypes
;
938 desc
->ifmt_string
!= NULL
; desc
++, ttos
++)
939 if (type
== desc
->ifmt_word
)
941 if (desc
->ifmt_string
== NULL
)
942 errx(1, "unknown media type 0x%x", type
);
945 * Look up the options in the user-provided comma-separated
948 for (; (val
= strtok(val
, ",")) != NULL
; val
= NULL
) {
949 for (i
= 0; ttos
->options
[i
].desc
!= NULL
; i
++) {
950 option
= lookup_media_word(ttos
->options
[i
].desc
, val
);
955 errx(1, "unknown option: %s", val
);
964 lookup_media_word(desc
, val
)
965 struct ifmedia_description
*desc
;
969 for (; desc
->ifmt_string
!= NULL
; desc
++)
970 if (strcasecmp(desc
->ifmt_string
, val
) == 0)
971 return (desc
->ifmt_word
);
977 print_media_word(ifmw
)
980 struct ifmedia_description
*desc
;
981 struct ifmedia_type_to_subtype
*ttos
;
982 int seen_option
= 0, i
;
984 /* Find the top-level interface type. */
985 for (desc
= ifm_type_descriptions
, ttos
= ifmedia_types_to_subtypes
;
986 desc
->ifmt_string
!= NULL
; desc
++, ttos
++)
987 if (IFM_TYPE(ifmw
) == desc
->ifmt_word
)
989 if (desc
->ifmt_string
== NULL
) {
990 printf("<unknown type>");
995 * Don't print the top-level type; it's not like we can
996 * change it, or anything.
1000 for (i
= 0; ttos
->subtypes
[i
].desc
!= NULL
; i
++) {
1001 if (ttos
->subtypes
[i
].alias
)
1003 for (desc
= ttos
->subtypes
[i
].desc
;
1004 desc
->ifmt_string
!= NULL
; desc
++) {
1005 if (IFM_SUBTYPE(ifmw
) == desc
->ifmt_word
)
1010 /* Falling to here means unknown subtype. */
1011 printf("<unknown subtype>");
1015 printf("%s", desc
->ifmt_string
);
1018 for (i
= 0; ttos
->options
[i
].desc
!= NULL
; i
++) {
1019 if (ttos
->options
[i
].alias
)
1021 for (desc
= ttos
->options
[i
].desc
;
1022 desc
->ifmt_string
!= NULL
; desc
++) {
1023 if (ifmw
& desc
->ifmt_word
) {
1024 if (seen_option
== 0)
1026 printf("%s%s", seen_option
++ ? "," : "",
1031 printf("%s", seen_option
? ">" : "");
1034 /**********************************************************************
1036 **********************************************************************/
1039 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
1040 \11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST"
1043 * Print the status of the interface. If an address family was
1044 * specified, show it and it only; otherwise, show them all.
1051 struct afswtch
*p
= afp
;
1052 #ifdef ENABLE_MEDIA_IOCTL
1053 struct ifmediareq ifmr
;
1058 printf("%s: ", name
);
1059 printb("flags", flags
, IFFBITS
);
1061 printf(" metric %d", metric
);
1063 printf(" mtu %d", mtu
);
1065 if (ap
&& alen
> 0) {
1066 printf("\taddress:");
1067 for (i
= 0; i
< alen
; i
++, ap
++)
1068 printf("%c%02x", i
> 0 ? ':' : ' ', *ap
);
1071 #ifdef ENABLE_MEDIA_IOCTL
1072 (void) memset(&ifmr
, 0, sizeof(ifmr
));
1073 (void) strncpy(ifmr
.ifm_name
, name
, sizeof(ifmr
.ifm_name
));
1075 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0) {
1077 * Interface doesn't support SIOC{G,S}IFMEDIA.
1082 if (ifmr
.ifm_count
== 0) {
1083 warnx("%s: no media types?", name
);
1087 media_list
= (int *)malloc(ifmr
.ifm_count
* sizeof(int));
1088 if (media_list
== NULL
)
1090 ifmr
.ifm_ulist
= media_list
;
1092 if (IoctlSocket(s
, SIOCGIFMEDIA
, (caddr_t
)&ifmr
) < 0)
1093 err(1, "SIOCGIFMEDIA");
1095 printf("\tmedia: ");
1096 print_media_word(ifmr
.ifm_current
);
1097 if (ifmr
.ifm_active
!= ifmr
.ifm_current
) {
1100 print_media_word(ifmr
.ifm_active
);
1104 if (ifmr
.ifm_status
& IFM_AVALID
) {
1105 printf(" status: ");
1106 switch (IFM_TYPE(ifmr
.ifm_active
)) {
1108 if (ifmr
.ifm_status
& IFM_ACTIVE
)
1111 printf("no carrier");
1116 if (ifmr
.ifm_status
& IFM_ACTIVE
)
1127 printf("\tsupported media:");
1128 for (i
= 0; i
< ifmr
.ifm_count
; i
++) {
1130 print_media_word(media_list
[i
]);
1138 if ((p
= afp
) != NULL
) {
1140 } else for (p
= afs
; p
->af_name
; p
++) {
1141 ifr
.ifr_addr
.sa_family
= p
->af_af
;
1150 struct sockaddr_in
*sin
;
1154 if (errno
== EPROTONOSUPPORT
)
1158 (void) memset(&ifr
, 0, sizeof(ifr
));
1159 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1160 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1161 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1164 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1166 warn("SIOCGIFADDR");
1168 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1169 sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
1170 printf("\tinet %s ", inet_ntoa(sin
->sin_addr
));
1171 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1172 if (IoctlSocket(s
, SIOCGIFNETMASK
, (caddr_t
)&ifr
) < 0) {
1173 if (errno
!= EADDRNOTAVAIL
)
1174 warn("SIOCGIFNETMASK");
1175 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1178 ((struct sockaddr_in
*)&ifr
.ifr_addr
)->sin_addr
;
1179 if (flags
& IFF_POINTOPOINT
) {
1180 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1181 if (errno
== EADDRNOTAVAIL
)
1182 (void) memset(&ifr
.ifr_addr
, 0,
1183 sizeof(ifr
.ifr_addr
));
1185 warn("SIOCGIFDSTADDR");
1187 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1188 sin
= (struct sockaddr_in
*)&ifr
.ifr_dstaddr
;
1189 printf("--> %s ", inet_ntoa(sin
->sin_addr
));
1191 printf("netmask 0x%x ", ntohl(netmask
.sin_addr
.s_addr
));
1192 if (flags
& IFF_BROADCAST
) {
1193 if (IoctlSocket(s
, SIOCGIFBRDADDR
, (caddr_t
)&ifr
) < 0) {
1194 if (errno
== EADDRNOTAVAIL
)
1195 (void) memset(&ifr
.ifr_addr
, 0,
1196 sizeof(ifr
.ifr_addr
));
1198 warn("SIOCGIFBRDADDR");
1200 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1201 sin
= (struct sockaddr_in
*)&ifr
.ifr_addr
;
1202 if (sin
->sin_addr
.s_addr
!= 0)
1203 printf("broadcast %s", inet_ntoa(sin
->sin_addr
));
1214 struct sockaddr_at
*sat
, null_sat
;
1215 struct netrange
*nr
;
1217 getsock(AF_APPLETALK
);
1219 if (errno
== EPROTONOSUPPORT
)
1223 (void) memset(&ifr
, 0, sizeof(ifr
));
1224 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1225 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1226 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1229 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1231 warn("SIOCGIFADDR");
1233 (void) strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
1234 sat
= (struct sockaddr_at
*)&ifr
.ifr_addr
;
1236 (void) memset(&null_sat
, 0, sizeof(null_sat
));
1238 nr
= (struct netrange
*) &sat
->sat_zero
;
1239 printf("\tatalk %d.%d range %d-%d phase %d",
1240 ntohs(sat
->sat_addr
.s_net
), sat
->sat_addr
.s_node
,
1241 ntohs(nr
->nr_firstnet
), ntohs(nr
->nr_lastnet
), nr
->nr_phase
);
1242 if (flags
& IFF_POINTOPOINT
) {
1243 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1244 if (errno
== EADDRNOTAVAIL
)
1245 (void) memset(&ifr
.ifr_addr
, 0,
1246 sizeof(ifr
.ifr_addr
));
1248 warn("SIOCGIFDSTADDR");
1250 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1251 sat
= (struct sockaddr_at
*)&ifr
.ifr_dstaddr
;
1255 ntohs(sat
->sat_addr
.s_net
), sat
->sat_addr
.s_node
);
1257 if (flags
& IFF_BROADCAST
) {
1258 /* note RTAX_BRD overlap with IFF_POINTOPOINT */
1259 sat
= (struct sockaddr_at
*)&ifr
.ifr_broadaddr
;
1261 printf(" broadcast %d.%d", ntohs(sat
->sat_addr
.s_net
),
1262 sat
->sat_addr
.s_node
);
1271 struct sockaddr_ns
*sns
;
1275 if (errno
== EPROTONOSUPPORT
)
1279 (void) memset(&ifr
, 0, sizeof(ifr
));
1280 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1281 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1282 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1285 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1287 warn("SIOCGIFADDR");
1289 (void) strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
1290 sns
= (struct sockaddr_ns
*)&ifr
.ifr_addr
;
1291 printf("\tns %s ", ns_ntoa(sns
->sns_addr
));
1292 if (flags
& IFF_POINTOPOINT
) { /* by W. Nesheim@Cornell */
1293 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1294 if (errno
== EADDRNOTAVAIL
)
1295 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1297 warn("SIOCGIFDSTADDR");
1299 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1300 sns
= (struct sockaddr_ns
*)&ifr
.ifr_dstaddr
;
1301 printf("--> %s ", ns_ntoa(sns
->sns_addr
));
1310 struct sockaddr_iso
*siso
;
1314 if (errno
== EPROTONOSUPPORT
)
1318 (void) memset(&ifr
, 0, sizeof(ifr
));
1319 (void) strncpy(ifr
.ifr_name
, name
, sizeof(ifr
.ifr_name
));
1320 if (IoctlSocket(s
, SIOCGIFADDR
, (caddr_t
)&ifr
) < 0) {
1321 if (errno
== EADDRNOTAVAIL
|| errno
== EAFNOSUPPORT
) {
1324 (void) memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1326 warn("SIOCGIFADDR");
1328 (void) strncpy(ifr
.ifr_name
, name
, sizeof ifr
.ifr_name
);
1329 siso
= (struct sockaddr_iso
*)&ifr
.ifr_addr
;
1330 printf("\tiso %s ", iso_ntoa(&siso
->siso_addr
));
1331 if (IoctlSocket(s
, SIOCGIFNETMASK
, (caddr_t
)&ifr
) < 0) {
1332 if (errno
== EADDRNOTAVAIL
)
1333 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1335 warn("SIOCGIFNETMASK");
1337 printf(" netmask %s ", iso_ntoa(&siso
->siso_addr
));
1339 if (flags
& IFF_POINTOPOINT
) {
1340 if (IoctlSocket(s
, SIOCGIFDSTADDR
, (caddr_t
)&ifr
) < 0) {
1341 if (errno
== EADDRNOTAVAIL
)
1342 memset(&ifr
.ifr_addr
, 0, sizeof(ifr
.ifr_addr
));
1344 warn("SIOCGIFDSTADDR");
1346 (void) strncpy(ifr
.ifr_name
, name
, sizeof (ifr
.ifr_name
));
1347 siso
= (struct sockaddr_iso
*)&ifr
.ifr_addr
;
1348 printf("--> %s ", iso_ntoa(&siso
->siso_addr
));
1353 #endif /* INET_ONLY */
1355 #define SIN(x) ((struct sockaddr_in *) &(x))
1356 struct sockaddr_in
*sintab
[] = {
1357 SIN(ridreq
.ifr_addr
), SIN(addreq
.ifra_addr
),
1358 SIN(addreq
.ifra_mask
), SIN(addreq
.ifra_broadaddr
)};
1361 in_getaddr(s
, which
)
1365 struct sockaddr_in
*sin
= sintab
[which
];
1369 sin
->sin_len
= sizeof(*sin
);
1371 sin
->sin_family
= AF_INET
;
1373 if (inet_aton(s
, &sin
->sin_addr
) == 0) {
1374 if ((hp
= gethostbyname(s
)) != NULL
)
1375 (void) memcpy(&sin
->sin_addr
, hp
->h_addr
, hp
->h_length
);
1376 else if ((np
= getnetbyname(s
)) != NULL
)
1378 sin
->sin_addr
.s_addr
= inet_makeaddr(np
->n_net
, INADDR_ANY
);
1381 errx(1, "%s: bad value", s
);
1386 * Print a value a la the %b format of the kernel's printf
1397 if (bits
&& *bits
== 8)
1398 printf("%s=%o", s
, v
);
1400 printf("%s=%x", s
, v
);
1404 while ((i
= *bits
++) != 0) {
1405 if (v
& (1 << (i
-1))) {
1409 for (; (c
= *bits
) > 32; bits
++)
1412 for (; *bits
> 32; bits
++)
1422 at_getaddr(addr
, which
)
1426 struct sockaddr_at
*sat
= (struct sockaddr_at
*) &addreq
.ifra_addr
;
1429 sat
->sat_family
= AF_APPLETALK
;
1430 sat
->sat_len
= sizeof(*sat
);
1432 errx(1, "AppleTalk does not use netmasks\n");
1433 if (sscanf(addr
, "%u.%u", &net
, &node
) != 2
1434 || net
== 0 || net
> 0xffff || node
== 0 || node
> 0xfe)
1435 errx(1, "%s: illegal address", addr
);
1436 sat
->sat_addr
.s_net
= htons(net
);
1437 sat
->sat_addr
.s_node
= node
;
1441 setatrange(range
, d
)
1445 u_short first
= 123, last
= 123;
1447 if (sscanf(range
, "%hu-%hu", &first
, &last
) != 2
1448 || first
== 0 || first
> 0xffff
1449 || last
== 0 || last
> 0xffff || first
> last
)
1450 errx(1, "%s: illegal net range: %u-%u", range
, first
, last
);
1451 at_nr
.nr_firstnet
= htons(first
);
1452 at_nr
.nr_lastnet
= htons(last
);
1456 setatphase(phase
, d
)
1460 if (!strcmp(phase
, "1"))
1462 else if (!strcmp(phase
, "2"))
1465 errx(1, "%s: illegal phase", phase
);
1470 struct sockaddr_at
*sat
;
1472 if (at_nr
.nr_phase
== 0)
1473 at_nr
.nr_phase
= 2; /* Default phase 2 */
1474 if (at_nr
.nr_firstnet
== 0)
1475 at_nr
.nr_firstnet
= /* Default range of one */
1476 at_nr
.nr_lastnet
= sat
->sat_addr
.s_net
;
1477 printf("\tatalk %d.%d range %d-%d phase %d\n",
1478 ntohs(sat
->sat_addr
.s_net
), sat
->sat_addr
.s_node
,
1479 ntohs(at_nr
.nr_firstnet
), ntohs(at_nr
.nr_lastnet
), at_nr
.nr_phase
);
1480 if ((u_short
) ntohs(at_nr
.nr_firstnet
) >
1481 (u_short
) ntohs(sat
->sat_addr
.s_net
)
1482 || (u_short
) ntohs(at_nr
.nr_lastnet
) <
1483 (u_short
) ntohs(sat
->sat_addr
.s_net
))
1484 errx(1, "AppleTalk address is not in range");
1485 *((struct netrange
*) &sat
->sat_zero
) = at_nr
;
1488 #define SNS(x) ((struct sockaddr_ns *) &(x))
1489 struct sockaddr_ns
*snstab
[] = {
1490 SNS(ridreq
.ifr_addr
), SNS(addreq
.ifra_addr
),
1491 SNS(addreq
.ifra_mask
), SNS(addreq
.ifra_broadaddr
)};
1494 xns_getaddr(addr
, which
)
1498 struct sockaddr_ns
*sns
= snstab
[which
];
1500 sns
->sns_family
= AF_NS
;
1501 sns
->sns_len
= sizeof(*sns
);
1502 sns
->sns_addr
= ns_addr(addr
);
1504 puts("Attempt to set XNS netmask will be ineffectual");
1507 #define SISO(x) ((struct sockaddr_iso *) &(x))
1508 struct sockaddr_iso
*sisotab
[] = {
1509 SISO(ridreq
.ifr_addr
), SISO(iso_addreq
.ifra_addr
),
1510 SISO(iso_addreq
.ifra_mask
), SISO(iso_addreq
.ifra_dstaddr
)};
1513 iso_getaddr(addr
, which
)
1517 struct sockaddr_iso
*siso
= sisotab
[which
];
1518 siso
->siso_addr
= *iso_addr(addr
);
1520 if (which
== MASK
) {
1521 siso
->siso_len
= TSEL(siso
) - (caddr_t
)(siso
);
1522 siso
->siso_nlen
= 0;
1524 siso
->siso_len
= sizeof(*siso
);
1525 siso
->siso_family
= AF_ISO
;
1530 setsnpaoffset(val
, d
)
1534 iso_addreq
.ifra_snpaoffset
= atoi(val
);
1538 setnsellength(val
, d
)
1542 nsellength
= atoi(val
);
1544 errx(1, "Negative NSEL length is absurd");
1545 if (afp
== 0 || afp
->af_af
!= AF_ISO
)
1546 errx(1, "Setting NSEL length valid only for iso");
1551 struct sockaddr_iso
*s
;
1553 if (s
->siso_family
== 0)
1555 s
->siso_tlen
= nsellength
;
1561 fixnsel(sisotab
[RIDADDR
]);
1562 fixnsel(sisotab
[ADDR
]);
1563 fixnsel(sisotab
[DSTADDR
]);
1566 #endif /* INET_ONLY */
1571 #warning "TODO: NicJA - AROS Should also display usage instructions"
1572 #if !defined(__AROS__)
1574 "usage: ifconfig [ -m ] interface\n%s%s%s%s%s%s%s%s%s%s%s",
1575 "\t[ af [alias | -alias | delete] [ address [ dest_addr ] ] [ up ] [ down ] ",
1576 "[ netmask mask ] ]\n",
1579 "\t[ arp | -arp ]\n",
1580 #ifdef ENABLE_MEDIA_IOCTL
1581 "\t[ media mtype ]\n",
1582 "\t[ mediaopt mopts ]\n",
1583 "\t[ -mediaopt mopts ]\n",
1587 "\t[ link0 | -link0 ] [ link1 | -link1 ] [ link2 | -link2 ]\n",
1588 " ifconfig -a [ -m ] [ -d ] [ -u ] [ af ]\n",
1589 " ifconfig -l [ -d ] [ -u ]\n");