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