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