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