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