Annotation of embedaddon/trafshow/addrtoname.c, revision 1.1.1.1
1.1 misho 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[] _U_ =
26: "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.96.2.3 2003/12/15 04:02:53 guy Exp $ (LBL)";
27: #endif
28: */
29:
30: #ifdef HAVE_CONFIG_H
31: #include "config.h"
32: #endif
33:
34: #include <ctype.h>
35: #include <unistd.h>
36: #include <netdb.h>
37: #include <sys/param.h>
38: #include <sys/types.h> /* concession to AIX */
39: #include <sys/time.h>
40: #include <sys/socket.h>
41: #ifdef linux
42: #include <linux/if.h>
43: #else
44: #include <net/if.h>
45: #endif
46: #include <netinet/in.h>
47: #include <netinet/if_ether.h>
48: #ifdef HAVE_NET_IF_DL_H
49: #include <net/if_dl.h>
50: #endif
51: #ifdef TIME_WITH_SYS_TIME
52: #include <time.h>
53: #endif
54:
55: #include <arpa/inet.h>
56:
57: #include <pcap.h>
58: #include <pcap-namedb.h>
59: #include <signal.h>
60: #include <stdio.h>
61: #include <string.h>
62: #include <stdlib.h>
63:
64: #include "addrtoname.h"
65: #include "ethertype.h"
66: #include "domain_resolver.h"
67:
68: #ifndef NTOHL
69: #define NTOHL(x) (x) = ntohl(x)
70: #define NTOHS(x) (x) = ntohs(x)
71: #define HTONL(x) (x) = htonl(x)
72: #define HTONS(x) (x) = htons(x)
73: #endif
74:
75: /* dirty fake */
76: #define error(s) { perror(s); exit(1); }
77:
78: struct tok {
79: int v; /* value */
80: const char *s; /* string */
81: };
82:
83: /*
84: * hash tables for whatever-to-name translations
85: *
86: * XXX there has to be error checks against strdup(3) failure
87: */
88:
89: #define HASHNAMESIZE 4096
90:
91: struct hnamemem {
92: int resolving;
93: u_int32_t addr;
94: const char *name;
95: struct hnamemem *nxt;
96: };
97:
98: struct hnamemem hnametable[HASHNAMESIZE];
99: struct hnamemem tporttable[HASHNAMESIZE];
100: struct hnamemem uporttable[HASHNAMESIZE];
101: struct hnamemem servtable[HASHNAMESIZE];
102: struct hnamemem iprototable[HASHNAMESIZE];
103: struct hnamemem etypetable[HASHNAMESIZE];
104: struct hnamemem dnaddrtable[HASHNAMESIZE];
105: struct hnamemem llcsaptable[HASHNAMESIZE];
106: struct hnamemem ipxsaptable[HASHNAMESIZE];
107: struct hnamemem icmptable[HASHNAMESIZE];
108: #ifdef INET6
109: struct hnamemem icmpv6table[HASHNAMESIZE];
110: #endif
111:
112: #ifdef INET6
113: struct h6namemem {
114: struct in6_addr addr;
115: char *name;
116: struct h6namemem *nxt;
117: };
118:
119: struct h6namemem h6nametable[HASHNAMESIZE];
120: #endif /* INET6 */
121:
122: struct enamemem {
123: u_short e_addr0;
124: u_short e_addr1;
125: u_short e_addr2;
126: const char *e_name;
127: u_char *e_nsap; /* used only for nsaptable[] */
128: #define e_bs e_nsap /* for bytestringtable */
129: struct enamemem *e_nxt;
130: };
131:
132: struct enamemem enametable[HASHNAMESIZE];
133: struct enamemem nsaptable[HASHNAMESIZE];
134: struct enamemem bytestringtable[HASHNAMESIZE];
135:
136: struct protoidmem {
137: u_int32_t p_oui;
138: u_short p_proto;
139: const char *p_name;
140: struct protoidmem *p_nxt;
141: };
142:
143: struct protoidmem protoidtable[HASHNAMESIZE];
144:
145: char *
146: satoa(sa, dst, size)
147: const struct sockaddr *sa;
148: char *dst;
149: int size;
150: {
151: const char *cp = 0;
152: #ifdef INET6
153: char buf[100];
154: #endif
155: if (!sa || !dst || size < 1)
156: return 0;
157: if (sa->sa_family == AF_INET) {
158: cp = intoa(((struct sockaddr_in *)sa)->sin_addr.s_addr);
159: }
160: #ifdef INET6
161: else if (sa->sa_family == AF_INET6) {
162: cp = inet_ntop(AF_INET6,
163: &((struct sockaddr_in6 *)sa)->sin6_addr,
164: buf, sizeof(buf));
165: }
166: #endif
167: #if defined(AF_LINK) && defined(LLADDR)
168: else if (sa->sa_family == AF_LINK) {
169: struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;
170: if (sdl->sdl_alen > 0)
171: cp = linkaddr_string((u_char *)LLADDR(sdl), sdl->sdl_alen);
172: }
173: #endif
174: if (!cp) return 0;
175: (void)strncpy(dst, cp, size);
176: dst[size-1] = '\0';
177: return dst;
178: }
179:
180: /*
181: * A faster replacement for inet_ntoa().
182: */
183: const char *
184: intoa(u_int32_t addr)
185: {
186: register char *cp;
187: register u_int byte;
188: register int n;
189: static char buf[sizeof(".xxx.xxx.xxx.xxx")];
190:
191: NTOHL(addr);
192: cp = &buf[sizeof buf];
193: *--cp = '\0';
194:
195: n = 4;
196: do {
197: byte = addr & 0xff;
198: *--cp = byte % 10 + '0';
199: byte /= 10;
200: if (byte > 0) {
201: *--cp = byte % 10 + '0';
202: byte /= 10;
203: if (byte > 0)
204: *--cp = byte + '0';
205: }
206: *--cp = '.';
207: addr >>= 8;
208: } while (--n > 0);
209:
210: return cp + 1;
211: }
212:
213: extern int nflag;
214:
215: static void
216: name_resolved(unused, dd)
217: void *unused;
218: DOMAIN_DATA *dd;
219: {
220: register struct hnamemem *p;
221:
222: /* sanity check */
223: if (unused || !dd) return;
224:
225: p = &hnametable[dd->addr & (HASHNAMESIZE-1)];
226: for (; p->nxt; p = p->nxt) {
227: if (p->addr == dd->addr) {
228: if (p->name) free((char *)p->name);
229: p->name = strdup(dd->name);
230: p->resolving = 2;
231: break;
232: }
233: }
234: domain_data_free(&dd, 0);
235: }
236:
237: /*
238: * Return a name for the IP address pointed to by ap. This address
239: * is assumed to be in network byte order.
240: */
241: const char *
242: getname(const u_char *ap)
243: {
244: u_int32_t addr;
245: register struct hnamemem *p;
246: int found;
247:
248: memcpy(&addr, ap, sizeof(addr));
249:
250: /*
251: * Do not print names if -n was given.
252: */
253: if (nflag)
254: return intoa(addr);
255:
256: found = 0;
257: p = &hnametable[addr & (HASHNAMESIZE-1)];
258: for (; p->nxt; p = p->nxt) {
259: if (p->addr == addr) {
260: found++;
261: break;
262: }
263: }
264: if (!found) {
265: p->addr = addr;
266: p->nxt = newhnamemem();
267: p->name = strdup(intoa(addr));
268: }
269: if (!p->resolving) {
270: if (domain_resolve_name(addr, 0, name_resolved) < 0)
271: p->resolving = -1;
272: else p->resolving = 1;
273: }
274: return (p->name);
275: }
276:
277: #ifdef INET6
278: /*
279: * Return a name for the IP6 address pointed to by ap. This address
280: * is assumed to be in network byte order.
281: */
282: const char *
283: getname6(const u_char *ap)
284: {
285: struct hostent *hp;
286: struct in6_addr addr;
287: static struct h6namemem *p; /* static for longjmp() */
288: const char *cp;
289: char ntop_buf[INET6_ADDRSTRLEN];
290:
291: memcpy(&addr, ap, sizeof(addr));
292:
293: /*
294: * Do not print names if -n was given.
295: */
296: if (nflag)
297: return inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf));
298:
299: p = &h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)];
300: for (; p->nxt; p = p->nxt) {
301: if (memcmp(&p->addr, &addr, sizeof(addr)) == 0)
302: return (p->name);
303: }
304: p->addr = addr;
305: p->nxt = newh6namemem();
306:
307: hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6);
308: if (hp) {
309: p->name = strdup(hp->h_name);
310: return (p->name);
311: }
312: cp = inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf));
313: if (!cp) return 0;
314: p->name = strdup(cp);
315: return (p->name);
316: }
317: #endif /* INET6 */
318:
319: static char hex[] = "0123456789abcdef";
320:
321:
322: /* Find the hash node that corresponds the ether address 'ep' */
323:
324: static inline struct enamemem *
325: lookup_emem(const u_char *ep)
326: {
327: register u_int i, j, k;
328: struct enamemem *tp;
329:
330: k = (ep[0] << 8) | ep[1];
331: j = (ep[2] << 8) | ep[3];
332: i = (ep[4] << 8) | ep[5];
333:
334: tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
335: while (tp->e_nxt)
336: if (tp->e_addr0 == i &&
337: tp->e_addr1 == j &&
338: tp->e_addr2 == k)
339: return tp;
340: else
341: tp = tp->e_nxt;
342: tp->e_addr0 = i;
343: tp->e_addr1 = j;
344: tp->e_addr2 = k;
345: tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
346: if (tp->e_nxt == NULL)
347: error("lookup_emem: calloc");
348:
349: return tp;
350: }
351:
352: /*
353: * Find the hash node that corresponds to the bytestring 'bs'
354: * with length 'nlen'
355: */
356:
357: static inline struct enamemem *
358: lookup_bytestring(register const u_char *bs, const unsigned int nlen)
359: {
360: struct enamemem *tp;
361: register u_int i, j, k;
362:
363: if (nlen >= 6) {
364: k = (bs[0] << 8) | bs[1];
365: j = (bs[2] << 8) | bs[3];
366: i = (bs[4] << 8) | bs[5];
367: } else if (nlen >= 4) {
368: k = (bs[0] << 8) | bs[1];
369: j = (bs[2] << 8) | bs[3];
370: i = 0;
371: } else
372: i = j = k = 0;
373:
374: tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)];
375: while (tp->e_nxt)
376: if (tp->e_addr0 == i &&
377: tp->e_addr1 == j &&
378: tp->e_addr2 == k &&
379: memcmp((const char *)bs, (const char *)(tp->e_bs), nlen) == 0)
380: return tp;
381: else
382: tp = tp->e_nxt;
383:
384: tp->e_addr0 = i;
385: tp->e_addr1 = j;
386: tp->e_addr2 = k;
387:
388: tp->e_bs = (u_char *) calloc(1, nlen + 1);
389: memcpy(tp->e_bs, bs, nlen);
390: tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
391: if (tp->e_nxt == NULL)
392: error("lookup_bytestring: calloc");
393:
394: return tp;
395: }
396:
397: /* Find the hash node that corresponds the NSAP 'nsap' */
398:
399: static inline struct enamemem *
400: lookup_nsap(register const u_char *nsap)
401: {
402: register u_int i, j, k;
403: unsigned int nlen = *nsap;
404: struct enamemem *tp;
405: const u_char *ensap = nsap + nlen - 6;
406:
407: if (nlen > 6) {
408: k = (ensap[0] << 8) | ensap[1];
409: j = (ensap[2] << 8) | ensap[3];
410: i = (ensap[4] << 8) | ensap[5];
411: }
412: else
413: i = j = k = 0;
414:
415: tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
416: while (tp->e_nxt)
417: if (tp->e_addr0 == i &&
418: tp->e_addr1 == j &&
419: tp->e_addr2 == k &&
420: tp->e_nsap[0] == nlen &&
421: memcmp((const char *)&(nsap[1]),
422: (char *)&(tp->e_nsap[1]), nlen) == 0)
423: return tp;
424: else
425: tp = tp->e_nxt;
426: tp->e_addr0 = i;
427: tp->e_addr1 = j;
428: tp->e_addr2 = k;
429: tp->e_nsap = (u_char *)malloc(nlen + 1);
430: if (tp->e_nsap == NULL)
431: error("lookup_nsap: malloc");
432: memcpy((char *)tp->e_nsap, (const char *)nsap, nlen + 1);
433: tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
434: if (tp->e_nxt == NULL)
435: error("lookup_nsap: calloc");
436:
437: return tp;
438: }
439:
440: /* Find the hash node that corresponds the protoid 'pi'. */
441:
442: static inline struct protoidmem *
443: lookup_protoid(const u_char *pi)
444: {
445: register u_int i, j;
446: struct protoidmem *tp;
447:
448: /* 5 octets won't be aligned */
449: i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
450: j = (pi[3] << 8) + pi[4];
451: /* XXX should be endian-insensitive, but do big-endian testing XXX */
452:
453: tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
454: while (tp->p_nxt)
455: if (tp->p_oui == i && tp->p_proto == j)
456: return tp;
457: else
458: tp = tp->p_nxt;
459: tp->p_oui = i;
460: tp->p_proto = j;
461: tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
462: if (tp->p_nxt == NULL)
463: error("lookup_protoid: calloc");
464:
465: return tp;
466: }
467:
468: const char *
469: etheraddr_string(register const u_char *ep)
470: {
471: register u_int i;
472: register char *cp;
473: register struct enamemem *tp;
474: char buf[sizeof("00:00:00:00:00:00")];
475:
476: tp = lookup_emem(ep);
477: if (tp->e_name)
478: return (tp->e_name);
479: #ifdef USE_ETHER_NTOHOST
480: if (!nflag) {
481: char buf2[128];
482: if (ether_ntohost(buf2, (const struct ether_addr *)ep) == 0) {
483: tp->e_name = strdup(buf2);
484: return (tp->e_name);
485: }
486: }
487: #endif
488: cp = buf;
489: *cp++ = hex[*ep >> 4 ];
490: *cp++ = hex[*ep++ & 0xf];
491: for (i = 5; (int)--i >= 0;) {
492: *cp++ = ':';
493: *cp++ = hex[*ep >> 4 ];
494: *cp++ = hex[*ep++ & 0xf];
495: }
496: *cp = '\0';
497: tp->e_name = strdup(buf);
498: return (tp->e_name);
499: }
500:
501: const char *
502: linkaddr_string(const u_char *ep, const unsigned int len)
503: {
504: register u_int i, j;
505: register char *cp;
506: register struct enamemem *tp;
507:
508: if (!ep || len < 1) return "";
509:
510: #ifdef notdef
511: if (len == 6) /* XXX not totally correct... */
512: return etheraddr_string(ep);
513: #endif
514:
515: tp = lookup_bytestring(ep, len);
516: if (tp->e_name)
517: return (tp->e_name);
518:
519: tp->e_name = cp = (char *)malloc(len*3);
520: if (tp->e_name == NULL)
521: error("linkaddr_string: malloc");
522: if ((j = *ep >> 4) != 0)
523: *cp++ = hex[j];
524: *cp++ = hex[*ep++ & 0xf];
525: for (i = len-1; i > 0 ; --i) {
526: *cp++ = ':';
527: if ((j = *ep >> 4) != 0)
528: *cp++ = hex[j];
529: *cp++ = hex[*ep++ & 0xf];
530: }
531: *cp = '\0';
532: return (tp->e_name);
533: }
534:
535: const char *
536: ethertype_string(u_short type)
537: {
538: register char *cp;
539: register struct hnamemem *tp;
540: register u_int32_t i = type;
541: char buf[sizeof("0000")];
542:
543: for (tp = &etypetable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
544: if (tp->addr == i)
545: return (tp->name);
546:
547: tp->addr = i;
548: tp->nxt = newhnamemem();
549:
550: cp = buf;
551: NTOHS(type);
552: *cp++ = toupper(hex[type >> 12 & 0xf]);
553: *cp++ = toupper(hex[type >> 8 & 0xf]);
554: *cp++ = toupper(hex[type >> 4 & 0xf]);
555: *cp++ = toupper(hex[type & 0xf]);
556: *cp++ = '\0';
557: tp->name = strdup(buf);
558: return (tp->name);
559: }
560:
561: const char *
562: protoid_string(register const u_char *pi)
563: {
564: register u_int i, j;
565: register char *cp;
566: register struct protoidmem *tp;
567: char buf[sizeof("00:00:00:00:00")];
568:
569: tp = lookup_protoid(pi);
570: if (tp->p_name)
571: return tp->p_name;
572:
573: cp = buf;
574: if ((j = *pi >> 4) != 0)
575: *cp++ = hex[j];
576: *cp++ = hex[*pi++ & 0xf];
577: for (i = 4; (int)--i >= 0;) {
578: *cp++ = ':';
579: if ((j = *pi >> 4) != 0)
580: *cp++ = hex[j];
581: *cp++ = hex[*pi++ & 0xf];
582: }
583: *cp = '\0';
584: tp->p_name = strdup(buf);
585: return (tp->p_name);
586: }
587:
588: const char *
589: llcsap_string(u_char sap)
590: {
591: register struct hnamemem *tp;
592: register u_int32_t i = sap;
593: char buf[sizeof("sap-00")];
594:
595: for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
596: if (tp->addr == i)
597: return (tp->name);
598:
599: tp->addr = i;
600: tp->nxt = newhnamemem();
601:
602: snprintf(buf, sizeof(buf), "sap-%02x", sap & 0xff);
603: tp->name = strdup(buf);
604: return (tp->name);
605: }
606:
607: const char *
608: isonsap_string(const u_char *nsap)
609: {
610: register u_int i, nlen = nsap[0];
611: register char *cp;
612: register struct enamemem *tp;
613:
614: tp = lookup_nsap(nsap);
615: if (tp->e_name)
616: return tp->e_name;
617:
618: tp->e_name = cp = (char *)malloc(nlen * 2 + 2);
619: if (cp == NULL)
620: error("isonsap_string: malloc");
621:
622: nsap++;
623: *cp++ = '/';
624: for (i = nlen; (int)--i >= 0;) {
625: *cp++ = hex[*nsap >> 4];
626: *cp++ = hex[*nsap++ & 0xf];
627: }
628: *cp = '\0';
629: return (tp->e_name);
630: }
631:
632: const char *
633: tcpport_string(u_short port)
634: {
635: register struct hnamemem *tp;
636: register u_int32_t i = port;
637: char buf[sizeof("00000")];
638:
639: for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) {
640: if (tp->addr == i)
641: return (tp->name);
642: }
643: tp->addr = i;
644: tp->nxt = newhnamemem();
645:
646: (void)snprintf(buf, sizeof(buf), "%u", i);
647: tp->name = strdup(buf);
648: return (tp->name);
649: }
650:
651: const char *
652: udpport_string(u_short port)
653: {
654: register struct hnamemem *tp;
655: register u_int32_t i = port;
656: char buf[sizeof("00000")];
657:
658: for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) {
659: if (tp->addr == i)
660: return (tp->name);
661: }
662: tp->addr = i;
663: tp->nxt = newhnamemem();
664:
665: (void)snprintf(buf, sizeof(buf), "%u", i);
666: tp->name = strdup(buf);
667: return (tp->name);
668: }
669:
670: int
671: isservport(u_short port)
672: {
673: register struct hnamemem *tp;
674: register u_int32_t i = port;
675:
676: for (tp = &servtable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt) {
677: if (tp->addr == i)
678: return 1;
679: }
680: return 0;
681: }
682:
683: const char *
684: ipxsap_string(u_short port)
685: {
686: register char *cp;
687: register struct hnamemem *tp;
688: register u_int32_t i = port;
689: char buf[sizeof("0000")];
690:
691: for (tp = &ipxsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
692: if (tp->addr == i)
693: return (tp->name);
694:
695: tp->addr = i;
696: tp->nxt = newhnamemem();
697:
698: cp = buf;
699: NTOHS(port);
700: *cp++ = toupper(hex[port >> 12 & 0xf]);
701: *cp++ = toupper(hex[port >> 8 & 0xf]);
702: *cp++ = toupper(hex[port >> 4 & 0xf]);
703: *cp++ = toupper(hex[port & 0xf]);
704: *cp++ = '\0';
705: tp->name = strdup(buf);
706: return (tp->name);
707: }
708:
709: static void
710: init_servarray(void)
711: {
712: struct servent *sv;
713: register struct hnamemem *table;
714: register int i;
715:
716: while ((sv = getservent()) != NULL) {
717: int port = ntohs(sv->s_port);
718: i = port & (HASHNAMESIZE-1);
719:
720: table = &servtable[i];
721: if (table->addr != port) {
722: while (table->addr)
723: table = table->nxt;
724: table->addr = port;
725: table->nxt = newhnamemem();
726: }
727:
728: if (strcmp(sv->s_proto, "tcp") == 0)
729: table = &tporttable[i];
730: else if (strcmp(sv->s_proto, "udp") == 0)
731: table = &uporttable[i];
732: else continue;
733:
734: while (table->name)
735: table = table->nxt;
736: table->name = strdup(sv->s_name);
737: table->addr = port;
738: table->nxt = newhnamemem();
739: }
740: endservent();
741: }
742:
743: static struct tok ethertype_db[] = {
744: { ETHERTYPE_IP, "ip" },
745: { ETHERTYPE_MPLS, "mpls" },
746: { ETHERTYPE_MPLS_MULTI, "mpls-mc" },
747: { ETHERTYPE_IPV6, "ipv6" },
748: { ETHERTYPE_8021Q, "dot1q" },
749: { ETHERTYPE_VMAN, "vman" },
750: { ETHERTYPE_PUP, "pup" },
751: { ETHERTYPE_ARP, "arp" },
752: { ETHERTYPE_REVARP , "rarp" },
753: { ETHERTYPE_NS, "ns" },
754: { ETHERTYPE_SPRITE, "sprite" },
755: { ETHERTYPE_TRAIL, "trail" },
756: { ETHERTYPE_CDP, "cdp" },
757: { ETHERTYPE_MOPDL, "mop-dl" },
758: { ETHERTYPE_MOPRC, "mop-rc" },
759: { ETHERTYPE_DN, "dn" },
760: { ETHERTYPE_LAT, "lat" },
761: { ETHERTYPE_SCA, "sca" },
762: { ETHERTYPE_LANBRIDGE, "lanbridge" },
763: { ETHERTYPE_DECDNS, "dec-dns" },
764: { ETHERTYPE_DECDTS, "dec-dts" },
765: { ETHERTYPE_VEXP, "vexp" },
766: { ETHERTYPE_VPROD, "vprod" },
767: { ETHERTYPE_ATALK, "atalk" },
768: { ETHERTYPE_AARP, "atalk-arp" },
769: { ETHERTYPE_IPX, "ipx" },
770: { ETHERTYPE_PPP, "ppp" },
771: { ETHERTYPE_PPPOED, "pppoe-d" },
772: { ETHERTYPE_PPPOES, "pppoe-s" },
773: { ETHERTYPE_LOOPBACK, "loopback" },
774: { 0, NULL }
775: };
776:
777: static void
778: init_etypearray(void)
779: {
780: register int i;
781: register struct hnamemem *table;
782:
783: for (i = 0; ethertype_db[i].s; i++) {
784: int j = htons(ethertype_db[i].v) & (HASHNAMESIZE-1);
785: table = &etypetable[j];
786: while (table->name)
787: table = table->nxt;
788: table->name = ethertype_db[i].s;
789: table->addr = htons(ethertype_db[i].v);
790: table->nxt = newhnamemem();
791: }
792: }
793:
794: static struct protoidlist {
795: const u_char protoid[5];
796: const char *name;
797: } protoidlist[] = {
798: {{ 0x00, 0x00, 0x0c, 0x01, 0x07 }, "CiscoMLS" },
799: {{ 0x00, 0x00, 0x0c, 0x20, 0x00 }, "CiscoCDP" },
800: {{ 0x00, 0x00, 0x0c, 0x20, 0x01 }, "CiscoCGMP" },
801: {{ 0x00, 0x00, 0x0c, 0x20, 0x03 }, "CiscoVTP" },
802: {{ 0x00, 0xe0, 0x2b, 0x00, 0xbb }, "ExtremeEDP" },
803: {{ 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
804: };
805:
806: /*
807: * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
808: * types.
809: */
810: static void
811: init_protoidarray(void)
812: {
813: register int i;
814: register struct protoidmem *tp;
815: struct protoidlist *pl;
816: u_char protoid[5];
817:
818: protoid[0] = 0;
819: protoid[1] = 0;
820: protoid[2] = 0;
821: for (i = 0; ethertype_db[i].s; i++) {
822: u_short etype = htons(ethertype_db[i].v);
823:
824: memcpy((char *)&protoid[3], (char *)&etype, 2);
825: tp = lookup_protoid(protoid);
826: tp->p_name = strdup(ethertype_db[i].s);
827: }
828: /* Hardwire some SNAP proto ID names */
829: for (pl = protoidlist; pl->name != NULL; ++pl) {
830: tp = lookup_protoid(pl->protoid);
831: /* Don't override existing name */
832: if (tp->p_name != NULL)
833: continue;
834:
835: tp->p_name = pl->name;
836: }
837: }
838:
839: static struct etherlist {
840: const u_char addr[6];
841: const char *name;
842: } etherlist[] = {
843: {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, "ethernet" },
844: {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "broadcast" },
845: {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
846: };
847:
848: /*
849: * Initialize the ethers hash table. We take two different approaches
850: * depending on whether or not the system provides the ethers name
851: * service. If it does, we just wire in a few names at startup,
852: * and etheraddr_string() fills in the table on demand. If it doesn't,
853: * then we suck in the entire /etc/ethers file at startup. The idea
854: * is that parsing the local file will be fast, but spinning through
855: * all the ethers entries via NIS & next_etherent might be very slow.
856: *
857: * XXX pcap_next_etherent doesn't belong in the pcap interface, but
858: * since the pcap module already does name-to-address translation,
859: * it's already does most of the work for the ethernet address-to-name
860: * translation, so we just pcap_next_etherent as a convenience.
861: */
862: static void
863: init_etherarray(void)
864: {
865: register struct etherlist *el;
866: register struct enamemem *tp;
867: #ifdef USE_ETHER_NTOHOST
868: char name[256];
869: #else
870: register struct pcap_etherent *ep;
871: register FILE *fp;
872:
873: /* Suck in entire ethers file */
874: fp = fopen(PCAP_ETHERS_FILE, "r");
875: if (fp != NULL) {
876: while ((ep = pcap_next_etherent(fp)) != NULL) {
877: tp = lookup_emem(ep->addr);
878: tp->e_name = strdup(ep->name);
879: }
880: (void)fclose(fp);
881: }
882: #endif
883:
884: /* Hardwire some ethernet names */
885: for (el = etherlist; el->name != NULL; ++el) {
886: tp = lookup_emem(el->addr);
887: /* Don't override existing name */
888: if (tp->e_name != NULL)
889: continue;
890:
891: #ifdef USE_ETHER_NTOHOST
892: /* Use yp/nis version of name if available */
893: if (ether_ntohost(name, (const struct ether_addr *)el->addr) == 0) {
894: tp->e_name = strdup(name);
895: continue;
896: }
897: #endif
898: tp->e_name = el->name;
899: }
900: }
901:
902: static struct tok llcsap_db[] = {
903: /* IEEE SAPs */
904: { 0x00, "null" },
905: { 0x02, "isap" },
906: { 0x03, "gsap" },
907: { 0x06, "ip-sap" },
908: { 0x0e, "proway-nm" },
909: { 0x42, "stp" },
910: { 0x4e, "rs511" },
911: { 0x5e, "isi-ip" },
912: { 0x7e, "x25-plp" },
913: { 0x80, "3com" },
914: { 0x8e, "proway" },
915: { 0xaa, "snap" },
916: { 0xbc, "banyan" },
917: { 0xe0, "ipx" },
918: { 0xf0, "netbeui" },
919: { 0xf4, "lanman" },
920: { 0xfe, "iso-clns" },
921: { 0xff, "raw-ipx" }, /* known as raw 802.3 packet */
922: /* IBM SAPs */
923: { 0x04, "isna" },
924: { 0x05, "gsna" },
925: { 0xd4, "resource" },
926: { 0xdc, "dyn-arp" },
927: { 0xf0, "netbios" },
928: { 0xf8, "irpl" },
929: { 0xf4, "ilan" },
930: { 0xf5, "glan" },
931: { 0xfc, "discovery" },
932: { 0, NULL }
933: };
934:
935: static void
936: init_llcsaparray(void)
937: {
938: register int i;
939: register struct hnamemem *table;
940:
941: for (i = 0; llcsap_db[i].s != NULL; i++) {
942: table = &llcsaptable[llcsap_db[i].v];
943: while (table->name)
944: table = table->nxt;
945: table->name = llcsap_db[i].s;
946: table->addr = llcsap_db[i].v;
947: table->nxt = newhnamemem();
948: }
949: }
950:
951: static struct tok ipxsap_db[] = {
952: { 0x0000, "Unknown" },
953: { 0x0001, "User" },
954: { 0x0002, "User Group" },
955: { 0x0003, "PrintQueue" },
956: { 0x0004, "FileServer" },
957: { 0x0005, "JobServer" },
958: { 0x0006, "Gateway" },
959: { 0x0007, "PrintServer" },
960: { 0x0008, "ArchiveQueue" },
961: { 0x0009, "ArchiveServer" },
962: { 0x000a, "JobQueue" },
963: { 0x000b, "Administration" },
964: { 0x000F, "Novell TI-RPC" },
965: { 0x0017, "Diagnostics" },
966: { 0x0020, "NetBIOS" },
967: { 0x0021, "NAS SNA Gateway" },
968: { 0x0023, "NACS AsyncGateway" },
969: { 0x0024, "RemoteBridge/RoutingService" },
970: { 0x0026, "BridgeServer" },
971: { 0x0027, "TCP/IP Gateway" },
972: { 0x0028, "Point-to-point X.25 BridgeServer" },
973: { 0x0029, "3270 Gateway" },
974: { 0x002a, "CHI Corp" },
975: { 0x002c, "PC Chalkboard" },
976: { 0x002d, "TimeSynchServer" },
977: { 0x002e, "ARCserve5.0/PalindromeBackup" },
978: { 0x0045, "DI3270 Gateway" },
979: { 0x0047, "AdvertisingPrintServer" },
980: { 0x004a, "NetBlazerModems" },
981: { 0x004b, "BtrieveVAP" },
982: { 0x004c, "NetwareSQL" },
983: { 0x004d, "XtreeNetwork" },
984: { 0x0050, "BtrieveVAP4.11" },
985: { 0x0052, "QuickLink" },
986: { 0x0053, "PrintQueueUser" },
987: { 0x0058, "Multipoint X.25 Router" },
988: { 0x0060, "STLB/NLM" },
989: { 0x0064, "ARCserve" },
990: { 0x0066, "ARCserve3.0" },
991: { 0x0072, "WAN CopyUtility" },
992: { 0x007a, "TES-NetwareVMS" },
993: { 0x0092, "WATCOM Debugger/EmeraldTapeBackupServer" },
994: { 0x0095, "DDA OBGYN" },
995: { 0x0098, "NetwareAccessServer" },
996: { 0x009a, "Netware for VMS II/NamedPipeServer" },
997: { 0x009b, "NetwareAccessServer" },
998: { 0x009e, "PortableNetwareServer/SunLinkNVT" },
999: { 0x00a1, "PowerchuteAPC UPS" },
1000: { 0x00aa, "LAWserve" },
1001: { 0x00ac, "CompaqIDA StatusMonitor" },
1002: { 0x0100, "PIPE STAIL" },
1003: { 0x0102, "LAN ProtectBindery" },
1004: { 0x0103, "OracleDataBaseServer" },
1005: { 0x0107, "Netware386/RSPX RemoteConsole" },
1006: { 0x010f, "NovellSNA Gateway" },
1007: { 0x0111, "TestServer" },
1008: { 0x0112, "HP PrintServer" },
1009: { 0x0114, "CSA MUX" },
1010: { 0x0115, "CSA LCA" },
1011: { 0x0116, "CSA CM" },
1012: { 0x0117, "CSA SMA" },
1013: { 0x0118, "CSA DBA" },
1014: { 0x0119, "CSA NMA" },
1015: { 0x011a, "CSA SSA" },
1016: { 0x011b, "CSA STATUS" },
1017: { 0x011e, "CSA APPC" },
1018: { 0x0126, "SNA TEST SSA Profile" },
1019: { 0x012a, "CSA TRACE" },
1020: { 0x012b, "NetwareSAA" },
1021: { 0x012e, "IKARUS VirusScan" },
1022: { 0x0130, "CommunicationsExecutive" },
1023: { 0x0133, "NNS DomainServer/NetwareNamingServicesDomain" },
1024: { 0x0135, "NetwareNamingServicesProfile" },
1025: { 0x0137, "Netware386 PrintQueue/NNS PrintQueue" },
1026: { 0x0141, "LAN SpoolServer" },
1027: { 0x0152, "IRMALAN Gateway" },
1028: { 0x0154, "NamedPipeServer" },
1029: { 0x0166, "NetWareManagement" },
1030: { 0x0168, "Intel PICKIT CommServer/Intel CAS TalkServer" },
1031: { 0x0173, "Compaq" },
1032: { 0x0174, "Compaq SNMP Agent" },
1033: { 0x0175, "Compaq" },
1034: { 0x0180, "XTreeServer/XTreeTools" },
1035: { 0x018A, "NASI ServicesBroadcastServer" },
1036: { 0x01b0, "GARP Gateway" },
1037: { 0x01b1, "Binfview" },
1038: { 0x01bf, "IntelLanDeskManager" },
1039: { 0x01ca, "AXTEC" },
1040: { 0x01cb, "ShivaNetModem/E" },
1041: { 0x01cc, "ShivaLanRover/E" },
1042: { 0x01cd, "ShivaLanRover/T" },
1043: { 0x01ce, "ShivaUniversal" },
1044: { 0x01d8, "CastelleFAXPressServer" },
1045: { 0x01da, "CastelleLANPressPrintServer" },
1046: { 0x01dc, "CastelleFAX/Xerox7033 FaxServer/ExcelLanFax" },
1047: { 0x01f0, "LEGATO" },
1048: { 0x01f5, "LEGATO" },
1049: { 0x0233, "NMS Agent/NetwareManagementAgent" },
1050: { 0x0237, "NMS IPX Discovery/LANternReadWriteChannel" },
1051: { 0x0238, "NMS IP Discovery/LANternTrapAlarmChannel" },
1052: { 0x023a, "LANtern" },
1053: { 0x023c, "MAVERICK" },
1054: { 0x023f, "NovellSMDR" },
1055: { 0x024e, "NetwareConnect" },
1056: { 0x024f, "NASI ServerBroadcast Cisco" },
1057: { 0x026a, "NMS ServiceConsole" },
1058: { 0x026b, "TimeSynchronizationServer Netware 4.x" },
1059: { 0x0278, "DirectoryServer Netware 4.x" },
1060: { 0x027b, "NetwareManagementAgent" },
1061: { 0x0280, "Novell File and Printer Sharing Service for PC" },
1062: { 0x0304, "NovellSAA Gateway" },
1063: { 0x0308, "COM/VERMED" },
1064: { 0x030a, "GalacticommWorldgroupServer" },
1065: { 0x030c, "IntelNetport2/HP JetDirect/HP Quicksilver" },
1066: { 0x0320, "AttachmateGateway" },
1067: { 0x0327, "MicrosoftDiagnostiocs" },
1068: { 0x0328, "WATCOM SQL Server" },
1069: { 0x0335, "MultiTechSystems MultisynchCommServer" },
1070: { 0x0343, "Xylogics RemoteAccessServer/LANModem" },
1071: { 0x0355, "ArcadaBackupExec" },
1072: { 0x0358, "MSLCD1" },
1073: { 0x0361, "NETINELO" },
1074: { 0x037e, "Powerchute UPS Monitoring" },
1075: { 0x037f, "ViruSafeNotify" },
1076: { 0x0386, "HP Bridge" },
1077: { 0x0387, "HP Hub" },
1078: { 0x0394, "NetWare SAA Gateway" },
1079: { 0x039b, "LotusNotes" },
1080: { 0x03b7, "CertusAntiVirus" },
1081: { 0x03c4, "ARCserve4.0" },
1082: { 0x03c7, "LANspool3.5" },
1083: { 0x03d7, "LexmarkPrinterServer" },
1084: { 0x03d8, "LexmarkXLE PrinterServer" },
1085: { 0x03dd, "BanyanENS NetwareClient" },
1086: { 0x03de, "GuptaSequelBaseServer/NetWareSQL" },
1087: { 0x03e1, "UnivelUnixware" },
1088: { 0x03e4, "UnivelUnixware" },
1089: { 0x03fc, "IntelNetport" },
1090: { 0x03fd, "PrintServerQueue" },
1091: { 0x040A, "ipnServer" },
1092: { 0x040D, "LVERRMAN" },
1093: { 0x040E, "LVLIC" },
1094: { 0x0414, "NET Silicon (DPI)/Kyocera" },
1095: { 0x0429, "SiteLockVirus" },
1096: { 0x0432, "UFHELPR???" },
1097: { 0x0433, "Synoptics281xAdvancedSNMPAgent" },
1098: { 0x0444, "MicrosoftNT SNA Server" },
1099: { 0x0448, "Oracle" },
1100: { 0x044c, "ARCserve5.01" },
1101: { 0x0457, "CanonGP55" },
1102: { 0x045a, "QMS Printers" },
1103: { 0x045b, "DellSCSI Array" },
1104: { 0x0491, "NetBlazerModems" },
1105: { 0x04ac, "OnTimeScheduler" },
1106: { 0x04b0, "CD-Net" },
1107: { 0x0513, "EmulexNQA" },
1108: { 0x0520, "SiteLockChecks" },
1109: { 0x0529, "SiteLockChecks" },
1110: { 0x052d, "CitrixOS2 AppServer" },
1111: { 0x0535, "Tektronix" },
1112: { 0x0536, "Milan" },
1113: { 0x055d, "Attachmate SNA gateway" },
1114: { 0x056b, "IBM8235 ModemServer" },
1115: { 0x056c, "ShivaLanRover/E PLUS" },
1116: { 0x056d, "ShivaLanRover/T PLUS" },
1117: { 0x0580, "McAfeeNetShield" },
1118: { 0x05B8, "NLM to workstation communication (Revelation Software)" },
1119: { 0x05BA, "CompatibleSystemsRouters" },
1120: { 0x05BE, "CheyenneHierarchicalStorageManager" },
1121: { 0x0606, "JCWatermarkImaging" },
1122: { 0x060c, "AXISNetworkPrinter" },
1123: { 0x0610, "AdaptecSCSIManagement" },
1124: { 0x0621, "IBM AntiVirus" },
1125: { 0x0640, "Windows95 RemoteRegistryService" },
1126: { 0x064e, "MicrosoftIIS" },
1127: { 0x067b, "Microsoft Win95/98 File and Print Sharing for NetWare" },
1128: { 0x067c, "Microsoft Win95/98 File and Print Sharing for NetWare" },
1129: { 0x076C, "Xerox" },
1130: { 0x079b, "ShivaLanRover/E 115" },
1131: { 0x079c, "ShivaLanRover/T 115" },
1132: { 0x07B4, "CubixWorldDesk" },
1133: { 0x07c2, "Quarterdeck IWare Connect V2.x NLM" },
1134: { 0x07c1, "Quarterdeck IWare Connect V3.x NLM" },
1135: { 0x0810, "ELAN License Server Demo" },
1136: { 0x0824, "ShivaLanRoverAccessSwitch/E" },
1137: { 0x086a, "ISSC Collector" },
1138: { 0x087f, "ISSC DAS AgentAIX" },
1139: { 0x0880, "Intel Netport PRO" },
1140: { 0x0881, "Intel Netport PRO" },
1141: { 0x0b29, "SiteLock" },
1142: { 0x0c29, "SiteLockApplications" },
1143: { 0x0c2c, "LicensingServer" },
1144: { 0x2101, "PerformanceTechnologyInstantInternet" },
1145: { 0x2380, "LAI SiteLock" },
1146: { 0x238c, "MeetingMaker" },
1147: { 0x4808, "SiteLockServer/SiteLockMetering" },
1148: { 0x5555, "SiteLockUser" },
1149: { 0x6312, "Tapeware" },
1150: { 0x6f00, "RabbitGateway" },
1151: { 0x7703, "MODEM" },
1152: { 0x8002, "NetPortPrinters" },
1153: { 0x8008, "WordPerfectNetworkVersion" },
1154: { 0x85BE, "Cisco EIGRP" },
1155: { 0x8888, "WordPerfectNetworkVersion/QuickNetworkManagement" },
1156: { 0x9000, "McAfeeNetShield" },
1157: { 0x9604, "CSA-NT_MON" },
1158: { 0xb6a8, "OceanIsleReachoutRemoteControl" },
1159: { 0xf11f, "SiteLockMetering" },
1160: { 0xf1ff, "SiteLock" },
1161: { 0xf503, "Microsoft SQL Server" },
1162: { 0xF905, "IBM TimeAndPlace" },
1163: { 0xfbfb, "TopCallIII FaxServer" },
1164: { 0xffff, "AnyService/Wildcard" },
1165: { 0, (char *)0 }
1166: };
1167:
1168: static void
1169: init_ipxsaparray(void)
1170: {
1171: register int i;
1172: register struct hnamemem *table;
1173:
1174: for (i = 0; ipxsap_db[i].s != NULL; i++) {
1175: int j = htons(ipxsap_db[i].v) & (HASHNAMESIZE-1);
1176: table = &ipxsaptable[j];
1177: while (table->name)
1178: table = table->nxt;
1179: table->name = ipxsap_db[i].s;
1180: table->addr = htons(ipxsap_db[i].v);
1181: table->nxt = newhnamemem();
1182: }
1183: }
1184:
1185: const char *
1186: ipproto_string(u_char proto)
1187: {
1188: register struct hnamemem *tp;
1189: register u_int32_t i = proto;
1190: char buf[sizeof("00000")];
1191:
1192: for (tp = &iprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
1193: if (tp->addr == i)
1194: return (tp->name);
1195:
1196: tp->addr = i;
1197: tp->nxt = newhnamemem();
1198:
1199: (void)snprintf(buf, sizeof(buf), "%u", i);
1200: tp->name = strdup(buf);
1201: return (tp->name);
1202: }
1203:
1204: static void
1205: init_iprotoarray(void)
1206: {
1207: struct protoent *pe;
1208: register struct hnamemem *tp;
1209: register u_int32_t i;
1210:
1211: while ((pe = getprotoent()) != NULL) {
1212: i = pe->p_proto;
1213: for (tp = &iprototable[i & (HASHNAMESIZE-1)];
1214: tp->name; tp = tp->nxt) ;
1215:
1216: tp->name = strdup(pe->p_name);
1217: tp->addr = i;
1218: tp->nxt = newhnamemem();
1219: }
1220: endprotoent();
1221: }
1222:
1223: static struct tok icmp_db[] = {
1224: { 0x0000, "echo-reply" },
1225: { 0x0300, "unrch-net" },
1226: { 0x0301, "unrch-host" },
1227: { 0x0302, "unrch-proto" },
1228: { 0x0303, "unrch-port" },
1229: { 0x0304, "need-frag" },
1230: { 0x0305, "src-fail" },
1231: { 0x0306, "bad-net" },
1232: { 0x0307, "bad-host" },
1233: { 0x0308, "isolated" },
1234: { 0x0309, "net-prhbt" },
1235: { 0x030a, "host-prhbt" },
1236: { 0x030b, "bad-ntos" },
1237: { 0x030c, "bad-htos" },
1238: { 0x030d, "filtered" },
1239: { 0x030e, "no-prec" },
1240: { 0x030f, "prec-cut" },
1241: { 0x0400, "quench" },
1242: { 0x0500, "redir-net" },
1243: { 0x0501, "redir-hst" },
1244: { 0x0502, "redir-ntos" },
1245: { 0x0503, "redir-htos" },
1246: { 0x0800, "echo-reqst" },
1247: { 0x0900, "advert" },
1248: { 0x0a00, "solicit" },
1249: { 0x0b00, "ttl-exceed" },
1250: { 0x0b01, "frg-exceed" },
1251: { 0x0c00, "err-atptr" },
1252: { 0x0c01, "optabsent" },
1253: { 0x0c02, "bad-len" },
1254: { 0x0d00, "time-reqst" },
1255: { 0x0e00, "time-reply" },
1256: { 0x0f00, "info-reqst" },
1257: { 0x1000, "info-reply" },
1258: { 0x1100, "mask-reqst" },
1259: { 0x1200, "mask-reply" },
1260: { 0, NULL }
1261: };
1262:
1263: static void
1264: init_icmparray(void)
1265: {
1266: register int i;
1267: register struct hnamemem *table;
1268:
1269: for (i = 0; icmp_db[i].s != NULL; i++) {
1270: table = &icmptable[icmp_db[i].v & (HASHNAMESIZE-1)];
1271: while (table->name)
1272: table = table->nxt;
1273: table->name = icmp_db[i].s;
1274: table->addr = icmp_db[i].v;
1275: table->nxt = newhnamemem();
1276: }
1277: }
1278:
1279: const char *
1280: icmp_string(u_short code)
1281: {
1282: register struct hnamemem *tp;
1283: register u_int32_t i = code;
1284: char buf[sizeof("0000")];
1285:
1286: for (tp = &icmptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
1287: if (tp->addr == i)
1288: return (tp->name);
1289:
1290: tp->addr = i;
1291: tp->nxt = newhnamemem();
1292:
1293: snprintf(buf, sizeof(buf), "%04x", code);
1294: tp->name = strdup(buf);
1295: return (tp->name);
1296: }
1297:
1298: #ifdef INET6
1299: static struct tok icmpv6_db[] = {
1300: { 0x0100, "no-route" },
1301: { 0x0101, "adm-prhbt" },
1302: { 0x0102, "not-nghbr" },
1303: { 0x0103, "addr-unrch" },
1304: { 0x0104, "bad-port" },
1305: { 0x0200, "pkt-toobig" },
1306: { 0x0300, "hop-exceed" },
1307: { 0x0301, "frg-exceed" },
1308: { 0x0400, "bad-hdr" },
1309: { 0x0401, "unkn-nhdr" },
1310: { 0x0402, "unkn-opt" },
1311: { 0x8000, "echo-reqst" },
1312: { 0x8100, "echo-repl" },
1313: { 0x8200, "membr-qry" },
1314: { 0x8300, "membr-rprt" },
1315: { 0x8400, "membr-red" },
1316: { 0x8500, "router-sol" },
1317: { 0x8600, "router-adv" },
1318: { 0x8700, "nghbr-sol" },
1319: { 0x8800, "nghbr-adv" },
1320: { 0x8900, "redirect" },
1321: { 0, NULL }
1322: };
1323:
1324: static void
1325: init_icmpv6array(void)
1326: {
1327: register int i;
1328: register struct hnamemem *table;
1329:
1330: for (i = 0; icmpv6_db[i].s != NULL; i++) {
1331: table = &icmpv6table[icmpv6_db[i].v & (HASHNAMESIZE-1)];
1332: while (table->name)
1333: table = table->nxt;
1334: table->name = icmpv6_db[i].s;
1335: table->addr = icmpv6_db[i].v;
1336: table->nxt = newhnamemem();
1337: }
1338: }
1339:
1340: const char *
1341: icmpv6_string(u_short code)
1342: {
1343: register struct hnamemem *tp;
1344: register u_int32_t i = code;
1345: char buf[sizeof("0000")];
1346:
1347: for (tp = &icmpv6table[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
1348: if (tp->addr == i)
1349: return (tp->name);
1350:
1351: tp->addr = i;
1352: tp->nxt = newhnamemem();
1353:
1354: snprintf(buf, sizeof(buf), "%04x", code);
1355: tp->name = strdup(buf);
1356: return (tp->name);
1357: }
1358: #endif
1359:
1360: /*
1361: * Initialize the address to name translation machinery. We map all
1362: * non-local IP addresses to numeric addresses if fflag is true (i.e.,
1363: * to prevent blocking on the nameserver). localnet is the IP address
1364: * of the local network. mask is its subnet mask.
1365: */
1366: void
1367: init_addrtoname()
1368: {
1369: #ifdef notdef
1370: if (nflag)
1371: /*
1372: * Simplest way to suppress names.
1373: */
1374: return;
1375: #endif
1376: init_etherarray();
1377: init_servarray();
1378: init_etypearray();
1379: init_llcsaparray();
1380: init_protoidarray();
1381: init_ipxsaparray();
1382: init_iprotoarray();
1383: init_icmparray();
1384: #ifdef INET6
1385: init_icmpv6array();
1386: #endif
1387: }
1388:
1389: #ifdef notdef
1390: const char *
1391: dnaddr_string(u_short dnaddr)
1392: {
1393: register struct hnamemem *tp;
1394:
1395: for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0;
1396: tp = tp->nxt)
1397: if (tp->addr == dnaddr)
1398: return (tp->name);
1399:
1400: tp->addr = dnaddr;
1401: tp->nxt = newhnamemem();
1402: if (nflag)
1403: tp->name = dnnum_string(dnaddr);
1404: else
1405: tp->name = dnname_string(dnaddr);
1406:
1407: return(tp->name);
1408: }
1409: #endif
1410:
1411: /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
1412: struct hnamemem *
1413: newhnamemem(void)
1414: {
1415: register struct hnamemem *p;
1416: static struct hnamemem *ptr = NULL;
1417: static u_int num = 0;
1418:
1419: if (num <= 0) {
1420: num = 64;
1421: ptr = (struct hnamemem *)calloc(num, sizeof (*ptr));
1422: if (ptr == NULL)
1423: error("newhnamemem: calloc");
1424: }
1425: --num;
1426: p = ptr++;
1427: return (p);
1428: }
1429:
1430: #ifdef INET6
1431: /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */
1432: struct h6namemem *
1433: newh6namemem(void)
1434: {
1435: register struct h6namemem *p;
1436: static struct h6namemem *ptr = NULL;
1437: static u_int num = 0;
1438:
1439: if (num <= 0) {
1440: num = 64;
1441: ptr = (struct h6namemem *)calloc(num, sizeof (*ptr));
1442: if (ptr == NULL)
1443: error("newh6namemem: calloc");
1444: }
1445: --num;
1446: p = ptr++;
1447: return (p);
1448: }
1449: #endif /* INET6 */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>