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