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