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