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