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