ifconfig.c revision 1.17 1 /*
2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #ifndef lint
35 static char copyright[] =
36 "@(#) Copyright (c) 1983, 1993\n\
37 The Regents of the University of California. All rights reserved.\n";
38 #endif /* not lint */
39
40 #ifndef lint
41 /*static char sccsid[] = "from: @(#)ifconfig.c 8.2 (Berkeley) 2/16/94";*/
42 static char *rcsid = "$Id: ifconfig.c,v 1.17 1994/12/18 12:58:39 cgd Exp $";
43 #endif /* not lint */
44
45 #include <sys/param.h>
46 #include <sys/socket.h>
47 #include <sys/ioctl.h>
48
49 #include <net/if.h>
50 #include <netinet/in.h>
51 #include <arpa/inet.h>
52
53 #define NSIP
54 #include <netns/ns.h>
55 #include <netns/ns_if.h>
56 #include <netdb.h>
57
58 #define EON
59 #include <netiso/iso.h>
60 #include <netiso/iso_var.h>
61 #include <sys/protosw.h>
62
63 #include <ctype.h>
64 #include <err.h>
65 #include <errno.h>
66 #include <stdio.h>
67 #include <stdlib.h>
68 #include <string.h>
69 #include <unistd.h>
70
71 struct ifreq ifr, ridreq;
72 struct ifaliasreq addreq;
73 struct iso_ifreq iso_ridreq;
74 struct iso_aliasreq iso_addreq;
75 struct sockaddr_in netmask;
76 char name[30];
77 int flags, metric, setaddr, setipdst, doalias;
78 int clearaddr, s;
79 int newaddr = 1;
80 int nsellength = 1;
81 int af = AF_INET;
82
83 void notealias __P((char *, int));
84 void notrailers __P((char *, int));
85 void setifaddr __P((char *, int));
86 void setifdstaddr __P((char *, int));
87 void setifflags __P((char *, int));
88 void setifbroadaddr __P((char *));
89 void setifipdst __P((char *));
90 void setifmetric __P((char *));
91 void setifnetmask __P((char *));
92 void setnsellength __P((char *));
93 void setsnpaoffset __P((char *));
94
95 #define NEXTARG 0xffffff
96
97 struct cmd {
98 char *c_name;
99 int c_parameter; /* NEXTARG means next argv */
100 void (*c_func)();
101 } cmds[] = {
102 { "up", IFF_UP, setifflags } ,
103 { "down", -IFF_UP, setifflags },
104 { "trailers", -1, notrailers },
105 { "-trailers", 1, notrailers },
106 { "arp", -IFF_NOARP, setifflags },
107 { "-arp", IFF_NOARP, setifflags },
108 { "debug", IFF_DEBUG, setifflags },
109 { "-debug", -IFF_DEBUG, setifflags },
110 { "alias", IFF_UP, notealias },
111 { "-alias", -IFF_UP, notealias },
112 { "delete", -IFF_UP, notealias },
113 #ifdef notdef
114 #define EN_SWABIPS 0x1000
115 { "swabips", EN_SWABIPS, setifflags },
116 { "-swabips", -EN_SWABIPS, setifflags },
117 #endif
118 { "netmask", NEXTARG, setifnetmask },
119 { "metric", NEXTARG, setifmetric },
120 { "broadcast", NEXTARG, setifbroadaddr },
121 { "ipdst", NEXTARG, setifipdst },
122 { "snpaoffset", NEXTARG, setsnpaoffset },
123 { "nsellength", NEXTARG, setnsellength },
124 { "link0", IFF_LINK0, setifflags } ,
125 { "-link0", -IFF_LINK0, setifflags } ,
126 { "link1", IFF_LINK1, setifflags } ,
127 { "-link1", -IFF_LINK1, setifflags } ,
128 { "link2", IFF_LINK2, setifflags } ,
129 { "-link2", -IFF_LINK2, setifflags } ,
130 { 0, 0, setifaddr },
131 { 0, 0, setifdstaddr },
132 };
133
134 void adjust_nsellength();
135 int getinfo __P((struct ifreq *));
136 void getsock __P((int));
137 void printall __P((void));
138 void printb __P((char *, unsigned short, char *));
139 void status();
140
141 /*
142 * XNS support liberally adapted from code written at the University of
143 * Maryland principally by James O'Toole and Chris Torek.
144 */
145 void in_status __P((int));
146 void in_getaddr __P((char *, int));
147 void xns_status __P((int));
148 void xns_getaddr __P((char *, int));
149 void iso_status __P((int));
150 void iso_getaddr __P((char *, int));
151
152 /* Known address families */
153 struct afswtch {
154 char *af_name;
155 short af_af;
156 void (*af_status)();
157 void (*af_getaddr)();
158 u_long af_difaddr;
159 u_long af_aifaddr;
160 caddr_t af_ridreq;
161 caddr_t af_addreq;
162 } afs[] = {
163 #define C(x) ((caddr_t) &x)
164 { "inet", AF_INET, in_status, in_getaddr,
165 SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
166 { "ns", AF_NS, xns_status, xns_getaddr,
167 SIOCDIFADDR, SIOCAIFADDR, C(ridreq), C(addreq) },
168 { "iso", AF_ISO, iso_status, iso_getaddr,
169 SIOCDIFADDR_ISO, SIOCAIFADDR_ISO, C(iso_ridreq), C(iso_addreq) },
170 { 0, 0, 0, 0 }
171 };
172
173 struct afswtch *afp; /*the address family being set or asked about*/
174
175 int
176 main(argc, argv)
177 int argc;
178 char *argv[];
179 {
180 register struct afswtch *rafp;
181 int aflag = 0;
182
183 if (argc < 2) {
184 fprintf(stderr, "usage: ifconfig interface\n%s%s%s%s%s",
185 "\t[ af [ address [ dest_addr ] ] [ up ] [ down ] ",
186 "[ netmask mask ] ]\n",
187 "\t[ metric n ]\n",
188 "\t[ arp | -arp ]\n",
189 "\t[ link0 | -link0 ] [ link1 | -link1 ] [ link2 | -link2 ]\n");
190 exit(1);
191 }
192 argc--, argv++;
193 if (!strcmp(*argv, "-a"))
194 aflag = 1;
195 else
196 strncpy(name, *argv, sizeof(name));
197 argc--, argv++;
198 if (argc > 0) {
199 for (afp = rafp = afs; rafp->af_name; rafp++)
200 if (strcmp(rafp->af_name, *argv) == 0) {
201 afp = rafp; argc--; argv++;
202 break;
203 }
204 rafp = afp;
205 af = ifr.ifr_addr.sa_family = rafp->af_af;
206 }
207 if (aflag) {
208 printall();
209 exit(0);
210 }
211 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
212 if (getinfo(&ifr) < 0)
213 exit(1);
214 if (argc == 0) {
215 status();
216 exit(0);
217 }
218 while (argc > 0) {
219 register struct cmd *p;
220
221 for (p = cmds; p->c_name; p++)
222 if (strcmp(*argv, p->c_name) == 0)
223 break;
224 if (p->c_name == 0 && setaddr)
225 p++; /* got src, do dst */
226 if (p->c_func) {
227 if (p->c_parameter == NEXTARG) {
228 if (argv[1] == NULL)
229 errx(1, "'%s' requires argument",
230 p->c_name);
231 (*p->c_func)(argv[1]);
232 argc--, argv++;
233 } else
234 (*p->c_func)(*argv, p->c_parameter);
235 }
236 argc--, argv++;
237 }
238 if (af == AF_ISO)
239 adjust_nsellength();
240 if (setipdst && af==AF_NS) {
241 struct nsip_req rq;
242 int size = sizeof(rq);
243
244 rq.rq_ns = addreq.ifra_addr;
245 rq.rq_ip = addreq.ifra_dstaddr;
246
247 if (setsockopt(s, 0, SO_NSIP_ROUTE, &rq, size) < 0)
248 warn("encapsulation routing");
249 }
250 if (clearaddr) {
251 int ret;
252 strncpy(rafp->af_ridreq, name, sizeof ifr.ifr_name);
253 if ((ret = ioctl(s, rafp->af_difaddr, rafp->af_ridreq)) < 0) {
254 if (errno == EADDRNOTAVAIL && (doalias >= 0)) {
255 /* means no previous address for interface */
256 } else
257 warn("SIOCDIFADDR");
258 }
259 }
260 if (newaddr) {
261 strncpy(rafp->af_addreq, name, sizeof ifr.ifr_name);
262 if (ioctl(s, rafp->af_aifaddr, rafp->af_addreq) < 0)
263 warn("SIOCAIFADDR");
264 }
265 exit(0);
266 }
267
268 void
269 getsock(naf)
270 int naf;
271 {
272 static int oaf = -1;
273
274 if (oaf == naf)
275 return;
276 if (oaf != -1)
277 close(s);
278 s = socket(naf, SOCK_DGRAM, 0);
279 if (s < 0)
280 oaf = -1;
281 else
282 oaf = naf;
283 }
284
285 int
286 getinfo(ifr)
287 struct ifreq *ifr;
288 {
289
290 getsock(af);
291 if (s < 0)
292 err(1, "socket");
293 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)ifr) < 0) {
294 warn("SIOCGIFFLAGS");
295 return (-1);
296 }
297 flags = ifr->ifr_flags;
298 if (ioctl(s, SIOCGIFMETRIC, (caddr_t)ifr) < 0) {
299 warn("SIOCGIFMETRIC");
300 metric = 0;
301 } else
302 metric = ifr->ifr_metric;
303 return (0);
304 }
305
306 void
307 printall()
308 {
309 char inbuf[8192];
310 struct ifconf ifc;
311 struct ifreq ifreq, *ifr;
312 int i;
313
314 ifc.ifc_len = sizeof(inbuf);
315 ifc.ifc_buf = inbuf;
316 getsock(af);
317 if (s < 0)
318 err(1, "socket");
319 if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
320 err(1, "SIOCGIFCONF");
321 ifr = ifc.ifc_req;
322 ifreq.ifr_name[0] = '\0';
323 for (i = 0; i < ifc.ifc_len; ) {
324 ifr = (struct ifreq *)((caddr_t)ifc.ifc_req + i);
325 i += sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len;
326 if (!strncmp(ifreq.ifr_name, ifr->ifr_name,
327 sizeof(ifr->ifr_name)))
328 continue;
329 strncpy(name, ifr->ifr_name, sizeof(ifr->ifr_name));
330 ifreq = *ifr;
331 if (getinfo(&ifreq) < 0)
332 continue;
333 status();
334 }
335 }
336
337 #define RIDADDR 0
338 #define ADDR 1
339 #define MASK 2
340 #define DSTADDR 3
341
342 /*ARGSUSED*/
343 void
344 setifaddr(addr, param)
345 char *addr;
346 int param;
347 {
348 /*
349 * Delay the ioctl to set the interface addr until flags are all set.
350 * The address interpretation may depend on the flags,
351 * and the flags may change when the address is set.
352 */
353 setaddr++;
354 if (doalias == 0)
355 clearaddr = 1;
356 (*afp->af_getaddr)(addr, (doalias >= 0 ? ADDR : RIDADDR));
357 }
358
359 void
360 setifnetmask(addr)
361 char *addr;
362 {
363 (*afp->af_getaddr)(addr, MASK);
364 }
365
366 void
367 setifbroadaddr(addr)
368 char *addr;
369 {
370 (*afp->af_getaddr)(addr, DSTADDR);
371 }
372
373 void
374 setifipdst(addr)
375 char *addr;
376 {
377 in_getaddr(addr, DSTADDR);
378 setipdst++;
379 clearaddr = 0;
380 newaddr = 0;
381 }
382
383 #define rqtosa(x) (&(((struct ifreq *)(afp->x))->ifr_addr))
384 /*ARGSUSED*/
385 void
386 notealias(addr, param)
387 char *addr;
388 int param;
389 {
390 if (setaddr && doalias == 0 && param < 0)
391 memcpy(rqtosa(af_ridreq),
392 rqtosa(af_addreq),
393 rqtosa(af_addreq)->sa_len);
394 doalias = param;
395 if (param < 0) {
396 clearaddr = 1;
397 newaddr = 0;
398 } else
399 clearaddr = 0;
400 }
401
402 /*ARGSUSED*/
403 void
404 notrailers(vname, value)
405 char *vname;
406 int value;
407 {
408 printf("Note: trailers are no longer sent, but always received\n");
409 }
410
411 /*ARGSUSED*/
412 void
413 setifdstaddr(addr, param)
414 char *addr;
415 int param;
416 {
417 (*afp->af_getaddr)(addr, DSTADDR);
418 }
419
420 void
421 setifflags(vname, value)
422 char *vname;
423 int value;
424 {
425 if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0)
426 err(1, "SIOCGIFFLAGS");
427 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
428 flags = ifr.ifr_flags;
429
430 if (value < 0) {
431 value = -value;
432 flags &= ~value;
433 } else
434 flags |= value;
435 ifr.ifr_flags = flags;
436 if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
437 err(1, "SIOCSIFFLAGS");
438 }
439
440 void
441 setifmetric(val)
442 char *val;
443 {
444 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
445 ifr.ifr_metric = atoi(val);
446 if (ioctl(s, SIOCSIFMETRIC, (caddr_t)&ifr) < 0)
447 warn("SIOCSIFMETRIC");
448 }
449
450 void
451 setsnpaoffset(val)
452 char *val;
453 {
454 iso_addreq.ifra_snpaoffset = atoi(val);
455 }
456
457 #define IFFBITS \
458 "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6NOTRAILERS\7RUNNING\10NOARP\
459 \11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST"
460
461 /*
462 * Print the status of the interface. If an address family was
463 * specified, show it and it only; otherwise, show them all.
464 */
465 void
466 status()
467 {
468 register struct afswtch *p = afp;
469
470 printf("%s: ", name);
471 printb("flags", flags, IFFBITS);
472 if (metric)
473 printf(" metric %d", metric);
474 putchar('\n');
475 if ((p = afp) != NULL) {
476 (*p->af_status)(1);
477 } else for (p = afs; p->af_name; p++) {
478 ifr.ifr_addr.sa_family = p->af_af;
479 (*p->af_status)(0);
480 }
481 }
482
483 void
484 in_status(force)
485 int force;
486 {
487 struct sockaddr_in *sin;
488 char *inet_ntoa();
489
490 getsock(AF_INET);
491 if (s < 0) {
492 if (errno == EPROTONOSUPPORT)
493 return;
494 err(1, "socket");
495 }
496 memset(&ifr, 0, sizeof(ifr));
497 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
498 if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
499 if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
500 if (!force)
501 return;
502 memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
503 } else
504 warn("SIOCGIFADDR");
505 }
506 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
507 sin = (struct sockaddr_in *)&ifr.ifr_addr;
508 printf("\tinet %s ", inet_ntoa(sin->sin_addr));
509 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
510 if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) {
511 if (errno != EADDRNOTAVAIL)
512 warn("SIOCGIFNETMASK");
513 memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
514 } else
515 netmask.sin_addr =
516 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
517 if (flags & IFF_POINTOPOINT) {
518 if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
519 if (errno == EADDRNOTAVAIL)
520 memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
521 else
522 warn("SIOCGIFDSTADDR");
523 }
524 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
525 sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
526 printf("--> %s ", inet_ntoa(sin->sin_addr));
527 }
528 printf("netmask 0x%x ", ntohl(netmask.sin_addr.s_addr));
529 if (flags & IFF_BROADCAST) {
530 if (ioctl(s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) {
531 if (errno == EADDRNOTAVAIL)
532 memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
533 else
534 warn("SIOCGIFBRDADDR");
535 }
536 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
537 sin = (struct sockaddr_in *)&ifr.ifr_addr;
538 if (sin->sin_addr.s_addr != 0)
539 printf("broadcast %s", inet_ntoa(sin->sin_addr));
540 }
541 putchar('\n');
542 }
543
544 void
545 xns_status(force)
546 int force;
547 {
548 struct sockaddr_ns *sns;
549
550 getsock(AF_NS);
551 if (s < 0) {
552 if (errno == EPROTONOSUPPORT)
553 return;
554 err(1, "socket");
555 }
556 memset(&ifr, 0, sizeof(ifr));
557 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
558 if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
559 if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
560 if (!force)
561 return;
562 memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
563 } else
564 warn("SIOCGIFADDR");
565 }
566 strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
567 sns = (struct sockaddr_ns *)&ifr.ifr_addr;
568 printf("\tns %s ", ns_ntoa(sns->sns_addr));
569 if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */
570 if (ioctl(s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
571 if (errno == EADDRNOTAVAIL)
572 memset(&ifr.ifr_addr, 0, sizeof(ifr.ifr_addr));
573 else
574 warn("SIOCGIFDSTADDR");
575 }
576 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
577 sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr;
578 printf("--> %s ", ns_ntoa(sns->sns_addr));
579 }
580 putchar('\n');
581 }
582
583 void
584 iso_status(force)
585 int force;
586 {
587 struct sockaddr_iso *siso;
588 struct iso_ifreq ifr;
589
590 getsock(AF_ISO);
591 if (s < 0) {
592 if (errno == EPROTONOSUPPORT)
593 return;
594 err(1, "socket");
595 }
596 memset(&ifr, 0, sizeof(ifr));
597 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
598 if (ioctl(s, SIOCGIFADDR_ISO, (caddr_t)&ifr) < 0) {
599 if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
600 if (!force)
601 return;
602 memset(&ifr.ifr_Addr, 0, sizeof(ifr.ifr_Addr));
603 } else
604 warn("SIOCGIFADDR_ISO");
605 }
606 strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
607 siso = &ifr.ifr_Addr;
608 printf("\tiso %s ", iso_ntoa(&siso->siso_addr));
609 if (ioctl(s, SIOCGIFNETMASK_ISO, (caddr_t)&ifr) < 0) {
610 if (errno == EADDRNOTAVAIL)
611 memset(&ifr.ifr_Addr, 0, sizeof(ifr.ifr_Addr));
612 else
613 warn("SIOCGIFNETMASK_ISO");
614 } else {
615 printf(" netmask %s ", iso_ntoa(&siso->siso_addr));
616 }
617 if (flags & IFF_POINTOPOINT) {
618 if (ioctl(s, SIOCGIFDSTADDR_ISO, (caddr_t)&ifr) < 0) {
619 if (errno == EADDRNOTAVAIL)
620 memset(&ifr.ifr_Addr, 0, sizeof(ifr.ifr_Addr));
621 else
622 warn("SIOCGIFDSTADDR_ISO");
623 }
624 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
625 siso = &ifr.ifr_Addr;
626 printf("--> %s ", iso_ntoa(&siso->siso_addr));
627 }
628 putchar('\n');
629 }
630
631 struct in_addr inet_makeaddr();
632
633 #define SIN(x) ((struct sockaddr_in *) &(x))
634 struct sockaddr_in *sintab[] = {
635 SIN(ridreq.ifr_addr), SIN(addreq.ifra_addr),
636 SIN(addreq.ifra_mask), SIN(addreq.ifra_broadaddr)};
637
638 void
639 in_getaddr(s, which)
640 char *s;
641 int which;
642 {
643 register struct sockaddr_in *sin = sintab[which];
644 struct hostent *hp;
645 struct netent *np;
646 int val;
647
648 sin->sin_len = sizeof(*sin);
649 if (which != MASK)
650 sin->sin_family = AF_INET;
651
652 if ((val = inet_addr(s)) != -1)
653 sin->sin_addr.s_addr = val;
654 else if (hp = gethostbyname(s))
655 memcpy(&sin->sin_addr, hp->h_addr, hp->h_length);
656 else if (np = getnetbyname(s))
657 sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
658 else
659 errx(1, "%s: bad value", s);
660 }
661
662 /*
663 * Print a value a la the %b format of the kernel's printf
664 */
665 void
666 printb(s, v, bits)
667 char *s;
668 register char *bits;
669 register unsigned short v;
670 {
671 register int i, any = 0;
672 register char c;
673
674 if (bits && *bits == 8)
675 printf("%s=%o", s, v);
676 else
677 printf("%s=%x", s, v);
678 bits++;
679 if (bits) {
680 putchar('<');
681 while (i = *bits++) {
682 if (v & (1 << (i-1))) {
683 if (any)
684 putchar(',');
685 any = 1;
686 for (; (c = *bits) > 32; bits++)
687 putchar(c);
688 } else
689 for (; *bits > 32; bits++)
690 ;
691 }
692 putchar('>');
693 }
694 }
695
696 #define SNS(x) ((struct sockaddr_ns *) &(x))
697 struct sockaddr_ns *snstab[] = {
698 SNS(ridreq.ifr_addr), SNS(addreq.ifra_addr),
699 SNS(addreq.ifra_mask), SNS(addreq.ifra_broadaddr)};
700
701 void
702 xns_getaddr(addr, which)
703 char *addr;
704 int which;
705 {
706 struct sockaddr_ns *sns = snstab[which];
707 struct ns_addr ns_addr();
708
709 sns->sns_family = AF_NS;
710 sns->sns_len = sizeof(*sns);
711 sns->sns_addr = ns_addr(addr);
712 if (which == MASK)
713 printf("Attempt to set XNS netmask will be ineffectual\n");
714 }
715
716 #define SISO(x) ((struct sockaddr_iso *) &(x))
717 struct sockaddr_iso *sisotab[] = {
718 SISO(iso_ridreq.ifr_Addr), SISO(iso_addreq.ifra_addr),
719 SISO(iso_addreq.ifra_mask), SISO(iso_addreq.ifra_dstaddr)};
720
721 void
722 iso_getaddr(addr, which)
723 char *addr;
724 int which;
725 {
726 register struct sockaddr_iso *siso = sisotab[which];
727 struct iso_addr *iso_addr();
728 siso->siso_addr = *iso_addr(addr);
729
730 if (which == MASK) {
731 siso->siso_len = TSEL(siso) - (caddr_t)(siso);
732 siso->siso_nlen = 0;
733 } else {
734 siso->siso_len = sizeof(*siso);
735 siso->siso_family = AF_ISO;
736 }
737 }
738
739 void
740 setnsellength(val)
741 char *val;
742 {
743 nsellength = atoi(val);
744 if (nsellength < 0)
745 errx(1, "Negative NSEL length is absurd");
746 if (afp == 0 || afp->af_af != AF_ISO)
747 errx(1, "Setting NSEL length valid only for iso");
748 }
749
750 void
751 fixnsel(s)
752 register struct sockaddr_iso *s;
753 {
754 if (s->siso_family == 0)
755 return;
756 s->siso_tlen = nsellength;
757 }
758
759 void
760 adjust_nsellength()
761 {
762 fixnsel(sisotab[RIDADDR]);
763 fixnsel(sisotab[ADDR]);
764 fixnsel(sisotab[DSTADDR]);
765 }
766