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