1 /* 2 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 * 21 * Internet, ethernet, port, and protocol string to address 22 * and address to string conversion routines 23 * 24 * $FreeBSD$ 25 */ 26 #ifndef lint 27 static const char rcsid[] = 28 "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.64 1999/11/21 09:36:44 fenner Exp $ (LBL)"; 29 #endif 30 31 #ifdef HAVE_CONFIG_H 32 #include "config.h" 33 #endif 34 35 #include <sys/types.h> 36 #include <sys/socket.h> 37 #include <sys/time.h> 38 39 #if __STDC__ 40 struct mbuf; 41 struct rtentry; 42 #endif 43 #include <net/if.h> 44 45 #include <netinet/in.h> 46 #include <net/ethernet.h> 47 48 #ifdef INET6 49 #include <netinet6/ip6.h> 50 #endif 51 52 #include <arpa/inet.h> 53 54 #include <ctype.h> 55 #include <netdb.h> 56 #include <pcap.h> 57 #include <pcap-namedb.h> 58 #ifdef HAVE_MALLOC_H 59 #include <malloc.h> 60 #endif 61 #ifdef HAVE_MEMORY_H 62 #include <memory.h> 63 #endif 64 #include <signal.h> 65 #include <stdio.h> 66 #include <string.h> 67 #include <stdlib.h> 68 #include <unistd.h> 69 70 #include "interface.h" 71 #include "addrtoname.h" 72 #include "llc.h" 73 #include "savestr.h" 74 #include "setsignal.h" 75 76 /* Forwards */ 77 static RETSIGTYPE nohostname(int); 78 79 /* 80 * hash tables for whatever-to-name translations 81 */ 82 83 #define HASHNAMESIZE 4096 84 85 struct hnamemem { 86 u_int32_t addr; 87 char *name; 88 struct hnamemem *nxt; 89 }; 90 91 struct hnamemem hnametable[HASHNAMESIZE]; 92 struct hnamemem tporttable[HASHNAMESIZE]; 93 struct hnamemem uporttable[HASHNAMESIZE]; 94 struct hnamemem eprototable[HASHNAMESIZE]; 95 struct hnamemem dnaddrtable[HASHNAMESIZE]; 96 struct hnamemem llcsaptable[HASHNAMESIZE]; 97 98 #ifdef INET6 99 struct h6namemem { 100 struct in6_addr addr; 101 char *name; 102 struct h6namemem *nxt; 103 }; 104 105 struct h6namemem h6nametable[HASHNAMESIZE]; 106 #endif /* INET6 */ 107 108 struct enamemem { 109 u_short e_addr0; 110 u_short e_addr1; 111 u_short e_addr2; 112 char *e_name; 113 u_char *e_nsap; /* used only for nsaptable[] */ 114 struct enamemem *e_nxt; 115 }; 116 117 struct enamemem enametable[HASHNAMESIZE]; 118 struct enamemem nsaptable[HASHNAMESIZE]; 119 120 struct protoidmem { 121 u_int32_t p_oui; 122 u_short p_proto; 123 char *p_name; 124 struct protoidmem *p_nxt; 125 }; 126 127 struct protoidmem protoidtable[HASHNAMESIZE]; 128 129 /* 130 * A faster replacement for inet_ntoa(). 131 */ 132 char * 133 intoa(u_int32_t addr) 134 { 135 register char *cp; 136 register u_int byte; 137 register int n; 138 static char buf[sizeof(".xxx.xxx.xxx.xxx")]; 139 140 NTOHL(addr); 141 cp = &buf[sizeof buf]; 142 *--cp = '\0'; 143 144 n = 4; 145 do { 146 byte = addr & 0xff; 147 *--cp = byte % 10 + '0'; 148 byte /= 10; 149 if (byte > 0) { 150 *--cp = byte % 10 + '0'; 151 byte /= 10; 152 if (byte > 0) 153 *--cp = byte + '0'; 154 } 155 *--cp = '.'; 156 addr >>= 8; 157 } while (--n > 0); 158 159 return cp + 1; 160 } 161 162 static u_int32_t f_netmask; 163 static u_int32_t f_localnet; 164 static u_int32_t netmask; 165 166 /* 167 * "getname" is written in this atrocious way to make sure we don't 168 * wait forever while trying to get hostnames from yp. 169 */ 170 #include <setjmp.h> 171 172 jmp_buf getname_env; 173 174 static RETSIGTYPE 175 nohostname(int signo) 176 { 177 longjmp(getname_env, 1); 178 } 179 180 /* 181 * Return a name for the IP address pointed to by ap. This address 182 * is assumed to be in network byte order. 183 */ 184 char * 185 getname(const u_char *ap) 186 { 187 register struct hostent *hp; 188 u_int32_t addr; 189 static struct hnamemem *p; /* static for longjmp() */ 190 191 #ifndef LBL_ALIGN 192 addr = *(const u_int32_t *)ap; 193 #else 194 memcpy(&addr, ap, sizeof(addr)); 195 #endif 196 p = &hnametable[addr & (HASHNAMESIZE-1)]; 197 for (; p->nxt; p = p->nxt) { 198 if (p->addr == addr) 199 return (p->name); 200 } 201 p->addr = addr; 202 p->nxt = newhnamemem(); 203 204 /* 205 * Only print names when: 206 * (1) -n was not given. 207 * (2) Address is foreign and -f was given. (If -f was not 208 * give, f_netmask and f_local are 0 and the test 209 * evaluates to true) 210 * (3) -a was given or the host portion is not all ones 211 * nor all zeros (i.e. not a network or broadcast address) 212 */ 213 if (!nflag && 214 (addr & f_netmask) == f_localnet && 215 (aflag || 216 !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))) { 217 if (!setjmp(getname_env)) { 218 (void)setsignal(SIGALRM, nohostname); 219 (void)alarm(20); 220 hp = gethostbyaddr((char *)&addr, 4, AF_INET); 221 (void)alarm(0); 222 if (hp) { 223 char *dotp; 224 225 p->name = savestr(hp->h_name); 226 if (Nflag) { 227 /* Remove domain qualifications */ 228 dotp = strchr(p->name, '.'); 229 if (dotp) 230 *dotp = '\0'; 231 } 232 return (p->name); 233 } 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 register struct hostent *hp; 249 struct in6_addr addr; 250 static struct h6namemem *p; /* static for longjmp() */ 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 if (!setjmp(getname_env)) { 281 (void)setsignal(SIGALRM, nohostname); 282 (void)alarm(20); 283 hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6); 284 (void)alarm(0); 285 if (hp) { 286 char *dotp; 287 288 p->name = savestr(hp->h_name); 289 if (Nflag) { 290 /* Remove domain qualifications */ 291 dotp = strchr(p->name, '.'); 292 if (dotp) 293 *dotp = '\0'; 294 } 295 return (p->name); 296 } 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 /* Find the hash node that corresponds the NSAP 'nsap' */ 339 340 static inline struct enamemem * 341 lookup_nsap(register const u_char *nsap) 342 { 343 register u_int i, j, k; 344 int nlen = *nsap; 345 struct enamemem *tp; 346 const u_char *ensap = nsap + nlen - 6; 347 348 if (nlen > 6) { 349 k = (ensap[0] << 8) | ensap[1]; 350 j = (ensap[2] << 8) | ensap[3]; 351 i = (ensap[4] << 8) | ensap[5]; 352 } 353 else 354 i = j = k = 0; 355 356 tp = &nsaptable[(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 tp->e_nsap[0] == nlen && 362 memcmp((char *)&(nsap[1]), 363 (char *)&(tp->e_nsap[1]), nlen) == 0) 364 return tp; 365 else 366 tp = tp->e_nxt; 367 tp->e_addr0 = i; 368 tp->e_addr1 = j; 369 tp->e_addr2 = k; 370 tp->e_nsap = (u_char *)malloc(nlen + 1); 371 if (tp->e_nsap == NULL) 372 error("lookup_nsap: malloc"); 373 memcpy((char *)tp->e_nsap, (char *)nsap, nlen + 1); 374 tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp)); 375 if (tp->e_nxt == NULL) 376 error("lookup_nsap: calloc"); 377 378 return tp; 379 } 380 381 /* Find the hash node that corresponds the protoid 'pi'. */ 382 383 static inline struct protoidmem * 384 lookup_protoid(const u_char *pi) 385 { 386 register u_int i, j; 387 struct protoidmem *tp; 388 389 /* 5 octets won't be aligned */ 390 i = (((pi[0] << 8) + pi[1]) << 8) + pi[2]; 391 j = (pi[3] << 8) + pi[4]; 392 /* XXX should be endian-insensitive, but do big-endian testing XXX */ 393 394 tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)]; 395 while (tp->p_nxt) 396 if (tp->p_oui == i && tp->p_proto == j) 397 return tp; 398 else 399 tp = tp->p_nxt; 400 tp->p_oui = i; 401 tp->p_proto = j; 402 tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp)); 403 if (tp->p_nxt == NULL) 404 error("lookup_protoid: calloc"); 405 406 return tp; 407 } 408 409 char * 410 etheraddr_string(register const u_char *ep) 411 { 412 register u_int i, j; 413 register char *cp; 414 register struct enamemem *tp; 415 char buf[sizeof("00:00:00:00:00:00")]; 416 417 tp = lookup_emem(ep); 418 if (tp->e_name) 419 return (tp->e_name); 420 #ifdef HAVE_ETHER_NTOHOST 421 if (!nflag) { 422 char buf[128]; 423 if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) { 424 tp->e_name = savestr(buf); 425 return (tp->e_name); 426 } 427 } 428 #endif 429 cp = buf; 430 if ((j = *ep >> 4) != 0) 431 *cp++ = hex[j]; 432 *cp++ = hex[*ep++ & 0xf]; 433 for (i = 5; (int)--i >= 0;) { 434 *cp++ = ':'; 435 if ((j = *ep >> 4) != 0) 436 *cp++ = hex[j]; 437 *cp++ = hex[*ep++ & 0xf]; 438 } 439 *cp = '\0'; 440 tp->e_name = savestr(buf); 441 return (tp->e_name); 442 } 443 444 char * 445 etherproto_string(u_short port) 446 { 447 register char *cp; 448 register struct hnamemem *tp; 449 register u_int32_t i = port; 450 char buf[sizeof("0000")]; 451 452 for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 453 if (tp->addr == i) 454 return (tp->name); 455 456 tp->addr = i; 457 tp->nxt = newhnamemem(); 458 459 cp = buf; 460 NTOHS(port); 461 *cp++ = hex[port >> 12 & 0xf]; 462 *cp++ = hex[port >> 8 & 0xf]; 463 *cp++ = hex[port >> 4 & 0xf]; 464 *cp++ = hex[port & 0xf]; 465 *cp++ = '\0'; 466 tp->name = savestr(buf); 467 return (tp->name); 468 } 469 470 char * 471 protoid_string(register const u_char *pi) 472 { 473 register u_int i, j; 474 register char *cp; 475 register struct protoidmem *tp; 476 char buf[sizeof("00:00:00:00:00")]; 477 478 tp = lookup_protoid(pi); 479 if (tp->p_name) 480 return tp->p_name; 481 482 cp = buf; 483 if ((j = *pi >> 4) != 0) 484 *cp++ = hex[j]; 485 *cp++ = hex[*pi++ & 0xf]; 486 for (i = 4; (int)--i >= 0;) { 487 *cp++ = ':'; 488 if ((j = *pi >> 4) != 0) 489 *cp++ = hex[j]; 490 *cp++ = hex[*pi++ & 0xf]; 491 } 492 *cp = '\0'; 493 tp->p_name = savestr(buf); 494 return (tp->p_name); 495 } 496 497 char * 498 llcsap_string(u_char sap) 499 { 500 register char *cp; 501 register struct hnamemem *tp; 502 register u_int32_t i = sap; 503 char buf[sizeof("sap 00")]; 504 505 for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 506 if (tp->addr == i) 507 return (tp->name); 508 509 tp->addr = i; 510 tp->nxt = newhnamemem(); 511 512 cp = buf; 513 (void)strcpy(cp, "sap "); 514 cp += strlen(cp); 515 *cp++ = hex[sap >> 4 & 0xf]; 516 *cp++ = hex[sap & 0xf]; 517 *cp++ = '\0'; 518 tp->name = savestr(buf); 519 return (tp->name); 520 } 521 522 char * 523 isonsap_string(const u_char *nsap) 524 { 525 register u_int i, nlen = nsap[0]; 526 register char *cp; 527 register struct enamemem *tp; 528 529 tp = lookup_nsap(nsap); 530 if (tp->e_name) 531 return tp->e_name; 532 533 tp->e_name = cp = (char *)malloc(nlen * 2 + 2 + (nlen>>1)); 534 if (cp == NULL) 535 error("isonsap_string: malloc"); 536 537 nsap++; 538 for (i = 0; i < nlen; i++) { 539 *cp++ = hex[*nsap >> 4]; 540 *cp++ = hex[*nsap++ & 0xf]; 541 if (((i & 1) == 0) && (i + 1 < nlen)) 542 *cp++ = '.'; 543 } 544 *cp = '\0'; 545 return (tp->e_name); 546 } 547 548 char * 549 tcpport_string(u_short port) 550 { 551 register struct hnamemem *tp; 552 register u_int32_t i = port; 553 char buf[sizeof("00000")]; 554 555 for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 556 if (tp->addr == i) 557 return (tp->name); 558 559 tp->addr = i; 560 tp->nxt = newhnamemem(); 561 562 (void)sprintf(buf, "%u", i); 563 tp->name = savestr(buf); 564 return (tp->name); 565 } 566 567 char * 568 udpport_string(register u_short port) 569 { 570 register struct hnamemem *tp; 571 register u_int32_t i = port; 572 char buf[sizeof("00000")]; 573 574 for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) 575 if (tp->addr == i) 576 return (tp->name); 577 578 tp->addr = i; 579 tp->nxt = newhnamemem(); 580 581 (void)sprintf(buf, "%u", i); 582 tp->name = savestr(buf); 583 return (tp->name); 584 } 585 586 static void 587 init_servarray(void) 588 { 589 struct servent *sv; 590 register struct hnamemem *table; 591 register int i; 592 char buf[sizeof("0000000000")]; 593 594 while ((sv = getservent()) != NULL) { 595 int port = ntohs(sv->s_port); 596 i = port & (HASHNAMESIZE-1); 597 if (strcmp(sv->s_proto, "tcp") == 0) 598 table = &tporttable[i]; 599 else if (strcmp(sv->s_proto, "udp") == 0) 600 table = &uporttable[i]; 601 else 602 continue; 603 604 while (table->name) 605 table = table->nxt; 606 if (nflag) { 607 (void)sprintf(buf, "%d", port); 608 table->name = savestr(buf); 609 } else 610 table->name = savestr(sv->s_name); 611 table->addr = port; 612 table->nxt = newhnamemem(); 613 } 614 endservent(); 615 } 616 617 /*XXX from libbpfc.a */ 618 extern struct eproto { 619 char *s; 620 u_short p; 621 } eproto_db[]; 622 623 static void 624 init_eprotoarray(void) 625 { 626 register int i; 627 register struct hnamemem *table; 628 629 for (i = 0; eproto_db[i].s; i++) { 630 int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1); 631 table = &eprototable[j]; 632 while (table->name) 633 table = table->nxt; 634 table->name = eproto_db[i].s; 635 table->addr = ntohs(eproto_db[i].p); 636 table->nxt = newhnamemem(); 637 } 638 } 639 640 /* 641 * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet 642 * types. 643 */ 644 static void 645 init_protoidarray(void) 646 { 647 register int i; 648 register struct protoidmem *tp; 649 u_char protoid[5]; 650 651 protoid[0] = 0; 652 protoid[1] = 0; 653 protoid[2] = 0; 654 for (i = 0; eproto_db[i].s; i++) { 655 u_short etype = htons(eproto_db[i].p); 656 657 memcpy((char *)&protoid[3], (char *)&etype, 2); 658 tp = lookup_protoid(protoid); 659 tp->p_name = savestr(eproto_db[i].s); 660 } 661 } 662 663 static struct etherlist { 664 u_char addr[6]; 665 char *name; 666 } etherlist[] = { 667 {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" }, 668 {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL } 669 }; 670 671 /* 672 * Initialize the ethers hash table. We take two different approaches 673 * depending on whether or not the system provides the ethers name 674 * service. If it does, we just wire in a few names at startup, 675 * and etheraddr_string() fills in the table on demand. If it doesn't, 676 * then we suck in the entire /etc/ethers file at startup. The idea 677 * is that parsing the local file will be fast, but spinning through 678 * all the ethers entries via NIS & next_etherent might be very slow. 679 * 680 * XXX pcap_next_etherent doesn't belong in the pcap interface, but 681 * since the pcap module already does name-to-address translation, 682 * it's already does most of the work for the ethernet address-to-name 683 * translation, so we just pcap_next_etherent as a convenience. 684 */ 685 static void 686 init_etherarray(void) 687 { 688 register struct etherlist *el; 689 register struct enamemem *tp; 690 #ifdef HAVE_ETHER_NTOHOST 691 char name[256]; 692 #else 693 register struct pcap_etherent *ep; 694 register FILE *fp; 695 696 /* Suck in entire ethers file */ 697 fp = fopen(PCAP_ETHERS_FILE, "r"); 698 if (fp != NULL) { 699 while ((ep = pcap_next_etherent(fp)) != NULL) { 700 tp = lookup_emem(ep->addr); 701 tp->e_name = savestr(ep->name); 702 } 703 (void)fclose(fp); 704 } 705 #endif 706 707 /* Hardwire some ethernet names */ 708 for (el = etherlist; el->name != NULL; ++el) { 709 tp = lookup_emem(el->addr); 710 /* Don't override existing name */ 711 if (tp->e_name != NULL) 712 continue; 713 714 #ifdef HAVE_ETHER_NTOHOST 715 /* Use yp/nis version of name if available */ 716 if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) { 717 tp->e_name = savestr(name); 718 continue; 719 } 720 #endif 721 tp->e_name = el->name; 722 } 723 } 724 725 static struct tok llcsap_db[] = { 726 { LLCSAP_NULL, "null" }, 727 { LLCSAP_8021B_I, "802.1b-gsap" }, 728 { LLCSAP_8021B_G, "802.1b-isap" }, 729 { LLCSAP_IP, "ip-sap" }, 730 { LLCSAP_PROWAYNM, "proway-nm" }, 731 { LLCSAP_8021D, "802.1d" }, 732 { LLCSAP_RS511, "eia-rs511" }, 733 { LLCSAP_ISO8208, "x.25/llc2" }, 734 { LLCSAP_PROWAY, "proway" }, 735 { LLCSAP_ISONS, "iso-clns" }, 736 { LLCSAP_GLOBAL, "global" }, 737 { 0, NULL } 738 }; 739 740 static void 741 init_llcsaparray(void) 742 { 743 register int i; 744 register struct hnamemem *table; 745 746 for (i = 0; llcsap_db[i].s != NULL; i++) { 747 table = &llcsaptable[llcsap_db[i].v]; 748 while (table->name) 749 table = table->nxt; 750 table->name = llcsap_db[i].s; 751 table->addr = llcsap_db[i].v; 752 table->nxt = newhnamemem(); 753 } 754 } 755 756 /* 757 * Initialize the address to name translation machinery. We map all 758 * non-local IP addresses to numeric addresses if fflag is true (i.e., 759 * to prevent blocking on the nameserver). localnet is the IP address 760 * of the local network. mask is its subnet mask. 761 */ 762 void 763 init_addrtoname(u_int32_t localnet, u_int32_t mask) 764 { 765 netmask = mask; 766 if (fflag) { 767 f_localnet = localnet; 768 f_netmask = mask; 769 } 770 if (nflag) 771 /* 772 * Simplest way to suppress names. 773 */ 774 return; 775 776 init_etherarray(); 777 init_servarray(); 778 init_eprotoarray(); 779 init_llcsaparray(); 780 init_protoidarray(); 781 } 782 783 char * 784 dnaddr_string(u_short dnaddr) 785 { 786 register struct hnamemem *tp; 787 788 for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0; 789 tp = tp->nxt) 790 if (tp->addr == dnaddr) 791 return (tp->name); 792 793 tp->addr = dnaddr; 794 tp->nxt = newhnamemem(); 795 if (nflag) 796 tp->name = dnnum_string(dnaddr); 797 else 798 tp->name = dnname_string(dnaddr); 799 800 return(tp->name); 801 } 802 803 /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */ 804 struct hnamemem * 805 newhnamemem(void) 806 { 807 register struct hnamemem *p; 808 static struct hnamemem *ptr = NULL; 809 static u_int num = 0; 810 811 if (num <= 0) { 812 num = 64; 813 ptr = (struct hnamemem *)calloc(num, sizeof (*ptr)); 814 if (ptr == NULL) 815 error("newhnamemem: calloc"); 816 } 817 --num; 818 p = ptr++; 819 return (p); 820 } 821 822 #ifdef INET6 823 /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */ 824 struct h6namemem * 825 newh6namemem(void) 826 { 827 register struct h6namemem *p; 828 static struct h6namemem *ptr = NULL; 829 static u_int num = 0; 830 831 if (num <= 0) { 832 num = 64; 833 ptr = (struct h6namemem *)calloc(num, sizeof (*ptr)); 834 if (ptr == NULL) 835 error("newh6namemem: calloc"); 836 } 837 --num; 838 p = ptr++; 839 return (p); 840 } 841 #endif /* INET6 */ 842