ifconfig.c revision 1.11 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.11 1993/12/10 11:29:42 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
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 { "link0", IFF_LINK0, setifflags },
111 { "-link0", -IFF_LINK0, setifflags },
112 { "link1", IFF_LINK1, setifflags },
113 { "-link1", -IFF_LINK1, setifflags },
114 { "link2", IFF_LINK2, setifflags },
115 { "-link2", -IFF_LINK2, 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\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2\20MULTICAST"
467
468 /*
469 * Print the status of the interface. If an address family was
470 * specified, show it and it only; otherwise, show them all.
471 */
472 status()
473 {
474 register struct afswtch *p = afp;
475 short af = ifr.ifr_addr.sa_family;
476
477 printf("%s: ", name);
478 printb("flags", flags, IFFBITS);
479 if (metric)
480 printf(" metric %d", metric);
481 putchar('\n');
482 if ((p = afp) != NULL) {
483 (*p->af_status)(1);
484 } else for (p = afs; p->af_name; p++) {
485 ifr.ifr_addr.sa_family = p->af_af;
486 (*p->af_status)(0);
487 }
488 }
489
490 in_status(force)
491 int force;
492 {
493 struct sockaddr_in *sin;
494 char *inet_ntoa();
495
496 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
497 if (ioctl(in_s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
498 if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
499 if (!force)
500 return;
501 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
502 } else
503 perror("ioctl (SIOCGIFADDR)");
504 }
505 sin = (struct sockaddr_in *)&ifr.ifr_addr;
506 printf("\tinet %s ", inet_ntoa(sin->sin_addr));
507 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
508 if (ioctl(in_s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) {
509 if (errno != EADDRNOTAVAIL)
510 perror("ioctl (SIOCGIFNETMASK)");
511 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
512 } else
513 netmask.sin_addr =
514 ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr;
515 if (flags & IFF_POINTOPOINT) {
516 if (ioctl(in_s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
517 if (errno == EADDRNOTAVAIL)
518 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
519 else
520 perror("ioctl (SIOCGIFDSTADDR)");
521 }
522 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
523 sin = (struct sockaddr_in *)&ifr.ifr_dstaddr;
524 printf("--> %s ", inet_ntoa(sin->sin_addr));
525 }
526 printf("netmask %x ", ntohl(netmask.sin_addr.s_addr));
527 if (flags & IFF_BROADCAST) {
528 if (ioctl(in_s, SIOCGIFBRDADDR, (caddr_t)&ifr) < 0) {
529 if (errno == EADDRNOTAVAIL)
530 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
531 else
532 perror("ioctl (SIOCGIFADDR)");
533 }
534 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
535 sin = (struct sockaddr_in *)&ifr.ifr_addr;
536 if (sin->sin_addr.s_addr != 0)
537 printf("broadcast %s", inet_ntoa(sin->sin_addr));
538 }
539 putchar('\n');
540 }
541
542 #ifdef NSIP
543
544 xns_status(force)
545 int force;
546 {
547 struct sockaddr_ns *sns;
548
549 if (xns_s < 0)
550 return;
551
552 if (ioctl(xns_s, SIOCGIFADDR, (caddr_t)&ifr) < 0) {
553 if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
554 if (!force)
555 return;
556 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
557 } else
558 perror("ioctl (SIOCGIFADDR)");
559 }
560 strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
561 sns = (struct sockaddr_ns *)&ifr.ifr_addr;
562 printf("\tns %s ", ns_ntoa(sns->sns_addr));
563 if (flags & IFF_POINTOPOINT) { /* by W. Nesheim@Cornell */
564 if (ioctl(xns_s, SIOCGIFDSTADDR, (caddr_t)&ifr) < 0) {
565 if (errno == EADDRNOTAVAIL)
566 bzero((char *)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
567 else
568 Perror("ioctl (SIOCGIFDSTADDR)");
569 }
570 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
571 sns = (struct sockaddr_ns *)&ifr.ifr_dstaddr;
572 printf("--> %s ", ns_ntoa(sns->sns_addr));
573 }
574 putchar('\n');
575 }
576
577 #endif
578 #ifdef EON
579 iso_status(force)
580 int force;
581 {
582 struct sockaddr_iso *siso;
583 struct iso_ifreq ifr;
584
585 if (iso_s < 0)
586 return;
587 bzero((caddr_t)&ifr, sizeof(ifr));
588 strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
589 if (ioctl(iso_s, SIOCGIFADDR_ISO, (caddr_t)&ifr) < 0) {
590 if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
591 if (!force)
592 return;
593 bzero((char *)&ifr.ifr_Addr, sizeof(ifr.ifr_Addr));
594 } else {
595 perror("ioctl (SIOCGIFADDR_ISO)");
596 exit(1);
597 }
598 }
599 strncpy(ifr.ifr_name, name, sizeof ifr.ifr_name);
600 siso = &ifr.ifr_Addr;
601 printf("\tiso %s ", iso_ntoa(&siso->siso_addr));
602 if (ioctl(iso_s, SIOCGIFNETMASK_ISO, (caddr_t)&ifr) < 0) {
603 if (errno != EADDRNOTAVAIL)
604 perror("ioctl (SIOCGIFNETMASK_ISO)");
605 } else {
606 printf(" netmask %s ", iso_ntoa(&siso->siso_addr));
607 }
608 if (flags & IFF_POINTOPOINT) {
609 if (ioctl(iso_s, SIOCGIFDSTADDR_ISO, (caddr_t)&ifr) < 0) {
610 if (errno == EADDRNOTAVAIL)
611 bzero((char *)&ifr.ifr_Addr, sizeof(ifr.ifr_Addr));
612 else
613 Perror("ioctl (SIOCGIFDSTADDR_ISO)");
614 }
615 strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
616 siso = &ifr.ifr_Addr;
617 printf("--> %s ", iso_ntoa(&siso->siso_addr));
618 }
619 putchar('\n');
620 }
621 #endif
622
623 Perror(cmd)
624 char *cmd;
625 {
626 extern int errno;
627
628 fprintf(stderr, "ifconfig: ");
629 switch (errno) {
630
631 case ENXIO:
632 fprintf(stderr, "%s: no such interface\n", cmd);
633 break;
634
635 case EPERM:
636 fprintf(stderr, "%s: permission denied\n", cmd);
637 break;
638
639 default:
640 perror(cmd);
641 }
642 exit(1);
643 }
644
645 struct in_addr inet_makeaddr();
646
647 #define SIN(x) ((struct sockaddr_in *) &(x))
648 struct sockaddr_in *sintab[] = {
649 SIN(ridreq.ifr_addr), SIN(addreq.ifra_addr),
650 SIN(addreq.ifra_mask), SIN(addreq.ifra_broadaddr)};
651
652 in_getaddr(s, which)
653 char *s;
654 {
655 register struct sockaddr_in *sin = sintab[which];
656 struct hostent *hp;
657 struct netent *np;
658 int val;
659
660 sin->sin_len = sizeof(*sin);
661 if (which != MASK)
662 sin->sin_family = AF_INET;
663
664 if ((val = inet_addr(s)) != -1)
665 sin->sin_addr.s_addr = val;
666 else if (hp = gethostbyname(s))
667 bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
668 else if (np = getnetbyname(s))
669 sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
670 else {
671 fprintf(stderr, "%s: bad value\n", s);
672 exit(1);
673 }
674 }
675
676 /*
677 * Print a value a la the %b format of the kernel's printf
678 */
679 printb(s, v, bits)
680 char *s;
681 register char *bits;
682 register unsigned short v;
683 {
684 register int i, any = 0;
685 register char c;
686
687 if (bits && *bits == 8)
688 printf("%s=%o", s, v);
689 else
690 printf("%s=%x", s, v);
691 bits++;
692 if (bits) {
693 putchar('<');
694 while (i = *bits++) {
695 if (v & (1 << (i-1))) {
696 if (any)
697 putchar(',');
698 any = 1;
699 for (; (c = *bits) > 32; bits++)
700 putchar(c);
701 } else
702 for (; *bits > 32; bits++)
703 ;
704 }
705 putchar('>');
706 }
707 }
708 #ifdef NSIP
709
710 #define SNS(x) ((struct sockaddr_ns *) &(x))
711 struct sockaddr_ns *snstab[] = {
712 SNS(ridreq.ifr_addr), SNS(addreq.ifra_addr),
713 SNS(addreq.ifra_mask), SNS(addreq.ifra_broadaddr)};
714
715 xns_getaddr(addr, which)
716 char *addr;
717 {
718 struct sockaddr_ns *sns = snstab[which];
719 struct ns_addr ns_addr();
720
721 sns->sns_family = AF_NS;
722 sns->sns_len = sizeof(*sns);
723 sns->sns_addr = ns_addr(addr);
724 if (which == MASK)
725 printf("Attempt to set XNS netmask will be ineffectual\n");
726 }
727
728 #endif
729 #ifdef EON
730 #define SISO(x) ((struct sockaddr_iso *) &(x))
731 struct sockaddr_iso *sisotab[] = {
732 SISO(iso_ridreq.ifr_Addr), SISO(iso_addreq.ifra_addr),
733 SISO(iso_addreq.ifra_mask), SISO(iso_addreq.ifra_dstaddr)};
734
735 iso_getaddr(addr, which)
736 char *addr;
737 {
738 register struct sockaddr_iso *siso = sisotab[which];
739 struct iso_addr *iso_addr();
740 siso->siso_addr = *iso_addr(addr);
741
742 if (which == MASK) {
743 siso->siso_len = TSEL(siso) - (caddr_t)(siso);
744 siso->siso_nlen = 0;
745 } else {
746 siso->siso_len = sizeof(*siso);
747 siso->siso_family = AF_ISO;
748 }
749 }
750 #endif
751
752 setnsellength(val)
753 char *val;
754 {
755 nsellength = atoi(val);
756 if (nsellength < 0) {
757 fprintf(stderr, "Negative NSEL length is absurd\n");
758 exit (1);
759 }
760 if (afp == 0 || afp->af_af != AF_ISO) {
761 fprintf(stderr, "Setting NSEL length valid only for iso\n");
762 exit (1);
763 }
764 }
765
766 #ifdef EON
767 fixnsel(s)
768 register struct sockaddr_iso *s;
769 {
770 if (s->siso_family == 0)
771 return;
772 s->siso_tlen = nsellength;
773 }
774 #endif
775
776 adjust_nsellength()
777 {
778 #ifdef EON
779 fixnsel(sisotab[RIDADDR]);
780 fixnsel(sisotab[ADDR]);
781 fixnsel(sisotab[DSTADDR]);
782 #endif
783 }
784