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