1 /* $OpenBSD: addrtoname.c,v 1.30 2007/10/07 16:41:05 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 #ifndef lint 27 static const char rcsid[] = 28 "@(#) $Id: addrtoname.c,v 1.30 2007/10/07 16:41:05 deraadt Exp $ (LBL)"; 29 #endif 30 31 #include <sys/param.h> 32 #include <sys/socket.h> 33 #include <sys/time.h> 34 #include <sys/types.h> 35 36 struct mbuf; 37 struct rtentry; 38 #include <net/if.h> 39 40 #include <netinet/in.h> 41 #include <netinet/if_ether.h> 42 43 #ifdef INET6 44 #include <netinet/ip6.h> 45 #endif 46 47 #include <arpa/inet.h> 48 49 #include <ctype.h> 50 #include <inttypes.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 "privsep.h" 67 #include "savestr.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 static char *ipprototable[256]; 112 113 struct protoidmem { 114 u_int32_t p_oui; 115 u_short p_proto; 116 char *p_name; 117 struct protoidmem *p_nxt; 118 }; 119 120 struct protoidmem protoidtable[HASHNAMESIZE]; 121 122 /* 123 * A faster replacement for inet_ntoa(). 124 */ 125 char * 126 intoa(u_int32_t addr) 127 { 128 register char *cp; 129 register u_int byte; 130 register int n; 131 static char buf[sizeof(".xxx.xxx.xxx.xxx")]; 132 133 NTOHL(addr); 134 cp = &buf[sizeof buf]; 135 *--cp = '\0'; 136 137 n = 4; 138 do { 139 byte = addr & 0xff; 140 *--cp = byte % 10 + '0'; 141 byte /= 10; 142 if (byte > 0) { 143 *--cp = byte % 10 + '0'; 144 byte /= 10; 145 if (byte > 0) 146 *--cp = byte + '0'; 147 } 148 *--cp = '.'; 149 addr >>= 8; 150 } while (--n > 0); 151 152 return cp + 1; 153 } 154 155 static u_int32_t f_netmask; 156 static u_int32_t f_localnet; 157 static u_int32_t netmask; 158 159 /* 160 * Return a name for the IP address pointed to by ap. This address 161 * is assumed to be in network byte order. 162 */ 163 char * 164 getname(const u_char *ap) 165 { 166 char host[MAXHOSTNAMELEN]; 167 u_int32_t addr; 168 struct hnamemem *p; 169 170 /* 171 * Extract 32 bits in network order, dealing with alignment. 172 */ 173 switch ((intptr_t)ap & (sizeof(u_int32_t)-1)) { 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 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 size_t n = priv_gethostbyaddr((char *)&addr, sizeof(addr), 226 AF_INET, host, sizeof(host)); 227 if (n > 0) { 228 char *dotp; 229 230 p->name = savestr(host); 231 if (Nflag) { 232 /* Remove domain qualifications */ 233 dotp = strchr(p->name, '.'); 234 if (dotp) 235 *dotp = '\0'; 236 } 237 return (p->name); 238 } 239 } 240 p->name = savestr(intoa(addr)); 241 return (p->name); 242 } 243 244 #ifdef INET6 245 /* 246 * Return a name for the IP6 address pointed to by ap. This address 247 * is assumed to be in network byte order. 248 */ 249 char * 250 getname6(const u_char *ap) 251 { 252 char host[MAXHOSTNAMELEN]; 253 struct in6_addr addr; 254 struct h6namemem *p; 255 register char *cp; 256 char ntop_buf[INET6_ADDRSTRLEN]; 257 258 memcpy(&addr, ap, sizeof(addr)); 259 p = &h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)]; 260 for (; p->nxt; p = p->nxt) { 261 if (memcmp(&p->addr, &addr, sizeof(addr)) == 0) 262 return (p->name); 263 } 264 p->addr = addr; 265 p->nxt = newh6namemem(); 266 267 /* 268 * Only print names when: 269 * (1) -n was not given 270 * (2) Address is foreign and -f was given. (If -f was not 271 * give, f_netmask and f_local are 0 and the test 272 * evaluates to true) 273 * (3) -a was given or the host portion is not all ones 274 * nor all zeros (i.e. not a network or broadcast address) 275 */ 276 if (!nflag 277 #if 0 278 && 279 (addr & f_netmask) == f_localnet && 280 (aflag || 281 !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff)) 282 #endif 283 ) { 284 size_t n = priv_gethostbyaddr((char *)&addr, sizeof(addr), 285 AF_INET6, host, sizeof(host)); 286 if (n > 0) { 287 char *dotp; 288 289 p->name = savestr(host); 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 if (tp->e_bs == NULL) 376 error("lookup_bytestring: calloc"); 377 bcopy(bs, tp->e_bs, nlen); 378 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 379 if (tp->e_nxt == NULL) 380 error("lookup_bytestring: calloc"); 381 382 return tp; 383 } 384 385 /* Find the hash node that corresponds the NSAP 'nsap' */ 386 387 static inline struct enamemem * 388 lookup_nsap(register const u_char *nsap) 389 { 390 register u_int i, j, k; 391 int nlen = *nsap; 392 struct enamemem *tp; 393 const u_char *ensap = nsap + nlen - 6; 394 395 if (nlen > 6) { 396 k = (ensap[0] << 8) | ensap[1]; 397 j = (ensap[2] << 8) | ensap[3]; 398 i = (ensap[4] << 8) | ensap[5]; 399 } 400 else 401 i = j = k = 0; 402 403 tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)]; 404 while (tp->e_nxt) 405 if (tp->e_addr0 == i && 406 tp->e_addr1 == j && 407 tp->e_addr2 == k && 408 tp->e_nsap[0] == nlen && 409 memcmp((char *)&(nsap[1]), 410 (char *)&(tp->e_nsap[1]), nlen) == 0) 411 return tp; 412 else 413 tp = tp->e_nxt; 414 tp->e_addr0 = i; 415 tp->e_addr1 = j; 416 tp->e_addr2 = k; 417 tp->e_nsap = (u_char *)malloc(nlen + 1); 418 if (tp->e_nsap == NULL) 419 error("lookup_nsap: malloc"); 420 memcpy((char *)tp->e_nsap, (char *)nsap, nlen + 1); 421 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 422 if (tp->e_nxt == NULL) 423 error("lookup_nsap: calloc"); 424 425 return tp; 426 } 427 428 /* Find the hash node that corresponds the protoid 'pi'. */ 429 430 static inline struct protoidmem * 431 lookup_protoid(const u_char *pi) 432 { 433 register u_int i, j; 434 struct protoidmem *tp; 435 436 /* 5 octets won't be aligned */ 437 i = (((pi[0] << 8) + pi[1]) << 8) + pi[2]; 438 j = (pi[3] << 8) + pi[4]; 439 /* XXX should be endian-insensitive, but do big-endian testing XXX */ 440 441 tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)]; 442 while (tp->p_nxt) 443 if (tp->p_oui == i && tp->p_proto == j) 444 return tp; 445 else 446 tp = tp->p_nxt; 447 tp->p_oui = i; 448 tp->p_proto = j; 449 tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp)); 450 if (tp->p_nxt == NULL) 451 error("lookup_protoid: calloc"); 452 453 return tp; 454 } 455 456 char * 457 etheraddr_string(register const u_char *ep) 458 { 459 register struct enamemem *tp; 460 struct ether_addr e; 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 (priv_ether_ntohost(buf, sizeof(buf), 469 (struct ether_addr *)ep) > 0) { 470 tp->e_name = savestr(buf); 471 return (tp->e_name); 472 } 473 } 474 #endif 475 memcpy(e.ether_addr_octet, ep, sizeof(e.ether_addr_octet)); 476 tp->e_name = savestr(ether_ntoa(&e)); 477 return (tp->e_name); 478 } 479 480 char * 481 linkaddr_string(const u_char *ep, const int len) 482 { 483 register u_int i, j; 484 register char *cp; 485 register struct enamemem *tp; 486 487 if (len == 6) /* XXX not totally correct... */ 488 return etheraddr_string(ep); 489 490 tp = lookup_bytestring(ep, len); 491 if (tp->e_name) 492 return (tp->e_name); 493 494 tp->e_name = cp = (char *)malloc(len*3); 495 if (tp->e_name == NULL) 496 error("linkaddr_string: malloc"); 497 if ((j = *ep >> 4) != 0) 498 *cp++ = hex[j]; 499 *cp++ = hex[*ep++ & 0xf]; 500 for (i = len-1; i > 0 ; --i) { 501 *cp++ = ':'; 502 if ((j = *ep >> 4) != 0) 503 *cp++ = hex[j]; 504 *cp++ = hex[*ep++ & 0xf]; 505 } 506 *cp = '\0'; 507 return (tp->e_name); 508 } 509 510 char * 511 etherproto_string(u_short port) 512 { 513 register char *cp; 514 register struct hnamemem *tp; 515 register u_int32_t i = port; 516 char buf[sizeof("0000")]; 517 518 for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 519 if (tp->addr == i) 520 return (tp->name); 521 522 tp->addr = i; 523 tp->nxt = newhnamemem(); 524 525 cp = buf; 526 NTOHS(port); 527 *cp++ = hex[port >> 12 & 0xf]; 528 *cp++ = hex[port >> 8 & 0xf]; 529 *cp++ = hex[port >> 4 & 0xf]; 530 *cp++ = hex[port & 0xf]; 531 *cp++ = '\0'; 532 tp->name = savestr(buf); 533 return (tp->name); 534 } 535 536 char * 537 protoid_string(register const u_char *pi) 538 { 539 register u_int i, j; 540 register char *cp; 541 register struct protoidmem *tp; 542 char buf[sizeof("00:00:00:00:00")]; 543 544 tp = lookup_protoid(pi); 545 if (tp->p_name) 546 return tp->p_name; 547 548 cp = buf; 549 if ((j = *pi >> 4) != 0) 550 *cp++ = hex[j]; 551 *cp++ = hex[*pi++ & 0xf]; 552 for (i = 4; (int)--i >= 0;) { 553 *cp++ = ':'; 554 if ((j = *pi >> 4) != 0) 555 *cp++ = hex[j]; 556 *cp++ = hex[*pi++ & 0xf]; 557 } 558 *cp = '\0'; 559 tp->p_name = savestr(buf); 560 return (tp->p_name); 561 } 562 563 char * 564 llcsap_string(u_char sap) 565 { 566 register struct hnamemem *tp; 567 register u_int32_t i = sap; 568 char buf[sizeof("sap 00")]; 569 570 for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 571 if (tp->addr == i) 572 return (tp->name); 573 574 tp->addr = i; 575 tp->nxt = newhnamemem(); 576 577 snprintf(buf, sizeof(buf), "sap %02x", sap & 0xff); 578 tp->name = savestr(buf); 579 return (tp->name); 580 } 581 582 char * 583 isonsap_string(const u_char *nsap) 584 { 585 register u_int i, nlen = nsap[0]; 586 register char *cp; 587 register struct enamemem *tp; 588 589 tp = lookup_nsap(nsap); 590 if (tp->e_name) 591 return tp->e_name; 592 593 tp->e_name = cp = (char *)malloc(nlen * 2 + 2); 594 if (cp == NULL) 595 error("isonsap_string: malloc"); 596 597 nsap++; 598 *cp++ = '/'; 599 for (i = nlen; (int)--i >= 0;) { 600 *cp++ = hex[*nsap >> 4]; 601 *cp++ = hex[*nsap++ & 0xf]; 602 } 603 *cp = '\0'; 604 return (tp->e_name); 605 } 606 607 char * 608 tcpport_string(u_short port) 609 { 610 register struct hnamemem *tp; 611 register u_int32_t i = port; 612 char buf[sizeof("00000")]; 613 614 for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 615 if (tp->addr == i) 616 return (tp->name); 617 618 tp->addr = i; 619 tp->nxt = newhnamemem(); 620 621 (void)snprintf(buf, sizeof(buf), "%u", i); 622 tp->name = savestr(buf); 623 return (tp->name); 624 } 625 626 char * 627 udpport_string(register u_short port) 628 { 629 register struct hnamemem *tp; 630 register u_int32_t i = port; 631 char buf[sizeof("00000")]; 632 633 for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 634 if (tp->addr == i) 635 return (tp->name); 636 637 tp->addr = i; 638 tp->nxt = newhnamemem(); 639 640 (void)snprintf(buf, sizeof(buf), "%u", i); 641 tp->name = savestr(buf); 642 return (tp->name); 643 } 644 645 char * 646 ipproto_string(u_int proto) 647 { 648 return ipprototable[proto & 0xff]; 649 } 650 651 static void 652 init_servarray(void) 653 { 654 struct hnamemem *table; 655 int i, port; 656 char buf[sizeof("0000000000")]; 657 char service[BUFSIZ]; 658 char protocol[BUFSIZ]; 659 660 priv_getserventries(); 661 while (priv_getserventry(service, sizeof(service), &port, protocol, 662 sizeof(protocol)) != 0) { 663 port = ntohs(port); 664 i = port & (HASHNAMESIZE-1); 665 if (strcmp(protocol, "tcp") == 0) 666 table = &tporttable[i]; 667 else if (strcmp(protocol, "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(service); 679 table->addr = port; 680 table->nxt = newhnamemem(); 681 } 682 } 683 684 static void 685 init_ipprotoarray(void) 686 { 687 int i; 688 char buf[sizeof("000")]; 689 char prot[BUFSIZ]; 690 691 if (!nflag) { 692 priv_getprotoentries(); 693 while (priv_getprotoentry(prot, sizeof(prot), &i) != 0) 694 ipprototable[i & 0xff] = savestr(prot); 695 } 696 for (i = 0; i < 256; i++) 697 if (ipprototable[i] == NULL) { 698 (void)snprintf(buf, sizeof(buf), "%d", i); 699 ipprototable[i] = savestr(buf); 700 } 701 } 702 703 /*XXX from libbpfc.a */ 704 extern struct eproto { 705 char *s; 706 u_short p; 707 } eproto_db[]; 708 709 static void 710 init_eprotoarray(void) 711 { 712 register int i; 713 register struct hnamemem *table; 714 715 for (i = 0; eproto_db[i].s; i++) { 716 int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1); 717 table = &eprototable[j]; 718 while (table->name) 719 table = table->nxt; 720 table->name = eproto_db[i].s; 721 table->addr = ntohs(eproto_db[i].p); 722 table->nxt = newhnamemem(); 723 } 724 } 725 726 /* 727 * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet 728 * types. 729 */ 730 static void 731 init_protoidarray(void) 732 { 733 register int i; 734 register struct protoidmem *tp; 735 u_char protoid[5]; 736 737 protoid[0] = 0; 738 protoid[1] = 0; 739 protoid[2] = 0; 740 for (i = 0; eproto_db[i].s; i++) { 741 u_short etype = htons(eproto_db[i].p); 742 743 memcpy((char *)&protoid[3], (char *)&etype, 2); 744 tp = lookup_protoid(protoid); 745 tp->p_name = savestr(eproto_db[i].s); 746 } 747 } 748 749 static struct etherlist { 750 u_char addr[6]; 751 char *name; 752 } etherlist[] = { 753 {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" }, 754 {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL } 755 }; 756 757 /* 758 * Initialize the ethers hash table. We take two different approaches 759 * depending on whether or not the system provides the ethers name 760 * service. If it does, we just wire in a few names at startup, 761 * and etheraddr_string() fills in the table on demand. If it doesn't, 762 * then we suck in the entire /etc/ethers file at startup. The idea 763 * is that parsing the local file will be fast, but spinning through 764 * all the ethers entries via NIS & next_etherent might be very slow. 765 * 766 * XXX pcap_next_etherent doesn't belong in the pcap interface, but 767 * since the pcap module already does name-to-address translation, 768 * it's already does most of the work for the ethernet address-to-name 769 * translation, so we just pcap_next_etherent as a convenience. 770 */ 771 static void 772 init_etherarray(void) 773 { 774 register struct etherlist *el; 775 register struct enamemem *tp; 776 #ifdef HAVE_ETHER_NTOHOST 777 char name[MAXHOSTNAMELEN + 1]; 778 #else 779 register struct pcap_etherent *ep; 780 register FILE *fp; 781 782 /* Suck in entire ethers file */ 783 fp = fopen(PCAP_ETHERS_FILE, "r"); 784 if (fp != NULL) { 785 while ((ep = pcap_next_etherent(fp)) != NULL) { 786 tp = lookup_emem(ep->addr); 787 tp->e_name = savestr(ep->name); 788 } 789 (void)fclose(fp); 790 } 791 #endif 792 793 /* Hardwire some ethernet names */ 794 for (el = etherlist; el->name != NULL; ++el) { 795 tp = lookup_emem(el->addr); 796 /* Don't override existing name */ 797 if (tp->e_name != NULL) 798 continue; 799 800 #ifdef HAVE_ETHER_NTOHOST 801 /* Use yp/nis version of name if available */ 802 if (priv_ether_ntohost(name, sizeof(name), 803 (struct ether_addr *)el->addr) > 0) { 804 tp->e_name = savestr(name); 805 continue; 806 } 807 #endif 808 tp->e_name = el->name; 809 } 810 } 811 812 static struct tok llcsap_db[] = { 813 { LLCSAP_NULL, "null" }, 814 { LLCSAP_8021B_I, "802.1b-gsap" }, 815 { LLCSAP_8021B_G, "802.1b-isap" }, 816 { LLCSAP_IP, "ip-sap" }, 817 { LLCSAP_PROWAYNM, "proway-nm" }, 818 { LLCSAP_8021D, "802.1d" }, 819 { LLCSAP_RS511, "eia-rs511" }, 820 { LLCSAP_ISO8208, "x.25/llc2" }, 821 { LLCSAP_PROWAY, "proway" }, 822 { LLCSAP_ISONS, "iso-clns" }, 823 { LLCSAP_GLOBAL, "global" }, 824 { 0, NULL } 825 }; 826 827 static void 828 init_llcsaparray(void) 829 { 830 register int i; 831 register struct hnamemem *table; 832 833 for (i = 0; llcsap_db[i].s != NULL; i++) { 834 table = &llcsaptable[llcsap_db[i].v]; 835 while (table->name) 836 table = table->nxt; 837 table->name = llcsap_db[i].s; 838 table->addr = llcsap_db[i].v; 839 table->nxt = newhnamemem(); 840 } 841 } 842 843 /* 844 * Initialize the address to name translation machinery. We map all 845 * non-local IP addresses to numeric addresses if fflag is true (i.e., 846 * to prevent blocking on the nameserver). localnet is the IP address 847 * of the local network. mask is its subnet mask. 848 */ 849 void 850 init_addrtoname(u_int32_t localnet, u_int32_t mask) 851 { 852 netmask = mask; 853 if (fflag) { 854 f_localnet = localnet; 855 f_netmask = mask; 856 } 857 858 init_servarray(); 859 init_ipprotoarray(); 860 861 if (nflag) 862 /* 863 * Simplest way to suppress names. 864 */ 865 return; 866 867 init_etherarray(); 868 init_eprotoarray(); 869 init_llcsaparray(); 870 init_protoidarray(); 871 } 872 873 char * 874 dnaddr_string(u_short dnaddr) 875 { 876 register struct hnamemem *tp; 877 878 for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0; 879 tp = tp->nxt) 880 if (tp->addr == dnaddr) 881 return (tp->name); 882 883 tp->addr = dnaddr; 884 tp->nxt = newhnamemem(); 885 if (nflag) 886 tp->name = dnnum_string(dnaddr); 887 else 888 tp->name = dnname_string(dnaddr); 889 890 return(tp->name); 891 } 892 893 /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */ 894 struct hnamemem * 895 newhnamemem(void) 896 { 897 register struct hnamemem *p; 898 static struct hnamemem *ptr = NULL; 899 static u_int num = 0; 900 901 if (num <= 0) { 902 num = 64; 903 ptr = (struct hnamemem *)calloc(num, sizeof (*ptr)); 904 if (ptr == NULL) 905 error("newhnamemem: calloc"); 906 } 907 --num; 908 p = ptr++; 909 return (p); 910 } 911 912 #ifdef INET6 913 /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */ 914 struct h6namemem * 915 newh6namemem(void) 916 { 917 register struct h6namemem *p; 918 static struct h6namemem *ptr = NULL; 919 static u_int num = 0; 920 921 if (num <= 0) { 922 num = 64; 923 ptr = (struct h6namemem *)calloc(num, sizeof (*ptr)); 924 if (ptr == NULL) 925 error("newh6namemem: calloc"); 926 } 927 --num; 928 p = ptr++; 929 return (p); 930 } 931 #endif /* INET6 */ 932