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