]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/addrtoname.c
This commit was generated by cvs2svn to compensate for changes in r56915,
[FreeBSD/FreeBSD.git] / contrib / 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  * $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 */