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