Fixed binary search: no more infinite loops when vendor is unknown.
[tangerine.git] / workbench / network / stacks / AROSTCP / C / ifconfig.c
blobad8c145a987f34991ba80cba7fd87cc8aaf1697b
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 *));
269 main(argc, argv)
270 int argc;
271 char *argv[];
273 int ch, aflag;
275 #if defined(__AROS__)
276 if (!(SocketBase = OpenLibrary(socket_name, SOCKET_VERSION)))
278 return RETURN_FAIL;
280 if (!(MiamiBase = OpenLibrary("miami.library", 0)))
282 return RETURN_FAIL;
284 #endif
286 /* Parse command-line options */
287 aflag = mflag = 0;
288 while ((ch = getopt(argc, argv, "adlmu")) != -1) {
289 switch (ch) {
290 case 'a':
291 aflag = 1;
292 break;
294 case 'd':
295 dflag = 1;
296 break;
298 case 'l':
299 lflag = 1;
300 break;
302 case 'm':
303 mflag = 1;
304 break;
306 case 'u':
307 uflag = 1;
308 break;
310 default:
311 usage();
312 /* NOTREACHED */
315 argc -= optind;
316 argv += optind;
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))
325 usage();
326 if (aflag || lflag) {
327 if (argc > 1)
328 usage();
329 else if (argc == 1) {
330 afp = lookup_af(argv[0]);
331 if (afp == NULL)
332 usage();
334 if (afp)
335 af = ifr.ifr_addr.sa_family = afp->af_af;
336 else
337 af = ifr.ifr_addr.sa_family = afs[0].af_af;
338 printall();
339 exit(0);
342 /* Make sure there's an interface name. */
343 if (argc < 1)
344 usage();
345 (void) strncpy(name, argv[0], sizeof(name));
346 argc--; argv++;
348 /* Check for address family. */
349 afp = NULL;
350 if (argc > 0) {
351 afp = lookup_af(argv[0]);
352 if (afp != NULL) {
353 argv++;
354 argc--;
358 if (afp == NULL)
359 afp = afs;
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)
365 exit(1);
367 /* No more arguments means interface status. */
368 if (argc == 0) {
369 status(NULL, 0);
370 exit(0);
373 /* Process commands. */
374 while (argc > 0) {
375 struct cmd *p;
377 for (p = cmds; p->c_name; p++)
378 if (strcmp(argv[0], p->c_name) == 0)
379 break;
380 if (p->c_name == 0 && setaddr)
381 p++; /* got src, do dst */
382 if (p->c_func) {
383 if (p->c_parameter == NEXTARG) {
384 if (argc < 2)
385 errx(1, "'%s' requires argument",
386 p->c_name);
387 (*p->c_func)(argv[1], 0);
388 argc--, argv++;
389 } else
390 (*p->c_func)(argv[0], p->c_parameter);
392 argc--, argv++;
395 #ifndef INET_ONLY
397 if (af == AF_ISO)
398 adjust_nsellength();
400 if (af == AF_APPLETALK)
401 checkatrange((struct sockaddr_at *) &addreq.ifra_addr);
403 if (setipdst && af==AF_NS) {
404 struct nsip_req rq;
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 */
416 if (clearaddr) {
417 int ret;
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 */
422 } else
423 warn("SIOCDIFADDR");
426 if (newaddr > 0) {
427 (void) strncpy(afp->af_addreq, name, sizeof ifr.ifr_name);
428 if (IoctlSocket(s, afp->af_aifaddr, afp->af_addreq) < 0)
429 warn("SIOCAIFADDR");
431 if (reset_if_flags && IoctlSocket(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
432 err(1, "SIOCSIFFLAGS");
433 exit(0);
436 struct afswtch *
437 lookup_af(cp)
438 const char *cp;
440 struct afswtch *a;
442 for (a = afs; a->af_name != NULL; a++)
443 if (strcmp(a->af_name, cp) == 0)
444 return (a);
445 return (NULL);
448 void
449 getsock(naf)
450 int naf;
452 static int oaf = -1;
454 if (oaf == naf)
455 return;
456 if (oaf != -1)
457 CloseSocket(s);
458 s = socket(naf, SOCK_DGRAM, 0);
459 if (s < 0)
460 oaf = -1;
461 else
462 oaf = naf;
466 getinfo(ifr)
467 struct ifreq *ifr;
470 getsock(af);
471 if (s < 0)
472 err(1, "socket");
473 if (IoctlSocket(s, SIOCGIFFLAGS, (caddr_t)ifr) < 0) {
474 #if !defined(__AROS__)
475 warn("SIOCGIFFLAGS %s", ifr->ifr_name);
476 #endif
477 return (-1);
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);
483 #endif
484 metric = 0;
485 } else
486 metric = ifr->ifr_metric;
487 if (IoctlSocket(s, SIOCGIFMTU, (caddr_t)ifr) < 0)
488 mtu = 0;
489 else
490 mtu = ifr->ifr_mtu;
491 return (0);
494 void
495 printall()
497 char inbuf[8192];
498 const struct sockaddr_dl *sdl = NULL;
499 struct ifconf ifc;
500 struct ifreq ifreq, *ifr;
501 int i, idx;
503 ifc.ifc_len = sizeof(inbuf);
504 ifc.ifc_buf = inbuf;
505 getsock(af);
506 if (s < 0)
507 err(1, "socket");
508 if (IoctlSocket(s, SIOCGIFCONF, &ifc) < 0)
509 err(1, "SIOCGIFCONF");
510 ifr = ifc.ifc_req;
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)))
522 continue;
523 (void) strncpy(name, ifr->ifr_name, sizeof(ifr->ifr_name));
524 ifreq = *ifr;
526 if (getinfo(&ifreq) < 0)
527 continue;
528 if (dflag && (flags & IFF_UP) != 0)
529 continue;
530 if (uflag && (flags & IFF_UP) == 0)
531 continue;
533 idx++;
535 * Are we just listing the interfaces?
537 if (lflag) {
538 if (idx > 1)
539 putchar(' ');
540 fputs(name, stdout);
541 continue;
544 if (sdl == NULL) {
545 status(NULL, 0);
546 } else {
547 status(LLADDR(sdl), sdl->sdl_alen);
548 sdl = NULL;
551 if (lflag)
552 putchar('\n');
555 #define RIDADDR 0
556 #define ADDR 1
557 #define MASK 2
558 #define DSTADDR 3
560 /*ARGSUSED*/
561 void
562 setifaddr(addr, param)
563 char *addr;
564 int 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.
571 setaddr++;
572 if (newaddr == -1)
573 newaddr = 1;
574 if (doalias == 0)
575 clearaddr = 1;
576 (*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR));
579 void
580 setifnetmask(addr, d)
581 char *addr;
582 int d;
584 (*afp->af_getaddr)(addr, MASK);
587 void
588 setifbroadaddr(addr, d)
589 char *addr;
590 int d;
592 (*afp->af_getaddr)(addr, DSTADDR);
595 void
596 setifipdst(addr, d)
597 char *addr;
598 int d;
600 in_getaddr(addr, DSTADDR);
601 setipdst++;
602 clearaddr = 0;
603 newaddr = 0;
606 #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
607 /*ARGSUSED*/
608 void
609 notealias(addr, param)
610 char *addr;
611 int param;
613 if (setaddr && doalias == 0 && param < 0)
614 (void) memcpy(rqtosa(af_ridreq), rqtosa(af_addreq),
615 rqtosa(af_addreq)->sa_len);
616 doalias = param;
617 if (param < 0) {
618 clearaddr = 1;
619 newaddr = 0;
620 } else
621 clearaddr = 0;
624 /*ARGSUSED*/
625 void
626 notrailers(vname, value)
627 char *vname;
628 int value;
630 puts("Note: trailers are no longer sent, but always received");
633 /*ARGSUSED*/
634 void
635 setifdstaddr(addr, param)
636 char *addr;
637 int param;
639 (*afp->af_getaddr)(addr, DSTADDR);
642 void
643 setifflags(vname, value)
644 char *vname;
645 int 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;
652 if (value < 0) {
653 value = -value;
654 flags &= ~value;
655 } else
656 flags |= value;
657 ifr.ifr_flags = flags;
658 /* if (IoctlSocket(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
659 err(1, "SIOCSIFFLAGS");*/
661 reset_if_flags = 1;
664 void
665 setifmetric(val, d)
666 char *val;
667 int d;
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");
675 void
676 setifmtu(val, d)
677 char *val;
678 int d;
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)
683 warn("SIOCSIFMTU");
685 #ifdef ENABLE_MEDIA_IOCTL
686 void
687 setmedia(val, d)
688 char *val;
689 int d;
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));
697 ifmr.ifm_count = 1;
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.
704 if (errno != E2BIG)
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"
715 * entry.
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");
730 void
731 setmediaopt(val, d)
732 char *val;
733 int d;
736 domediaopt(val, 0);
739 void
740 unsetmediaopt(val, d)
741 int d;
742 char *val;
745 domediaopt(val, 1);
748 void
749 domediaopt(val, clear)
750 char *val;
751 int 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));
772 if (mwords == NULL)
773 err(1, "malloc");
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);
781 free(mwords);
783 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
784 ifr.ifr_media = ifmr.ifm_current;
785 if (clear)
786 ifr.ifr_media &= ~options;
787 else
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 {
838 struct {
839 struct ifmedia_description *desc;
840 int alias;
841 } subtypes[5];
842 struct {
843 struct ifmedia_description *desc;
844 int alias;
845 } options[3];
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 },
856 { NULL, 0 },
859 { &ifm_shared_option_descriptions[0], 0 },
860 { &ifm_subtype_ethernet_option_descriptions[0], 1 },
861 { NULL, 0 },
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 },
870 { NULL, 0 },
873 { &ifm_shared_option_descriptions[0], 0 },
874 { &ifm_subtype_tokenring_option_descriptions[0], 1 },
875 { NULL, 0 },
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 },
884 { NULL, 0 },
887 { &ifm_shared_option_descriptions[0], 0 },
888 { &ifm_subtype_fddi_option_descriptions[0], 1 },
889 { NULL, 0 },
895 get_media_subtype(type, val)
896 int type;
897 char *val;
899 struct ifmedia_description *desc;
900 struct ifmedia_type_to_subtype *ttos;
901 int rval, i;
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)
907 break;
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);
913 if (rval != -1)
914 return (rval);
916 errx(1, "unknown media subtype: %s", val);
917 /* NOTREACHED */
921 get_media_options(type, val)
922 int type;
923 char *val;
925 struct ifmedia_description *desc;
926 struct ifmedia_type_to_subtype *ttos;
927 char *optlist;
928 int option = 0, i, rval = 0;
930 /* We muck with the string, so copy it. */
931 optlist = strdup(val);
932 if (optlist == NULL)
933 err(1, "strdup");
934 val = optlist;
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)
940 break;
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
946 * list.
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);
951 if (option != -1)
952 break;
954 if (option == 0)
955 errx(1, "unknown option: %s", val);
956 rval |= option;
959 free(optlist);
960 return (rval);
964 lookup_media_word(desc, val)
965 struct ifmedia_description *desc;
966 char *val;
969 for (; desc->ifmt_string != NULL; desc++)
970 if (strcasecmp(desc->ifmt_string, val) == 0)
971 return (desc->ifmt_word);
973 return (-1);
976 void
977 print_media_word(ifmw)
978 int 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)
988 break;
989 if (desc->ifmt_string == NULL) {
990 printf("<unknown type>");
991 return;
995 * Don't print the top-level type; it's not like we can
996 * change it, or anything.
999 /* Find subtype. */
1000 for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
1001 if (ttos->subtypes[i].alias)
1002 continue;
1003 for (desc = ttos->subtypes[i].desc;
1004 desc->ifmt_string != NULL; desc++) {
1005 if (IFM_SUBTYPE(ifmw) == desc->ifmt_word)
1006 goto got_subtype;
1010 /* Falling to here means unknown subtype. */
1011 printf("<unknown subtype>");
1012 return;
1014 got_subtype:
1015 printf("%s", desc->ifmt_string);
1017 /* Find options. */
1018 for (i = 0; ttos->options[i].desc != NULL; i++) {
1019 if (ttos->options[i].alias)
1020 continue;
1021 for (desc = ttos->options[i].desc;
1022 desc->ifmt_string != NULL; desc++) {
1023 if (ifmw & desc->ifmt_word) {
1024 if (seen_option == 0)
1025 printf(" <");
1026 printf("%s%s", seen_option++ ? "," : "",
1027 desc->ifmt_string);
1031 printf("%s", seen_option ? ">" : "");
1033 #endif
1034 /**********************************************************************
1035 * ...until here.
1036 **********************************************************************/
1038 #define IFFBITS \
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.
1046 void
1047 status(ap, alen)
1048 const u_int8_t *ap;
1049 int alen;
1051 struct afswtch *p = afp;
1052 #ifdef ENABLE_MEDIA_IOCTL
1053 struct ifmediareq ifmr;
1054 int *media_list;
1055 #endif
1056 int i;
1058 printf("%s: ", name);
1059 printb("flags", flags, IFFBITS);
1060 if (metric)
1061 printf(" metric %d", metric);
1062 if (mtu)
1063 printf(" mtu %d", mtu);
1064 putchar('\n');
1065 if (ap && alen > 0) {
1066 printf("\taddress:");
1067 for (i = 0; i < alen; i++, ap++)
1068 printf("%c%02x", i > 0 ? ':' : ' ', *ap);
1069 putchar('\n');
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.
1079 goto proto_status;
1082 if (ifmr.ifm_count == 0) {
1083 warnx("%s: no media types?", name);
1084 goto proto_status;
1087 media_list = (int *)malloc(ifmr.ifm_count * sizeof(int));
1088 if (media_list == NULL)
1089 err(1, "malloc");
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) {
1098 putchar(' ');
1099 putchar('(');
1100 print_media_word(ifmr.ifm_active);
1101 putchar(')');
1104 if (ifmr.ifm_status & IFM_AVALID) {
1105 printf(" status: ");
1106 switch (IFM_TYPE(ifmr.ifm_active)) {
1107 case IFM_ETHER:
1108 if (ifmr.ifm_status & IFM_ACTIVE)
1109 printf("active");
1110 else
1111 printf("no carrier");
1112 break;
1114 case IFM_FDDI:
1115 case IFM_TOKEN:
1116 if (ifmr.ifm_status & IFM_ACTIVE)
1117 printf("inserted");
1118 else
1119 printf("no ring");
1120 break;
1124 putchar('\n');
1126 if (mflag) {
1127 printf("\tsupported media:");
1128 for (i = 0; i < ifmr.ifm_count; i++) {
1129 putchar(' ');
1130 print_media_word(media_list[i]);
1132 putchar('\n');
1135 free(media_list);
1136 #endif
1137 proto_status:
1138 if ((p = afp) != NULL) {
1139 (*p->af_status)(1);
1140 } else for (p = afs; p->af_name; p++) {
1141 ifr.ifr_addr.sa_family = p->af_af;
1142 (*p->af_status)(0);
1146 void
1147 in_status(force)
1148 int force;
1150 struct sockaddr_in *sin;
1152 getsock(AF_INET);
1153 if (s < 0) {
1154 if (errno == EPROTONOSUPPORT)
1155 return;
1156 err(1, "socket");
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) {
1162 if (!force)
1163 return;
1164 (void) memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
1165 } else
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));
1176 } else
1177 netmask.sin_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));
1184 else
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));
1197 else
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));
1205 putchar('\n');
1208 #ifndef INET_ONLY
1210 void
1211 at_status(force)
1212 int force;
1214 struct sockaddr_at *sat, null_sat;
1215 struct netrange *nr;
1217 getsock(AF_APPLETALK);
1218 if (s < 0) {
1219 if (errno == EPROTONOSUPPORT)
1220 return;
1221 err(1, "socket");
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) {
1227 if (!force)
1228 return;
1229 (void) memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
1230 } else
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));
1247 else
1248 warn("SIOCGIFDSTADDR");
1250 (void) strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
1251 sat = (struct sockaddr_at *)&ifr.ifr_dstaddr;
1252 if (!sat)
1253 sat = &null_sat;
1254 printf("--> %d.%d",
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;
1260 if (sat)
1261 printf(" broadcast %d.%d", ntohs(sat->sat_addr.s_net),
1262 sat->sat_addr.s_node);
1264 putchar('\n');
1267 void
1268 xns_status(force)
1269 int force;
1271 struct sockaddr_ns *sns;
1273 getsock(AF_NS);
1274 if (s < 0) {
1275 if (errno == EPROTONOSUPPORT)
1276 return;
1277 err(1, "socket");
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) {
1283 if (!force)
1284 return;
1285 memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
1286 } else
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));
1296 else
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));
1303 putchar('\n');
1306 void
1307 iso_status(force)
1308 int force;
1310 struct sockaddr_iso *siso;
1312 getsock(AF_ISO);
1313 if (s < 0) {
1314 if (errno == EPROTONOSUPPORT)
1315 return;
1316 err(1, "socket");
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) {
1322 if (!force)
1323 return;
1324 (void) memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
1325 } else
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));
1334 else
1335 warn("SIOCGIFNETMASK");
1336 } else {
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));
1343 else
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));
1350 putchar('\n');
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)};
1360 void
1361 in_getaddr(s, which)
1362 char *s;
1363 int which;
1365 struct sockaddr_in *sin = sintab[which];
1366 struct hostent *hp;
1367 struct netent *np;
1369 sin->sin_len = sizeof(*sin);
1370 if (which != MASK)
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);
1380 else
1381 errx(1, "%s: bad value", s);
1386 * Print a value a la the %b format of the kernel's printf
1388 void
1389 printb(s, v, bits)
1390 char *s;
1391 char *bits;
1392 unsigned short v;
1394 int i, any = 0;
1395 char c;
1397 if (bits && *bits == 8)
1398 printf("%s=%o", s, v);
1399 else
1400 printf("%s=%x", s, v);
1401 bits++;
1402 if (bits) {
1403 putchar('<');
1404 while ((i = *bits++) != 0) {
1405 if (v & (1 << (i-1))) {
1406 if (any)
1407 putchar(',');
1408 any = 1;
1409 for (; (c = *bits) > 32; bits++)
1410 putchar(c);
1411 } else
1412 for (; *bits > 32; bits++)
1415 putchar('>');
1419 #ifndef INET_ONLY
1421 void
1422 at_getaddr(addr, which)
1423 char *addr;
1424 int which;
1426 struct sockaddr_at *sat = (struct sockaddr_at *) &addreq.ifra_addr;
1427 u_int net, node;
1429 sat->sat_family = AF_APPLETALK;
1430 sat->sat_len = sizeof(*sat);
1431 if (which == MASK)
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;
1440 void
1441 setatrange(range, d)
1442 char *range;
1443 int 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);
1455 void
1456 setatphase(phase, d)
1457 char *phase;
1458 int d;
1460 if (!strcmp(phase, "1"))
1461 at_nr.nr_phase = 1;
1462 else if (!strcmp(phase, "2"))
1463 at_nr.nr_phase = 2;
1464 else
1465 errx(1, "%s: illegal phase", phase);
1468 void
1469 checkatrange(sat)
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)};
1493 void
1494 xns_getaddr(addr, which)
1495 char *addr;
1496 int 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);
1503 if (which == MASK)
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)};
1512 void
1513 iso_getaddr(addr, which)
1514 char *addr;
1515 int 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;
1523 } else {
1524 siso->siso_len = sizeof(*siso);
1525 siso->siso_family = AF_ISO;
1529 void
1530 setsnpaoffset(val, d)
1531 char *val;
1532 int d;
1534 iso_addreq.ifra_snpaoffset = atoi(val);
1537 void
1538 setnsellength(val, d)
1539 char *val;
1540 int d;
1542 nsellength = atoi(val);
1543 if (nsellength < 0)
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");
1549 void
1550 fixnsel(s)
1551 struct sockaddr_iso *s;
1553 if (s->siso_family == 0)
1554 return;
1555 s->siso_tlen = nsellength;
1558 void
1559 adjust_nsellength()
1561 fixnsel(sisotab[RIDADDR]);
1562 fixnsel(sisotab[ADDR]);
1563 fixnsel(sisotab[DSTADDR]);
1566 #endif /* INET_ONLY */
1568 void
1569 usage()
1571 #warning "TODO: NicJA - AROS Should also display usage instructions"
1572 #if !defined(__AROS__)
1573 fprintf(stderr,
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",
1577 "\t[ metric n ]\n",
1578 "\t[ mtu n ]\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",
1584 #else
1585 "","","",
1586 #endif
1587 "\t[ link0 | -link0 ] [ link1 | -link1 ] [ link2 | -link2 ]\n",
1588 " ifconfig -a [ -m ] [ -d ] [ -u ] [ af ]\n",
1589 " ifconfig -l [ -d ] [ -u ]\n");
1590 #endif
1591 exit(1);