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