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