1 /* $OpenBSD: addrtoname.c,v 1.17 2000/11/23 18:32:20 jakob Exp $ */ 2 3 /* 4 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 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: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 * 23 * Internet, ethernet, port, and protocol string to address 24 * and address to string conversion routines 25 */ 26 #ifndef lint 27 static const char rcsid[] = 28 "@(#) $Header: /home/cvs/src/usr.sbin/tcpdump/addrtoname.c,v 1.17 2000/11/23 18:32:20 jakob Exp $ (LBL)"; 29 #endif 30 31 #include <sys/types.h> 32 #include <sys/socket.h> 33 #include <sys/time.h> 34 35 #ifdef __STDC__ 36 struct mbuf; 37 struct rtentry; 38 #endif 39 #include <net/if.h> 40 41 #include <netinet/in.h> 42 #include <netinet/if_ether.h> 43 44 #ifdef INET6 45 #include <netinet/ip6.h> 46 #endif 47 48 #include <arpa/inet.h> 49 50 #include <ctype.h> 51 #include <netdb.h> 52 #include <pcap.h> 53 #include <pcap-namedb.h> 54 #ifdef HAVE_MEMORY_H 55 #include <memory.h> 56 #endif 57 #include <signal.h> 58 #include <stdio.h> 59 #include <string.h> 60 #include <stdlib.h> 61 #include <unistd.h> 62 63 #include "interface.h" 64 #include "addrtoname.h" 65 #include "llc.h" 66 #include "savestr.h" 67 #include "setsignal.h" 68 69 /* Forwards */ 70 static RETSIGTYPE nohostname(int); 71 72 /* 73 * hash tables for whatever-to-name translations 74 */ 75 76 #define HASHNAMESIZE 4096 77 78 struct hnamemem { 79 u_int32_t addr; 80 char *name; 81 struct hnamemem *nxt; 82 }; 83 84 struct hnamemem hnametable[HASHNAMESIZE]; 85 struct hnamemem tporttable[HASHNAMESIZE]; 86 struct hnamemem uporttable[HASHNAMESIZE]; 87 struct hnamemem eprototable[HASHNAMESIZE]; 88 struct hnamemem dnaddrtable[HASHNAMESIZE]; 89 struct hnamemem llcsaptable[HASHNAMESIZE]; 90 91 #ifdef INET6 92 struct h6namemem { 93 struct in6_addr addr; 94 char *name; 95 struct h6namemem *nxt; 96 }; 97 98 struct h6namemem h6nametable[HASHNAMESIZE]; 99 #endif /* INET6 */ 100 101 struct enamemem { 102 u_short e_addr0; 103 u_short e_addr1; 104 u_short e_addr2; 105 char *e_name; 106 u_char *e_nsap; /* used only for nsaptable[] */ 107 #define e_bs e_nsap /* for bytestringtable */ 108 struct enamemem *e_nxt; 109 }; 110 111 struct enamemem enametable[HASHNAMESIZE]; 112 struct enamemem nsaptable[HASHNAMESIZE]; 113 struct enamemem bytestringtable[HASHNAMESIZE]; 114 115 struct protoidmem { 116 u_int32_t p_oui; 117 u_short p_proto; 118 char *p_name; 119 struct protoidmem *p_nxt; 120 }; 121 122 struct protoidmem protoidtable[HASHNAMESIZE]; 123 124 /* 125 * A faster replacement for inet_ntoa(). 126 */ 127 char * 128 intoa(u_int32_t addr) 129 { 130 register char *cp; 131 register u_int byte; 132 register int n; 133 static char buf[sizeof(".xxx.xxx.xxx.xxx")]; 134 135 NTOHL(addr); 136 cp = &buf[sizeof buf]; 137 *--cp = '\0'; 138 139 n = 4; 140 do { 141 byte = addr & 0xff; 142 *--cp = byte % 10 + '0'; 143 byte /= 10; 144 if (byte > 0) { 145 *--cp = byte % 10 + '0'; 146 byte /= 10; 147 if (byte > 0) 148 *--cp = byte + '0'; 149 } 150 *--cp = '.'; 151 addr >>= 8; 152 } while (--n > 0); 153 154 return cp + 1; 155 } 156 157 static u_int32_t f_netmask; 158 static u_int32_t f_localnet; 159 static u_int32_t netmask; 160 161 /* 162 * "getname" is written in this atrocious way to make sure we don't 163 * wait forever while trying to get hostnames from yp. 164 */ 165 #include <setjmp.h> 166 167 jmp_buf getname_env; 168 169 static RETSIGTYPE 170 nohostname(int signo) 171 { 172 longjmp(getname_env, 1); 173 } 174 175 /* 176 * Return a name for the IP address pointed to by ap. This address 177 * is assumed to be in network byte order. 178 */ 179 char * 180 getname(const u_char *ap) 181 { 182 register struct hostent *hp; 183 u_int32_t addr; 184 static struct hnamemem *p; /* static for longjmp() */ 185 186 #ifndef LBL_ALIGN 187 addr = *(const u_int32_t *)ap; 188 #else 189 /* 190 * Extract 32 bits in network order, dealing with alignment. 191 */ 192 switch ((long)ap & 3) { 193 194 case 0: 195 addr = *(u_int32_t *)ap; 196 break; 197 198 case 2: 199 #if BYTE_ORDER == BIG_ENDIAN 200 addr = ((u_int32_t)*(u_short *)ap << 16) | 201 (u_int32_t)*(u_short *)(ap + 2); 202 #else 203 addr = ((u_int32_t)*(u_short *)(ap + 2) << 16) | 204 (u_int32_t)*(u_short *)ap; 205 #endif 206 break; 207 208 default: 209 #if BYTE_ORDER == BIG_ENDIAN 210 addr = ((u_int32_t)ap[0] << 24) | 211 ((u_int32_t)ap[1] << 16) | 212 ((u_int32_t)ap[2] << 8) | 213 (u_int32_t)ap[3]; 214 #else 215 addr = ((u_int32_t)ap[3] << 24) | 216 ((u_int32_t)ap[2] << 16) | 217 ((u_int32_t)ap[1] << 8) | 218 (u_int32_t)ap[0]; 219 #endif 220 break; 221 } 222 #endif 223 p = &hnametable[addr & (HASHNAMESIZE-1)]; 224 for (; p->nxt; p = p->nxt) { 225 if (p->addr == addr) 226 return (p->name); 227 } 228 p->addr = addr; 229 p->nxt = newhnamemem(); 230 231 /* 232 * Only print names when: 233 * (1) -n was not given. 234 * (2) Address is foreign and -f was given. (If -f was not 235 * give, f_netmask and f_local are 0 and the test 236 * evaluates to true) 237 * (3) -a was given or the host portion is not all ones 238 * nor all zeros (i.e. not a network or broadcast address) 239 */ 240 if (!nflag && 241 (addr & f_netmask) == f_localnet && 242 (aflag || 243 !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))) { 244 if (!setjmp(getname_env)) { 245 (void)setsignal(SIGALRM, nohostname); 246 (void)alarm(20); 247 hp = gethostbyaddr((char *)&addr, 4, AF_INET); 248 (void)alarm(0); 249 if (hp) { 250 char *dotp; 251 252 p->name = savestr(hp->h_name); 253 if (Nflag) { 254 /* Remove domain qualifications */ 255 dotp = strchr(p->name, '.'); 256 if (dotp) 257 *dotp = '\0'; 258 } 259 return (p->name); 260 } 261 } 262 } 263 p->name = savestr(intoa(addr)); 264 return (p->name); 265 } 266 267 #ifdef INET6 268 /* 269 * Return a name for the IP6 address pointed to by ap. This address 270 * is assumed to be in network byte order. 271 */ 272 char * 273 getname6(const u_char *ap) 274 { 275 register struct hostent *hp; 276 struct in6_addr addr; 277 static struct h6namemem *p; /* static for longjmp() */ 278 register char *cp; 279 char ntop_buf[INET6_ADDRSTRLEN]; 280 281 memcpy(&addr, ap, sizeof(addr)); 282 p = &h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)]; 283 for (; p->nxt; p = p->nxt) { 284 if (memcmp(&p->addr, &addr, sizeof(addr)) == 0) 285 return (p->name); 286 } 287 p->addr = addr; 288 p->nxt = newh6namemem(); 289 290 /* 291 * Only print names when: 292 * (1) -n was not given. 293 * (2) Address is foreign and -f was given. (If -f was not 294 * give, f_netmask and f_local are 0 and the test 295 * evaluates to true) 296 * (3) -a was given or the host portion is not all ones 297 * nor all zeros (i.e. not a network or broadcast address) 298 */ 299 if (!nflag 300 #if 0 301 && 302 (addr & f_netmask) == f_localnet && 303 (aflag || 304 !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff)) 305 #endif 306 ) { 307 if (!setjmp(getname_env)) { 308 (void)setsignal(SIGALRM, nohostname); 309 (void)alarm(20); 310 hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6); 311 (void)alarm(0); 312 if (hp) { 313 char *dotp; 314 315 p->name = savestr(hp->h_name); 316 if (Nflag) { 317 /* Remove domain qualifications */ 318 dotp = strchr(p->name, '.'); 319 if (dotp) 320 *dotp = '\0'; 321 } 322 return (p->name); 323 } 324 } 325 } 326 cp = (char *)inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf)); 327 p->name = savestr(cp); 328 return (p->name); 329 } 330 #endif /* INET6 */ 331 332 static char hex[] = "0123456789abcdef"; 333 334 335 /* Find the hash node that corresponds the ether address 'ep' */ 336 337 static inline struct enamemem * 338 lookup_emem(const u_char *ep) 339 { 340 register u_int i, j, k; 341 struct enamemem *tp; 342 343 k = (ep[0] << 8) | ep[1]; 344 j = (ep[2] << 8) | ep[3]; 345 i = (ep[4] << 8) | ep[5]; 346 347 tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)]; 348 while (tp->e_nxt) 349 if (tp->e_addr0 == i && 350 tp->e_addr1 == j && 351 tp->e_addr2 == k) 352 return tp; 353 else 354 tp = tp->e_nxt; 355 tp->e_addr0 = i; 356 tp->e_addr1 = j; 357 tp->e_addr2 = k; 358 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 359 if (tp->e_nxt == NULL) 360 error("lookup_emem: calloc"); 361 362 return tp; 363 } 364 365 /* 366 * Find the hash node that corresponds to the bytestring 'bs' 367 * with length 'nlen' 368 */ 369 370 static inline struct enamemem * 371 lookup_bytestring(register const u_char *bs, const int nlen) 372 { 373 struct enamemem *tp; 374 register u_int i, j, k; 375 376 if (nlen >= 6) { 377 k = (bs[0] << 8) | bs[1]; 378 j = (bs[2] << 8) | bs[3]; 379 i = (bs[4] << 8) | bs[5]; 380 } else if (nlen >= 4) { 381 k = (bs[0] << 8) | bs[1]; 382 j = (bs[2] << 8) | bs[3]; 383 i = 0; 384 } else 385 i = j = k = 0; 386 387 tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)]; 388 while (tp->e_nxt) 389 if (tp->e_addr0 == i && 390 tp->e_addr1 == j && 391 tp->e_addr2 == k && 392 bcmp((char *)bs, (char *)(tp->e_bs), nlen) == 0) 393 return tp; 394 else 395 tp = tp->e_nxt; 396 397 tp->e_addr0 = i; 398 tp->e_addr1 = j; 399 tp->e_addr2 = k; 400 401 tp->e_bs = (u_char *) calloc(1, nlen + 1); 402 bcopy(bs, tp->e_bs, nlen); 403 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 404 if (tp->e_nxt == NULL) 405 error("lookup_bytestring: calloc"); 406 407 return tp; 408 } 409 410 /* Find the hash node that corresponds the NSAP 'nsap' */ 411 412 static inline struct enamemem * 413 lookup_nsap(register const u_char *nsap) 414 { 415 register u_int i, j, k; 416 int nlen = *nsap; 417 struct enamemem *tp; 418 const u_char *ensap = nsap + nlen - 6; 419 420 if (nlen > 6) { 421 k = (ensap[0] << 8) | ensap[1]; 422 j = (ensap[2] << 8) | ensap[3]; 423 i = (ensap[4] << 8) | ensap[5]; 424 } 425 else 426 i = j = k = 0; 427 428 tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)]; 429 while (tp->e_nxt) 430 if (tp->e_addr0 == i && 431 tp->e_addr1 == j && 432 tp->e_addr2 == k && 433 tp->e_nsap[0] == nlen && 434 memcmp((char *)&(nsap[1]), 435 (char *)&(tp->e_nsap[1]), nlen) == 0) 436 return tp; 437 else 438 tp = tp->e_nxt; 439 tp->e_addr0 = i; 440 tp->e_addr1 = j; 441 tp->e_addr2 = k; 442 tp->e_nsap = (u_char *)malloc(nlen + 1); 443 if (tp->e_nsap == NULL) 444 error("lookup_nsap: malloc"); 445 memcpy((char *)tp->e_nsap, (char *)nsap, nlen + 1); 446 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 447 if (tp->e_nxt == NULL) 448 error("lookup_nsap: calloc"); 449 450 return tp; 451 } 452 453 /* Find the hash node that corresponds the protoid 'pi'. */ 454 455 static inline struct protoidmem * 456 lookup_protoid(const u_char *pi) 457 { 458 register u_int i, j; 459 struct protoidmem *tp; 460 461 /* 5 octets won't be aligned */ 462 i = (((pi[0] << 8) + pi[1]) << 8) + pi[2]; 463 j = (pi[3] << 8) + pi[4]; 464 /* XXX should be endian-insensitive, but do big-endian testing XXX */ 465 466 tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)]; 467 while (tp->p_nxt) 468 if (tp->p_oui == i && tp->p_proto == j) 469 return tp; 470 else 471 tp = tp->p_nxt; 472 tp->p_oui = i; 473 tp->p_proto = j; 474 tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp)); 475 if (tp->p_nxt == NULL) 476 error("lookup_protoid: calloc"); 477 478 return tp; 479 } 480 481 char * 482 etheraddr_string(register const u_char *ep) 483 { 484 register u_int i, j; 485 register char *cp; 486 register struct enamemem *tp; 487 char buf[sizeof("00:00:00:00:00:00")]; 488 489 tp = lookup_emem(ep); 490 if (tp->e_name) 491 return (tp->e_name); 492 #ifdef HAVE_ETHER_NTOHOST 493 if (!nflag) { 494 char buf[MAXHOSTNAMELEN + 1]; 495 if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) { 496 tp->e_name = savestr(buf); 497 return (tp->e_name); 498 } 499 } 500 #endif 501 cp = buf; 502 if ((j = *ep >> 4) != 0) 503 *cp++ = hex[j]; 504 *cp++ = hex[*ep++ & 0xf]; 505 for (i = 5; (int)--i >= 0;) { 506 *cp++ = ':'; 507 if ((j = *ep >> 4) != 0) 508 *cp++ = hex[j]; 509 *cp++ = hex[*ep++ & 0xf]; 510 } 511 *cp = '\0'; 512 tp->e_name = savestr(buf); 513 return (tp->e_name); 514 } 515 516 char * 517 linkaddr_string(const u_char *ep, const int len) 518 { 519 register u_int i, j; 520 register char *cp; 521 register struct enamemem *tp; 522 523 if (len == 6) /* XXX not totally correct... */ 524 return etheraddr_string(ep); 525 526 tp = lookup_bytestring(ep, len); 527 if (tp->e_name) 528 return (tp->e_name); 529 530 tp->e_name = cp = (char *)malloc(len*3); 531 if (tp->e_name == NULL) 532 error("linkaddr_string: malloc"); 533 if ((j = *ep >> 4) != 0) 534 *cp++ = hex[j]; 535 *cp++ = hex[*ep++ & 0xf]; 536 for (i = len-1; i > 0 ; --i) { 537 *cp++ = ':'; 538 if ((j = *ep >> 4) != 0) 539 *cp++ = hex[j]; 540 *cp++ = hex[*ep++ & 0xf]; 541 } 542 *cp = '\0'; 543 return (tp->e_name); 544 } 545 546 char * 547 etherproto_string(u_short port) 548 { 549 register char *cp; 550 register struct hnamemem *tp; 551 register u_int32_t i = port; 552 char buf[sizeof("0000")]; 553 554 for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 555 if (tp->addr == i) 556 return (tp->name); 557 558 tp->addr = i; 559 tp->nxt = newhnamemem(); 560 561 cp = buf; 562 NTOHS(port); 563 *cp++ = hex[port >> 12 & 0xf]; 564 *cp++ = hex[port >> 8 & 0xf]; 565 *cp++ = hex[port >> 4 & 0xf]; 566 *cp++ = hex[port & 0xf]; 567 *cp++ = '\0'; 568 tp->name = savestr(buf); 569 return (tp->name); 570 } 571 572 char * 573 protoid_string(register const u_char *pi) 574 { 575 register u_int i, j; 576 register char *cp; 577 register struct protoidmem *tp; 578 char buf[sizeof("00:00:00:00:00")]; 579 580 tp = lookup_protoid(pi); 581 if (tp->p_name) 582 return tp->p_name; 583 584 cp = buf; 585 if ((j = *pi >> 4) != 0) 586 *cp++ = hex[j]; 587 *cp++ = hex[*pi++ & 0xf]; 588 for (i = 4; (int)--i >= 0;) { 589 *cp++ = ':'; 590 if ((j = *pi >> 4) != 0) 591 *cp++ = hex[j]; 592 *cp++ = hex[*pi++ & 0xf]; 593 } 594 *cp = '\0'; 595 tp->p_name = savestr(buf); 596 return (tp->p_name); 597 } 598 599 char * 600 llcsap_string(u_char sap) 601 { 602 register struct hnamemem *tp; 603 register u_int32_t i = sap; 604 char buf[sizeof("sap 00")]; 605 606 for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 607 if (tp->addr == i) 608 return (tp->name); 609 610 tp->addr = i; 611 tp->nxt = newhnamemem(); 612 613 snprintf(buf, sizeof(buf), "sap %02x", sap & 0xff); 614 tp->name = savestr(buf); 615 return (tp->name); 616 } 617 618 char * 619 isonsap_string(const u_char *nsap) 620 { 621 register u_int i, nlen = nsap[0]; 622 register char *cp; 623 register struct enamemem *tp; 624 625 tp = lookup_nsap(nsap); 626 if (tp->e_name) 627 return tp->e_name; 628 629 tp->e_name = cp = (char *)malloc(nlen * 2 + 2); 630 if (cp == NULL) 631 error("isonsap_string: malloc"); 632 633 nsap++; 634 *cp++ = '/'; 635 for (i = nlen; (int)--i >= 0;) { 636 *cp++ = hex[*nsap >> 4]; 637 *cp++ = hex[*nsap++ & 0xf]; 638 } 639 *cp = '\0'; 640 return (tp->e_name); 641 } 642 643 char * 644 tcpport_string(u_short port) 645 { 646 register struct hnamemem *tp; 647 register u_int32_t i = port; 648 char buf[sizeof("00000")]; 649 650 for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 651 if (tp->addr == i) 652 return (tp->name); 653 654 tp->addr = i; 655 tp->nxt = newhnamemem(); 656 657 (void)snprintf(buf, sizeof(buf), "%u", i); 658 tp->name = savestr(buf); 659 return (tp->name); 660 } 661 662 char * 663 udpport_string(register u_short port) 664 { 665 register struct hnamemem *tp; 666 register u_int32_t i = port; 667 char buf[sizeof("00000")]; 668 669 for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 670 if (tp->addr == i) 671 return (tp->name); 672 673 tp->addr = i; 674 tp->nxt = newhnamemem(); 675 676 (void)snprintf(buf, sizeof(buf), "%u", i); 677 tp->name = savestr(buf); 678 return (tp->name); 679 } 680 681 static void 682 init_servarray(void) 683 { 684 struct servent *sv; 685 register struct hnamemem *table; 686 register int i; 687 char buf[sizeof("0000000000")]; 688 689 while ((sv = getservent()) != NULL) { 690 int port = ntohs(sv->s_port); 691 i = port & (HASHNAMESIZE-1); 692 if (strcmp(sv->s_proto, "tcp") == 0) 693 table = &tporttable[i]; 694 else if (strcmp(sv->s_proto, "udp") == 0) 695 table = &uporttable[i]; 696 else 697 continue; 698 699 while (table->name) 700 table = table->nxt; 701 if (nflag) { 702 (void)snprintf(buf, sizeof(buf), "%d", port); 703 table->name = savestr(buf); 704 } else 705 table->name = savestr(sv->s_name); 706 table->addr = port; 707 table->nxt = newhnamemem(); 708 } 709 endservent(); 710 } 711 712 /*XXX from libbpfc.a */ 713 extern struct eproto { 714 char *s; 715 u_short p; 716 } eproto_db[]; 717 718 static void 719 init_eprotoarray(void) 720 { 721 register int i; 722 register struct hnamemem *table; 723 724 for (i = 0; eproto_db[i].s; i++) { 725 int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1); 726 table = &eprototable[j]; 727 while (table->name) 728 table = table->nxt; 729 table->name = eproto_db[i].s; 730 table->addr = ntohs(eproto_db[i].p); 731 table->nxt = newhnamemem(); 732 } 733 } 734 735 /* 736 * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet 737 * types. 738 */ 739 static void 740 init_protoidarray(void) 741 { 742 register int i; 743 register struct protoidmem *tp; 744 u_char protoid[5]; 745 746 protoid[0] = 0; 747 protoid[1] = 0; 748 protoid[2] = 0; 749 for (i = 0; eproto_db[i].s; i++) { 750 u_short etype = htons(eproto_db[i].p); 751 752 memcpy((char *)&protoid[3], (char *)&etype, 2); 753 tp = lookup_protoid(protoid); 754 tp->p_name = savestr(eproto_db[i].s); 755 } 756 } 757 758 static struct etherlist { 759 u_char addr[6]; 760 char *name; 761 } etherlist[] = { 762 {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" }, 763 {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL } 764 }; 765 766 /* 767 * Initialize the ethers hash table. We take two different approaches 768 * depending on whether or not the system provides the ethers name 769 * service. If it does, we just wire in a few names at startup, 770 * and etheraddr_string() fills in the table on demand. If it doesn't, 771 * then we suck in the entire /etc/ethers file at startup. The idea 772 * is that parsing the local file will be fast, but spinning through 773 * all the ethers entries via NIS & next_etherent might be very slow. 774 * 775 * XXX pcap_next_etherent doesn't belong in the pcap interface, but 776 * since the pcap module already does name-to-address translation, 777 * it's already does most of the work for the ethernet address-to-name 778 * translation, so we just pcap_next_etherent as a convenience. 779 */ 780 static void 781 init_etherarray(void) 782 { 783 register struct etherlist *el; 784 register struct enamemem *tp; 785 #ifdef HAVE_ETHER_NTOHOST 786 char name[MAXHOSTNAMELEN + 1]; 787 #else 788 register struct pcap_etherent *ep; 789 register FILE *fp; 790 791 /* Suck in entire ethers file */ 792 fp = fopen(PCAP_ETHERS_FILE, "r"); 793 if (fp != NULL) { 794 while ((ep = pcap_next_etherent(fp)) != NULL) { 795 tp = lookup_emem(ep->addr); 796 tp->e_name = savestr(ep->name); 797 } 798 (void)fclose(fp); 799 } 800 #endif 801 802 /* Hardwire some ethernet names */ 803 for (el = etherlist; el->name != NULL; ++el) { 804 tp = lookup_emem(el->addr); 805 /* Don't override existing name */ 806 if (tp->e_name != NULL) 807 continue; 808 809 #ifdef HAVE_ETHER_NTOHOST 810 /* Use yp/nis version of name if available */ 811 if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) { 812 tp->e_name = savestr(name); 813 continue; 814 } 815 #endif 816 tp->e_name = el->name; 817 } 818 } 819 820 static struct tok llcsap_db[] = { 821 { LLCSAP_NULL, "null" }, 822 { LLCSAP_8021B_I, "802.1b-gsap" }, 823 { LLCSAP_8021B_G, "802.1b-isap" }, 824 { LLCSAP_IP, "ip-sap" }, 825 { LLCSAP_PROWAYNM, "proway-nm" }, 826 { LLCSAP_8021D, "802.1d" }, 827 { LLCSAP_RS511, "eia-rs511" }, 828 { LLCSAP_ISO8208, "x.25/llc2" }, 829 { LLCSAP_PROWAY, "proway" }, 830 { LLCSAP_ISONS, "iso-clns" }, 831 { LLCSAP_GLOBAL, "global" }, 832 { 0, NULL } 833 }; 834 835 static void 836 init_llcsaparray(void) 837 { 838 register int i; 839 register struct hnamemem *table; 840 841 for (i = 0; llcsap_db[i].s != NULL; i++) { 842 table = &llcsaptable[llcsap_db[i].v]; 843 while (table->name) 844 table = table->nxt; 845 table->name = llcsap_db[i].s; 846 table->addr = llcsap_db[i].v; 847 table->nxt = newhnamemem(); 848 } 849 } 850 851 /* 852 * Initialize the address to name translation machinery. We map all 853 * non-local IP addresses to numeric addresses if fflag is true (i.e., 854 * to prevent blocking on the nameserver). localnet is the IP address 855 * of the local network. mask is its subnet mask. 856 */ 857 void 858 init_addrtoname(u_int32_t localnet, u_int32_t mask) 859 { 860 netmask = mask; 861 if (fflag) { 862 f_localnet = localnet; 863 f_netmask = mask; 864 } 865 if (nflag) 866 /* 867 * Simplest way to suppress names. 868 */ 869 return; 870 871 init_etherarray(); 872 init_servarray(); 873 init_eprotoarray(); 874 init_llcsaparray(); 875 init_protoidarray(); 876 } 877 878 char * 879 dnaddr_string(u_short dnaddr) 880 { 881 register struct hnamemem *tp; 882 883 for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0; 884 tp = tp->nxt) 885 if (tp->addr == dnaddr) 886 return (tp->name); 887 888 tp->addr = dnaddr; 889 tp->nxt = newhnamemem(); 890 if (nflag) 891 tp->name = dnnum_string(dnaddr); 892 else 893 tp->name = dnname_string(dnaddr); 894 895 return(tp->name); 896 } 897 898 /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */ 899 struct hnamemem * 900 newhnamemem(void) 901 { 902 register struct hnamemem *p; 903 static struct hnamemem *ptr = NULL; 904 static u_int num = 0; 905 906 if (num <= 0) { 907 num = 64; 908 ptr = (struct hnamemem *)calloc(num, sizeof (*ptr)); 909 if (ptr == NULL) 910 error("newhnamemem: calloc"); 911 } 912 --num; 913 p = ptr++; 914 return (p); 915 } 916 917 #ifdef INET6 918 /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */ 919 struct h6namemem * 920 newh6namemem(void) 921 { 922 register struct h6namemem *p; 923 static struct h6namemem *ptr = NULL; 924 static u_int num = 0; 925 926 if (num <= 0) { 927 num = 64; 928 ptr = (struct h6namemem *)calloc(num, sizeof (*ptr)); 929 if (ptr == NULL) 930 error("newh6namemem: calloc"); 931 } 932 --num; 933 p = ptr++; 934 return (p); 935 } 936 #endif /* INET6 */ 937