Check for SYS/GL during library init. Reason is that
[AROS.git] / workbench / network / common / C / ifconfig.c
blob40e7ef0293be212f79f5c1067e7261ee86d951eb
1 /*
2 * Copyright (C) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
3 * Helsinki University of Technology, Finland.
4 * All rights reserved.
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,
20 * MA 02111-1307, USA.
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
30 * are met:
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
54 * SUCH DAMAGE.
57 #define INET_ONLY
59 #include <dos/dos.h>
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>
68 #include <net/if.h>
69 #include <net/if_dl.h>
70 #ifdef ENABLE_MEDIA_IOCTL
71 #include <net/if_media.h>
72 #endif
73 #include <netinet/in.h>
74 #include <arpa/inet.h>
75 #ifdef ENABLE_APPLETALK
76 #include <netatalk/at.h>
77 #endif
78 #ifdef NS
79 #define NSIP
80 #include <netns/ns.h>
81 #include <netns/ns_if.h>
82 #endif
83 #include <netdb.h>
85 #define EON
86 #ifdef ISO
87 #include <netiso/iso.h>
88 #include <netiso/iso_var.h>
89 #endif
90 #if !defined(__AROS__)
91 #include <sys/protosw.h>
92 #endif
94 #include <ctype.h>
95 #if !defined(__AROS__)
96 #include <err.h>
97 #else
98 #define err(a,b)
99 #define errx(a,b,c)
100 #define warn(a)
101 #define inet_makeaddr(a,b) Inet_MakeAddr(a,b)
102 #endif
103 #include <errno.h>
104 #include <stdio.h>
105 #include <stdlib.h>
106 #include <string.h>
107 #include <unistd.h>
108 #include <proto/miami.h>
109 #include <proto/socket.h>
111 #if defined(__AROS__)
112 struct Library *SocketBase;
113 struct Library *MiamiBase;
114 #endif
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)));
122 #ifdef ISO
123 struct iso_aliasreq iso_addreq;
124 #endif
125 struct sockaddr_in netmask;
126 #ifdef ENABLE_APPLETALK
127 struct netrange at_nr; /* AppleTalk net range */
128 #endif
129 char name[30];
130 int flags, metric, mtu, setaddr, setipdst, doalias;
131 int clearaddr, s;
132 int newaddr = -1;
133 int nsellength = 1;
134 int af;
135 int dflag, mflag, lflag, uflag;
136 int reset_if_flags;
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 *));
154 #endif
155 void setmedia __P((char *, int));
156 void setmediaopt __P((char *, int));
157 void unsetmediaopt __P((char *, int));
158 #ifdef ISO
159 void fixnsel __P((struct sockaddr_iso *));
160 #endif
161 int main __P((int, char *[]));
163 #define NEXTARG 0xffffff
165 struct cmd {
166 char *c_name;
167 int c_parameter; /* NEXTARG means next argv */
168 void (*c_func) __P((char *, int));
169 } cmds[] = {
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 },
181 #ifdef notdef
182 #define EN_SWABIPS 0x1000
183 { "swabips", EN_SWABIPS, setifflags },
184 { "-swabips", -EN_SWABIPS, setifflags },
185 #endif
186 { "netmask", NEXTARG, setifnetmask },
187 { "metric", NEXTARG, setifmetric },
188 { "mtu", NEXTARG, setifmtu },
189 { "broadcast", NEXTARG, setifbroadaddr },
190 { "ipdst", NEXTARG, setifipdst },
191 #ifndef INET_ONLY
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 },
207 #endif
208 { 0, 0, setifaddr },
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));
225 #endif
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 */
240 struct afswtch {
241 char *af_name;
242 short af_af;
243 void (*af_status) __P((int));
244 void (*af_getaddr) __P((char *, int));
245 u_long af_difaddr;
246 u_long af_aifaddr;
247 caddr_t af_ridreq;
248 caddr_t af_addreq;
249 } afs[] = {
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 */
261 { 0, 0, 0, 0 }
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);
273 MiamiBase = NULL;
275 if (SocketBase != NULL)
277 CloseLibrary(SocketBase);
278 SocketBase = NULL;
283 main(argc, argv)
284 int argc;
285 char *argv[];
287 int ch, aflag;
289 #if defined(__AROS__)
290 if (!(SocketBase = OpenLibrary(socket_name, SOCKET_VERSION)))
292 return RETURN_FAIL;
294 if (!(MiamiBase = OpenLibrary("miami.library", 0)))
296 return RETURN_FAIL;
298 atexit(__close_bsdsocket);
299 #endif
301 /* Parse command-line options */
302 aflag = mflag = 0;
303 while ((ch = getopt(argc, argv, "adlmu")) != -1) {
304 switch (ch) {
305 case 'a':
306 aflag = 1;
307 break;
309 case 'd':
310 dflag = 1;
311 break;
313 case 'l':
314 lflag = 1;
315 break;
317 case 'm':
318 mflag = 1;
319 break;
321 case 'u':
322 uflag = 1;
323 break;
325 default:
326 usage();
327 /* NOTREACHED */
330 argc -= optind;
331 argv += optind;
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))
340 usage();
341 if (aflag || lflag) {
342 if (argc > 1)
343 usage();
344 else if (argc == 1) {
345 afp = lookup_af(argv[0]);
346 if (afp == NULL)
347 usage();
349 if (afp)
350 af = ifr.ifr_addr.sa_family = afp->af_af;
351 else
352 af = ifr.ifr_addr.sa_family = afs[0].af_af;
353 printall();
354 exit(0);
357 /* Make sure there's an interface name. */
358 if (argc < 1)
359 usage();
360 (void) strncpy(name, argv[0], sizeof(name));
361 argc--; argv++;
363 /* Check for address family. */
364 afp = NULL;
365 if (argc > 0) {
366 afp = lookup_af(argv[0]);
367 if (afp != NULL) {
368 argv++;
369 argc--;
373 if (afp == NULL)
374 afp = afs;
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)
380 exit(1);
382 /* No more arguments means interface status. */
383 if (argc == 0) {
384 status(NULL, 0);
385 exit(0);
388 /* Process commands. */
389 while (argc > 0) {
390 struct cmd *p;
392 for (p = cmds; p->c_name; p++)
393 if (strcmp(argv[0], p->c_name) == 0)
394 break;
395 if (p->c_name == 0 && setaddr)
396 p++; /* got src, do dst */
397 if (p->c_func) {
398 if (p->c_parameter == NEXTARG) {
399 if (argc < 2)
400 errx(1, "'%s' requires argument",
401 p->c_name);
402 (*p->c_func)(argv[1], 0);
403 argc--, argv++;
404 } else
405 (*p->c_func)(argv[0], p->c_parameter);
407 argc--, argv++;
410 #ifndef INET_ONLY
412 if (af == AF_ISO)
413 adjust_nsellength();
415 if (af == AF_APPLETALK)
416 checkatrange((struct sockaddr_at *) &addreq.ifra_addr);
418 if (setipdst && af==AF_NS) {
419 struct nsip_req rq;
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 */
431 if (clearaddr) {
432 int ret;
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 */
437 } else
438 warn("SIOCDIFADDR");
441 if (newaddr > 0) {
442 (void) strncpy(afp->af_addreq, name, sizeof ifr.ifr_name);
443 if (IoctlSocket(s, afp->af_aifaddr, afp->af_addreq) < 0)
444 warn("SIOCAIFADDR");
446 if (reset_if_flags && IoctlSocket(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
447 err(1, "SIOCSIFFLAGS");
448 exit(0);
451 struct afswtch *
452 lookup_af(cp)
453 const char *cp;
455 struct afswtch *a;
457 for (a = afs; a->af_name != NULL; a++)
458 if (strcmp(a->af_name, cp) == 0)
459 return (a);
460 return (NULL);
463 void
464 getsock(naf)
465 int naf;
467 static int oaf = -1;
469 if (oaf == naf)
470 return;
471 if (oaf != -1)
472 CloseSocket(s);
473 s = socket(naf, SOCK_DGRAM, 0);
474 if (s < 0)
475 oaf = -1;
476 else
477 oaf = naf;
481 getinfo(ifr)
482 struct ifreq *ifr;
485 getsock(af);
486 if (s < 0)
487 err(1, "socket");
488 if (IoctlSocket(s, SIOCGIFFLAGS, (caddr_t)ifr) < 0) {
489 #if !defined(__AROS__)
490 warn("SIOCGIFFLAGS %s", ifr->ifr_name);
491 #endif
492 return (-1);
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);
498 #endif
499 metric = 0;
500 } else
501 metric = ifr->ifr_metric;
502 if (IoctlSocket(s, SIOCGIFMTU, (caddr_t)ifr) < 0)
503 mtu = 0;
504 else
505 mtu = ifr->ifr_mtu;
506 return (0);
509 void
510 printall()
512 char inbuf[8192];
513 const struct sockaddr_dl *sdl = NULL;
514 struct ifconf ifc;
515 struct ifreq ifreq, *ifr;
516 int i, idx;
518 ifc.ifc_len = sizeof(inbuf);
519 ifc.ifc_buf = inbuf;
520 getsock(af);
521 if (s < 0)
522 err(1, "socket");
523 if (IoctlSocket(s, SIOCGIFCONF, (char *)&ifc) < 0)
524 err(1, "SIOCGIFCONF");
525 ifr = ifc.ifc_req;
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)))
537 continue;
538 (void) strncpy(name, ifr->ifr_name, sizeof(ifr->ifr_name));
539 ifreq = *ifr;
541 if (getinfo(&ifreq) < 0)
542 continue;
543 if (dflag && (flags & IFF_UP) != 0)
544 continue;
545 if (uflag && (flags & IFF_UP) == 0)
546 continue;
548 idx++;
550 * Are we just listing the interfaces?
552 if (lflag) {
553 if (idx > 1)
554 putchar(' ');
555 fputs(name, stdout);
556 continue;
559 if (sdl == NULL) {
560 status(NULL, 0);
561 } else {
562 status(LLADDR(sdl), sdl->sdl_alen);
563 sdl = NULL;
566 if (lflag)
567 putchar('\n');
570 #define RIDADDR 0
571 #define ADDR 1
572 #define MASK 2
573 #define DSTADDR 3
575 /*ARGSUSED*/
576 void
577 setifaddr(addr, param)
578 char *addr;
579 int 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.
586 setaddr++;
587 if (newaddr == -1)
588 newaddr = 1;
589 if (doalias == 0)
590 clearaddr = 1;
591 (*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR));
594 void
595 setifnetmask(addr, d)
596 char *addr;
597 int d;
599 (*afp->af_getaddr)(addr, MASK);
602 void
603 setifbroadaddr(addr, d)
604 char *addr;
605 int d;
607 (*afp->af_getaddr)(addr, DSTADDR);
610 void
611 setifipdst(addr, d)
612 char *addr;
613 int d;
615 in_getaddr(addr, DSTADDR);
616 setipdst++;
617 clearaddr = 0;
618 newaddr = 0;
621 #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
622 /*ARGSUSED*/
623 void
624 notealias(addr, param)
625 char *addr;
626 int param;
628 if (setaddr && doalias == 0 && param < 0)
629 (void) memcpy(rqtosa(af_ridreq), rqtosa(af_addreq),
630 rqtosa(af_addreq)->sa_len);
631 doalias = param;
632 if (param < 0) {
633 clearaddr = 1;
634 newaddr = 0;
635 } else
636 clearaddr = 0;
639 /*ARGSUSED*/
640 void
641 notrailers(vname, value)
642 char *vname;
643 int value;
645 puts("Note: trailers are no longer sent, but always received");
648 /*ARGSUSED*/
649 void
650 setifdstaddr(addr, param)
651 char *addr;
652 int param;
654 (*afp->af_getaddr)(addr, DSTADDR);
657 void
658 setifflags(vname, value)
659 char *vname;
660 int 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;
667 if (value < 0) {
668 value = -value;
669 flags &= ~value;
670 } else
671 flags |= value;
672 ifr.ifr_flags = flags;
673 /* if (IoctlSocket(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
674 err(1, "SIOCSIFFLAGS");*/
676 reset_if_flags = 1;
679 void
680 setifmetric(val, d)
681 char *val;
682 int d;
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");
690 void
691 setifmtu(val, d)
692 char *val;
693 int d;
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)
698 warn("SIOCSIFMTU");
700 #ifdef ENABLE_MEDIA_IOCTL
701 void
702 setmedia(val, d)
703 char *val;
704 int d;
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));
712 ifmr.ifm_count = 1;
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.
719 if (errno != E2BIG)
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"
730 * entry.
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");
745 void
746 setmediaopt(val, d)
747 char *val;
748 int d;
751 domediaopt(val, 0);
754 void
755 unsetmediaopt(val, d)
756 int d;
757 char *val;
760 domediaopt(val, 1);
763 void
764 domediaopt(val, clear)
765 char *val;
766 int 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));
787 if (mwords == NULL)
788 err(1, "malloc");
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);
796 free(mwords);
798 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
799 ifr.ifr_media = ifmr.ifm_current;
800 if (clear)
801 ifr.ifr_media &= ~options;
802 else
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 {
853 struct {
854 struct ifmedia_description *desc;
855 int alias;
856 } subtypes[5];
857 struct {
858 struct ifmedia_description *desc;
859 int alias;
860 } options[3];
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 },
871 { NULL, 0 },
874 { &ifm_shared_option_descriptions[0], 0 },
875 { &ifm_subtype_ethernet_option_descriptions[0], 1 },
876 { NULL, 0 },
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 },
885 { NULL, 0 },
888 { &ifm_shared_option_descriptions[0], 0 },
889 { &ifm_subtype_tokenring_option_descriptions[0], 1 },
890 { NULL, 0 },
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 },
899 { NULL, 0 },
902 { &ifm_shared_option_descriptions[0], 0 },
903 { &ifm_subtype_fddi_option_descriptions[0], 1 },
904 { NULL, 0 },
910 get_media_subtype(type, val)
911 int type;
912 char *val;
914 struct ifmedia_description *desc;
915 struct ifmedia_type_to_subtype *ttos;
916 int rval, i;
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)
922 break;
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);
928 if (rval != -1)
929 return (rval);
931 errx(1, "unknown media subtype: %s", val);
932 /* NOTREACHED */
936 get_media_options(type, val)
937 int type;
938 char *val;
940 struct ifmedia_description *desc;
941 struct ifmedia_type_to_subtype *ttos;
942 char *optlist;
943 int option = 0, i, rval = 0;
945 /* We muck with the string, so copy it. */
946 optlist = strdup(val);
947 if (optlist == NULL)
948 err(1, "strdup");
949 val = optlist;
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)
955 break;
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
961 * list.
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);
966 if (option != -1)
967 break;
969 if (option == 0)
970 errx(1, "unknown option: %s", val);
971 rval |= option;
974 free(optlist);
975 return (rval);
979 lookup_media_word(desc, val)
980 struct ifmedia_description *desc;
981 char *val;
984 for (; desc->ifmt_string != NULL; desc++)
985 if (strcasecmp(desc->ifmt_string, val) == 0)
986 return (desc->ifmt_word);
988 return (-1);
991 void
992 print_media_word(ifmw)
993 int 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)
1003 break;
1004 if (desc->ifmt_string == NULL) {
1005 printf("<unknown type>");
1006 return;
1010 * Don't print the top-level type; it's not like we can
1011 * change it, or anything.
1014 /* Find subtype. */
1015 for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
1016 if (ttos->subtypes[i].alias)
1017 continue;
1018 for (desc = ttos->subtypes[i].desc;
1019 desc->ifmt_string != NULL; desc++) {
1020 if (IFM_SUBTYPE(ifmw) == desc->ifmt_word)
1021 goto got_subtype;
1025 /* Falling to here means unknown subtype. */
1026 printf("<unknown subtype>");
1027 return;
1029 got_subtype:
1030 printf("%s", desc->ifmt_string);
1032 /* Find options. */
1033 for (i = 0; ttos->options[i].desc != NULL; i++) {
1034 if (ttos->options[i].alias)
1035 continue;
1036 for (desc = ttos->options[i].desc;
1037 desc->ifmt_string != NULL; desc++) {
1038 if (ifmw & desc->ifmt_word) {
1039 if (seen_option == 0)
1040 printf(" <");
1041 printf("%s%s", seen_option++ ? "," : "",
1042 desc->ifmt_string);
1046 printf("%s", seen_option ? ">" : "");
1048 #endif
1049 /**********************************************************************
1050 * ...until here.
1051 **********************************************************************/
1053 #define IFFBITS \
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.
1061 void
1062 status(ap, alen)
1063 const u_int8_t *ap;
1064 int alen;
1066 struct afswtch *p = afp;
1067 #ifdef ENABLE_MEDIA_IOCTL
1068 struct ifmediareq ifmr;
1069 int *media_list;
1070 #endif
1071 int i;
1073 printf("%s: ", name);
1074 printb("flags", flags, IFFBITS);
1075 if (metric)
1076 printf(" metric %d", metric);
1077 if (mtu)
1078 printf(" mtu %d", mtu);
1079 putchar('\n');
1080 if (ap && alen > 0) {
1081 printf("\taddress:");
1082 for (i = 0; i < alen; i++, ap++)
1083 printf("%c%02x", i > 0 ? ':' : ' ', *ap);
1084 putchar('\n');
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.
1094 goto proto_status;
1097 if (ifmr.ifm_count == 0) {
1098 warnx("%s: no media types?", name);
1099 goto proto_status;
1102 media_list = (int *)malloc(ifmr.ifm_count * sizeof(int));
1103 if (media_list == NULL)
1104 err(1, "malloc");
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) {
1113 putchar(' ');
1114 putchar('(');
1115 print_media_word(ifmr.ifm_active);
1116 putchar(')');
1119 if (ifmr.ifm_status & IFM_AVALID) {
1120 printf(" status: ");
1121 switch (IFM_TYPE(ifmr.ifm_active)) {
1122 case IFM_ETHER:
1123 if (ifmr.ifm_status & IFM_ACTIVE)
1124 printf("active");
1125 else
1126 printf("no carrier");
1127 break;
1129 case IFM_FDDI:
1130 case IFM_TOKEN:
1131 if (ifmr.ifm_status & IFM_ACTIVE)
1132 printf("inserted");
1133 else
1134 printf("no ring");
1135 break;
1139 putchar('\n');
1141 if (mflag) {
1142 printf("\tsupported media:");
1143 for (i = 0; i < ifmr.ifm_count; i++) {
1144 putchar(' ');
1145 print_media_word(media_list[i]);
1147 putchar('\n');
1150 free(media_list);
1151 proto_status:
1152 #endif
1153 if ((p = afp) != NULL) {
1154 (*p->af_status)(1);
1155 } else for (p = afs; p->af_name; p++) {
1156 ifr.ifr_addr.sa_family = p->af_af;
1157 (*p->af_status)(0);
1161 void
1162 in_status(force)
1163 int force;
1165 struct sockaddr_in *sin;
1167 getsock(AF_INET);
1168 if (s < 0) {
1169 if (errno == EPROTONOSUPPORT)
1170 return;
1171 err(1, "socket");
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) {
1177 if (!force)
1178 return;
1179 (void) memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
1180 } else
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));
1191 } else {
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));
1200 else
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));
1213 else
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));
1221 putchar('\n');
1224 #ifndef INET_ONLY
1226 void
1227 at_status(force)
1228 int force;
1230 struct sockaddr_at *sat, null_sat;
1231 struct netrange *nr;
1233 getsock(AF_APPLETALK);
1234 if (s < 0) {
1235 if (errno == EPROTONOSUPPORT)
1236 return;
1237 err(1, "socket");
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) {
1243 if (!force)
1244 return;
1245 (void) memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
1246 } else
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));
1263 else
1264 warn("SIOCGIFDSTADDR");
1266 (void) strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
1267 sat = (struct sockaddr_at *)&ifr.ifr_dstaddr;
1268 if (!sat)
1269 sat = &null_sat;
1270 printf("--> %d.%d",
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;
1276 if (sat)
1277 printf(" broadcast %d.%d", ntohs(sat->sat_addr.s_net),
1278 sat->sat_addr.s_node);
1280 putchar('\n');
1283 void
1284 xns_status(force)
1285 int force;
1287 struct sockaddr_ns *sns;
1289 getsock(AF_NS);
1290 if (s < 0) {
1291 if (errno == EPROTONOSUPPORT)
1292 return;
1293 err(1, "socket");
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) {
1299 if (!force)
1300 return;
1301 memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
1302 } else
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));
1312 else
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));
1319 putchar('\n');
1322 void
1323 iso_status(force)
1324 int force;
1326 struct sockaddr_iso *siso;
1328 getsock(AF_ISO);
1329 if (s < 0) {
1330 if (errno == EPROTONOSUPPORT)
1331 return;
1332 err(1, "socket");
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) {
1338 if (!force)
1339 return;
1340 (void) memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
1341 } else
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));
1350 else
1351 warn("SIOCGIFNETMASK");
1352 } else {
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));
1359 else
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));
1366 putchar('\n');
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)};
1376 void
1377 in_getaddr(s, which)
1378 char *s;
1379 int which;
1381 struct sockaddr_in *sin = sintab[which];
1382 struct hostent *hp;
1383 struct netent *np;
1385 sin->sin_len = sizeof(*sin);
1386 if (which != MASK)
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);
1396 else
1397 errx(1, "%s: bad value", s);
1402 * Print a value a la the %b format of the kernel's printf
1404 void
1405 printb(s, v, bits)
1406 char *s;
1407 char *bits;
1408 unsigned short v;
1410 int i, any = 0;
1411 char c;
1413 if (bits && *bits == 8)
1414 printf("%s=%o", s, v);
1415 else
1416 printf("%s=%x", s, v);
1417 bits++;
1418 if (bits) {
1419 putchar('<');
1420 while ((i = *bits++) != 0) {
1421 if (v & (1 << (i-1))) {
1422 if (any)
1423 putchar(',');
1424 any = 1;
1425 for (; (c = *bits) > 32; bits++)
1426 putchar(c);
1427 } else
1428 for (; *bits > 32; bits++)
1431 putchar('>');
1435 #ifndef INET_ONLY
1437 void
1438 at_getaddr(addr, which)
1439 char *addr;
1440 int which;
1442 struct sockaddr_at *sat = (struct sockaddr_at *) &addreq.ifra_addr;
1443 u_int net, node;
1445 sat->sat_family = AF_APPLETALK;
1446 sat->sat_len = sizeof(*sat);
1447 if (which == MASK)
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;
1456 void
1457 setatrange(range, d)
1458 char *range;
1459 int 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);
1471 void
1472 setatphase(phase, d)
1473 char *phase;
1474 int d;
1476 if (!strcmp(phase, "1"))
1477 at_nr.nr_phase = 1;
1478 else if (!strcmp(phase, "2"))
1479 at_nr.nr_phase = 2;
1480 else
1481 errx(1, "%s: illegal phase", phase);
1484 void
1485 checkatrange(sat)
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)};
1509 void
1510 xns_getaddr(addr, which)
1511 char *addr;
1512 int 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);
1519 if (which == MASK)
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)};
1528 void
1529 iso_getaddr(addr, which)
1530 char *addr;
1531 int 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;
1539 } else {
1540 siso->siso_len = sizeof(*siso);
1541 siso->siso_family = AF_ISO;
1545 void
1546 setsnpaoffset(val, d)
1547 char *val;
1548 int d;
1550 iso_addreq.ifra_snpaoffset = atoi(val);
1553 void
1554 setnsellength(val, d)
1555 char *val;
1556 int d;
1558 nsellength = atoi(val);
1559 if (nsellength < 0)
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");
1565 void
1566 fixnsel(s)
1567 struct sockaddr_iso *s;
1569 if (s->siso_family == 0)
1570 return;
1571 s->siso_tlen = nsellength;
1574 void
1575 adjust_nsellength()
1577 fixnsel(sisotab[RIDADDR]);
1578 fixnsel(sisotab[ADDR]);
1579 fixnsel(sisotab[DSTADDR]);
1582 #endif /* INET_ONLY */
1584 void
1585 usage()
1587 fprintf(stderr,
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",
1591 "\t[ metric n ]\n",
1592 "\t[ mtu n ]\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",
1598 #else
1599 "","","",
1600 #endif
1601 "\t[ link0 | -link0 ] [ link1 | -link1 ] [ link2 | -link2 ]\n",
1602 " ifconfig -a [ -m ] [ -d ] [ -u ] [ af ]\n",
1603 " ifconfig -l [ -d ] [ -u ]\n");
1604 exit(1);