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