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