tcpdump  4.99.1
About: tcpdump is a tool for network monitoring and data acquisition.
  Fossies Dox: tcpdump-4.99.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

addrtoname.c
Go to the documentation of this file.
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 
25 #ifdef HAVE_CONFIG_H
26 #include <config.h>
27 #endif
28 
29 #ifdef HAVE_CASPER
30 #include <libcasper.h>
31 #include <casper/cap_dns.h>
32 #endif /* HAVE_CASPER */
33 
34 #include "netdissect-stdinc.h"
35 
36 #ifdef _WIN32
37  /*
38  * We have our own ether_ntohost(), reading from the system's
39  * Ethernet address file.
40  */
42 #else
43  #ifdef USE_ETHER_NTOHOST
44  #if defined(NET_ETHERNET_H_DECLARES_ETHER_NTOHOST)
45  /*
46  * OK, just include <net/ethernet.h>.
47  */
48  #include <net/ethernet.h>
49  #elif defined(NETINET_ETHER_H_DECLARES_ETHER_NTOHOST)
50  /*
51  * OK, just include <netinet/ether.h>
52  */
53  #include <netinet/ether.h>
54  #elif defined(SYS_ETHERNET_H_DECLARES_ETHER_NTOHOST)
55  /*
56  * OK, just include <sys/ethernet.h>
57  */
58  #include <sys/ethernet.h>
59  #elif defined(ARPA_INET_H_DECLARES_ETHER_NTOHOST)
60  /*
61  * OK, just include <arpa/inet.h>
62  */
63  #include <arpa/inet.h>
64  #elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_NTOHOST)
65  /*
66  * OK, include <netinet/if_ether.h>, after all the other stuff we
67  * need to include or define for its benefit.
68  */
69  #define NEED_NETINET_IF_ETHER_H
70  #else
71  /*
72  * We'll have to declare it ourselves.
73  * If <netinet/if_ether.h> defines struct ether_addr, include
74  * it. Otherwise, define it ourselves.
75  */
76  #ifdef HAVE_STRUCT_ETHER_ADDR
77  #define NEED_NETINET_IF_ETHER_H
78  #else /* HAVE_STRUCT_ETHER_ADDR */
79  struct ether_addr {
80  /* Beware FreeBSD calls this "octet". */
81  unsigned char ether_addr_octet[MAC_ADDR_LEN];
82  };
83  #endif /* HAVE_STRUCT_ETHER_ADDR */
84  #endif /* what declares ether_ntohost() */
85 
86  #ifdef NEED_NETINET_IF_ETHER_H
87  #include <net/if.h> /* Needed on some platforms */
88  #include <netinet/in.h> /* Needed on some platforms */
89  #include <netinet/if_ether.h>
90  #endif /* NEED_NETINET_IF_ETHER_H */
91 
92  #ifndef HAVE_DECL_ETHER_NTOHOST
93  /*
94  * No header declares it, so declare it ourselves.
95  */
96  extern int ether_ntohost(char *, const struct ether_addr *);
97  #endif /* !defined(HAVE_DECL_ETHER_NTOHOST) */
98  #endif /* USE_ETHER_NTOHOST */
99 #endif /* _WIN32 */
100 
101 #include <pcap.h>
102 #include <pcap-namedb.h>
103 #ifndef HAVE_GETSERVENT
104 #include <getservent.h>
105 #endif
106 #include <signal.h>
107 #include <stdio.h>
108 #include <string.h>
109 #include <stdlib.h>
110 
111 #include "netdissect.h"
112 #include "addrtoname.h"
113 #include "addrtostr.h"
114 #include "ethertype.h"
115 #include "llc.h"
116 #include "extract.h"
117 #include "oui.h"
118 
119 /*
120  * hash tables for whatever-to-name translations
121  *
122  * ndo_error() called on strdup(3) failure with S_ERR_ND_MEM_ALLOC status
123  */
124 
125 #define HASHNAMESIZE 4096
126 
127 struct hnamemem {
128  uint32_t addr;
129  const char *name;
130  struct hnamemem *nxt;
131 };
132 
133 static struct hnamemem hnametable[HASHNAMESIZE];
134 static struct hnamemem tporttable[HASHNAMESIZE];
135 static struct hnamemem uporttable[HASHNAMESIZE];
136 static struct hnamemem eprototable[HASHNAMESIZE];
137 static struct hnamemem dnaddrtable[HASHNAMESIZE];
138 static struct hnamemem ipxsaptable[HASHNAMESIZE];
139 
140 #ifdef _WIN32
141 /*
142  * fake gethostbyaddr for Win2k/XP
143  * gethostbyaddr() returns incorrect value when AF_INET6 is passed
144  * to 3rd argument.
145  *
146  * h_name in struct hostent is only valid.
147  */
148 static struct hostent *
149 win32_gethostbyaddr(const char *addr, int len, int type)
150 {
151  static struct hostent host;
152  static char hostbuf[NI_MAXHOST];
153  char hname[NI_MAXHOST];
154  struct sockaddr_in6 addr6;
155 
156  host.h_name = hostbuf;
157  switch (type) {
158  case AF_INET:
159  return gethostbyaddr(addr, len, type);
160  break;
161  case AF_INET6:
162  memset(&addr6, 0, sizeof(addr6));
163  addr6.sin6_family = AF_INET6;
164  memcpy(&addr6.sin6_addr, addr, len);
165  if (getnameinfo((struct sockaddr *)&addr6, sizeof(addr6),
166  hname, sizeof(hname), NULL, 0, 0)) {
167  return NULL;
168  } else {
169  strlcpy(host.h_name, hname, NI_MAXHOST);
170  return &host;
171  }
172  break;
173  default:
174  return NULL;
175  }
176 }
177 #define gethostbyaddr win32_gethostbyaddr
178 #endif /* _WIN32 */
179 
180 struct h6namemem {
182  char *name;
183  struct h6namemem *nxt;
184 };
185 
186 static struct h6namemem h6nametable[HASHNAMESIZE];
187 
188 struct enamemem {
189  u_short e_addr0;
190  u_short e_addr1;
191  u_short e_addr2;
192  const char *e_name;
193  u_char *e_nsap; /* used only for nsaptable[] */
194  struct enamemem *e_nxt;
195 };
196 
197 static struct enamemem enametable[HASHNAMESIZE];
198 static struct enamemem nsaptable[HASHNAMESIZE];
199 
200 struct bsnamemem {
201  u_short bs_addr0;
202  u_short bs_addr1;
203  u_short bs_addr2;
204  const char *bs_name;
205  u_char *bs_bytes;
206  unsigned int bs_nbytes;
207  struct bsnamemem *bs_nxt;
208 };
209 
210 static struct bsnamemem bytestringtable[HASHNAMESIZE];
211 
212 struct protoidmem {
213  uint32_t p_oui;
214  u_short p_proto;
215  const char *p_name;
216  struct protoidmem *p_nxt;
217 };
218 
219 static struct protoidmem protoidtable[HASHNAMESIZE];
220 
221 /*
222  * A faster replacement for inet_ntoa().
223  */
224 const char *
225 intoa(uint32_t addr)
226 {
227  char *cp;
228  u_int byte;
229  int n;
230  static char buf[sizeof(".xxx.xxx.xxx.xxx")];
231 
232  addr = ntohl(addr);
233  cp = buf + sizeof(buf);
234  *--cp = '\0';
235 
236  n = 4;
237  do {
238  byte = addr & 0xff;
239  *--cp = (char)(byte % 10) + '0';
240  byte /= 10;
241  if (byte > 0) {
242  *--cp = (char)(byte % 10) + '0';
243  byte /= 10;
244  if (byte > 0)
245  *--cp = (char)byte + '0';
246  }
247  *--cp = '.';
248  addr >>= 8;
249  } while (--n > 0);
250 
251  return cp + 1;
252 }
253 
254 static uint32_t f_netmask;
255 static uint32_t f_localnet;
256 #ifdef HAVE_CASPER
257 extern cap_channel_t *capdns;
258 #endif
259 
260 /*
261  * Return a name for the IP address pointed to by ap. This address
262  * is assumed to be in network byte order.
263  *
264  * NOTE: ap is *NOT* necessarily part of the packet data, so you
265  * *CANNOT* use the ND_TCHECK_* or ND_TTEST_* macros on it. Furthermore,
266  * even in cases where it *is* part of the packet data, the caller
267  * would still have to check for a null return value, even if it's
268  * just printing the return value with "%s" - not all versions of
269  * printf print "(null)" with "%s" and a null pointer, some of them
270  * don't check for a null pointer and crash in that case.
271  *
272  * The callers of this routine should, before handing this routine
273  * a pointer to packet data, be sure that the data is present in
274  * the packet buffer. They should probably do those checks anyway,
275  * as other data at that layer might not be IP addresses, and it
276  * also needs to check whether they're present in the packet buffer.
277  */
278 const char *
279 ipaddr_string(netdissect_options *ndo, const u_char *ap)
280 {
281  struct hostent *hp;
282  uint32_t addr;
283  struct hnamemem *p;
284 
285  memcpy(&addr, ap, sizeof(addr));
286  p = &hnametable[addr & (HASHNAMESIZE-1)];
287  for (; p->nxt; p = p->nxt) {
288  if (p->addr == addr)
289  return (p->name);
290  }
291  p->addr = addr;
292  p->nxt = newhnamemem(ndo);
293 
294  /*
295  * Print names unless:
296  * (1) -n was given.
297  * (2) Address is foreign and -f was given. (If -f was not
298  * given, f_netmask and f_localnet are 0 and the test
299  * evaluates to true)
300  */
301  if (!ndo->ndo_nflag &&
302  (addr & f_netmask) == f_localnet) {
303 #ifdef HAVE_CASPER
304  if (capdns != NULL) {
305  hp = cap_gethostbyaddr(capdns, (char *)&addr, 4,
306  AF_INET);
307  } else
308 #endif
309  hp = gethostbyaddr((char *)&addr, 4, AF_INET);
310  if (hp) {
311  char *dotp;
312 
313  p->name = strdup(hp->h_name);
314  if (p->name == NULL)
315  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
316  "%s: strdup(hp->h_name)", __func__);
317  if (ndo->ndo_Nflag) {
318  /* Remove domain qualifications */
319  dotp = strchr(p->name, '.');
320  if (dotp)
321  *dotp = '\0';
322  }
323  return (p->name);
324  }
325  }
326  p->name = strdup(intoa(addr));
327  if (p->name == NULL)
328  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
329  "%s: strdup(intoa(addr))", __func__);
330  return (p->name);
331 }
332 
333 /*
334  * Return a name for the IP6 address pointed to by ap. This address
335  * is assumed to be in network byte order.
336  */
337 const char *
338 ip6addr_string(netdissect_options *ndo, const u_char *ap)
339 {
340  struct hostent *hp;
341  union {
342  nd_ipv6 addr;
343  struct for_hash_addr {
344  char fill[14];
345  uint16_t d;
346  } addra;
347  } addr;
348  struct h6namemem *p;
349  const char *cp;
350  char ntop_buf[INET6_ADDRSTRLEN];
351 
352  memcpy(&addr, ap, sizeof(addr));
353  p = &h6nametable[addr.addra.d & (HASHNAMESIZE-1)];
354  for (; p->nxt; p = p->nxt) {
355  if (memcmp(&p->addr, &addr, sizeof(addr)) == 0)
356  return (p->name);
357  }
358  memcpy(p->addr, addr.addr, sizeof(nd_ipv6));
359  p->nxt = newh6namemem(ndo);
360 
361  /*
362  * Do not print names if -n was given.
363  */
364  if (!ndo->ndo_nflag) {
365 #ifdef HAVE_CASPER
366  if (capdns != NULL) {
367  hp = cap_gethostbyaddr(capdns, (char *)&addr,
368  sizeof(addr), AF_INET6);
369  } else
370 #endif
371  hp = gethostbyaddr((char *)&addr, sizeof(addr),
372  AF_INET6);
373  if (hp) {
374  char *dotp;
375 
376  p->name = strdup(hp->h_name);
377  if (p->name == NULL)
378  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
379  "%s: strdup(hp->h_name)", __func__);
380  if (ndo->ndo_Nflag) {
381  /* Remove domain qualifications */
382  dotp = strchr(p->name, '.');
383  if (dotp)
384  *dotp = '\0';
385  }
386  return (p->name);
387  }
388  }
389  cp = addrtostr6(ap, ntop_buf, sizeof(ntop_buf));
390  p->name = strdup(cp);
391  if (p->name == NULL)
392  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
393  "%s: strdup(cp)", __func__);
394  return (p->name);
395 }
396 
397 static const char hex[16] = {
398  '0', '1', '2', '3', '4', '5', '6', '7',
399  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
400 };
401 
402 /*
403  * Convert an octet to two hex digits.
404  *
405  * Coverity appears either:
406  *
407  * not to believe the C standard when it asserts that a uint8_t is
408  * exactly 8 bits in size;
409  *
410  * not to believe that an unsigned type of exactly 8 bits has a value
411  * in the range of 0 to 255;
412  *
413  * not to believe that, for a range of unsigned values, if you shift
414  * one of those values right by 4 bits, the maximum result value is
415  * the maximum value shifted right by 4 bits, with no stray 1's shifted
416  * in;
417  *
418  * not to believe that 255 >> 4 is 15;
419  *
420  * so it gets upset that we're taking a "tainted" unsigned value, shifting
421  * it right 4 bits, and using it as an index into a 16-element array.
422  *
423  * So we do a stupid pointless masking of the result of the shift with
424  * 0xf, to hammer the point home to Coverity.
425  */
426 static inline char *
427 octet_to_hex(char *cp, uint8_t octet)
428 {
429  *cp++ = hex[(octet >> 4) & 0xf];
430  *cp++ = hex[(octet >> 0) & 0xf];
431  return (cp);
432 }
433 
434 /* Find the hash node that corresponds the ether address 'ep' */
435 
436 static struct enamemem *
437 lookup_emem(netdissect_options *ndo, const u_char *ep)
438 {
439  u_int i, j, k;
440  struct enamemem *tp;
441 
442  k = (ep[0] << 8) | ep[1];
443  j = (ep[2] << 8) | ep[3];
444  i = (ep[4] << 8) | ep[5];
445 
446  tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
447  while (tp->e_nxt)
448  if (tp->e_addr0 == i &&
449  tp->e_addr1 == j &&
450  tp->e_addr2 == k)
451  return tp;
452  else
453  tp = tp->e_nxt;
454  tp->e_addr0 = (u_short)i;
455  tp->e_addr1 = (u_short)j;
456  tp->e_addr2 = (u_short)k;
457  tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
458  if (tp->e_nxt == NULL)
459  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__);
460 
461  return tp;
462 }
463 
464 /*
465  * Find the hash node that corresponds to the bytestring 'bs'
466  * with length 'nlen'
467  */
468 
469 static struct bsnamemem *
470 lookup_bytestring(netdissect_options *ndo, const u_char *bs,
471  const unsigned int nlen)
472 {
473  struct bsnamemem *tp;
474  u_int i, j, k;
475 
476  if (nlen >= 6) {
477  k = (bs[0] << 8) | bs[1];
478  j = (bs[2] << 8) | bs[3];
479  i = (bs[4] << 8) | bs[5];
480  } else if (nlen >= 4) {
481  k = (bs[0] << 8) | bs[1];
482  j = (bs[2] << 8) | bs[3];
483  i = 0;
484  } else
485  i = j = k = 0;
486 
487  tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)];
488  while (tp->bs_nxt)
489  if (nlen == tp->bs_nbytes &&
490  tp->bs_addr0 == i &&
491  tp->bs_addr1 == j &&
492  tp->bs_addr2 == k &&
493  memcmp((const char *)bs, (const char *)(tp->bs_bytes), nlen) == 0)
494  return tp;
495  else
496  tp = tp->bs_nxt;
497 
498  tp->bs_addr0 = (u_short)i;
499  tp->bs_addr1 = (u_short)j;
500  tp->bs_addr2 = (u_short)k;
501 
502  tp->bs_bytes = (u_char *) calloc(1, nlen);
503  if (tp->bs_bytes == NULL)
504  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
505  "%s: calloc", __func__);
506 
507  memcpy(tp->bs_bytes, bs, nlen);
508  tp->bs_nbytes = nlen;
509  tp->bs_nxt = (struct bsnamemem *)calloc(1, sizeof(*tp));
510  if (tp->bs_nxt == NULL)
511  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
512  "%s: calloc", __func__);
513 
514  return tp;
515 }
516 
517 /* Find the hash node that corresponds the NSAP 'nsap' */
518 
519 static struct enamemem *
520 lookup_nsap(netdissect_options *ndo, const u_char *nsap,
521  u_int nsap_length)
522 {
523  u_int i, j, k;
524  struct enamemem *tp;
525  const u_char *ensap;
526 
527  if (nsap_length > 6) {
528  ensap = nsap + nsap_length - 6;
529  k = (ensap[0] << 8) | ensap[1];
530  j = (ensap[2] << 8) | ensap[3];
531  i = (ensap[4] << 8) | ensap[5];
532  }
533  else
534  i = j = k = 0;
535 
536  tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
537  while (tp->e_nxt)
538  if (nsap_length == tp->e_nsap[0] &&
539  tp->e_addr0 == i &&
540  tp->e_addr1 == j &&
541  tp->e_addr2 == k &&
542  memcmp((const char *)nsap,
543  (char *)&(tp->e_nsap[1]), nsap_length) == 0)
544  return tp;
545  else
546  tp = tp->e_nxt;
547  tp->e_addr0 = (u_short)i;
548  tp->e_addr1 = (u_short)j;
549  tp->e_addr2 = (u_short)k;
550  tp->e_nsap = (u_char *)malloc(nsap_length + 1);
551  if (tp->e_nsap == NULL)
552  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: malloc", __func__);
553  tp->e_nsap[0] = (u_char)nsap_length; /* guaranteed < ISONSAP_MAX_LENGTH */
554  memcpy((char *)&tp->e_nsap[1], (const char *)nsap, nsap_length);
555  tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
556  if (tp->e_nxt == NULL)
557  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__);
558 
559  return tp;
560 }
561 
562 /* Find the hash node that corresponds the protoid 'pi'. */
563 
564 static struct protoidmem *
565 lookup_protoid(netdissect_options *ndo, const u_char *pi)
566 {
567  u_int i, j;
568  struct protoidmem *tp;
569 
570  /* 5 octets won't be aligned */
571  i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
572  j = (pi[3] << 8) + pi[4];
573  /* XXX should be endian-insensitive, but do big-endian testing XXX */
574 
575  tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
576  while (tp->p_nxt)
577  if (tp->p_oui == i && tp->p_proto == j)
578  return tp;
579  else
580  tp = tp->p_nxt;
581  tp->p_oui = i;
582  tp->p_proto = (u_short)j;
583  tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
584  if (tp->p_nxt == NULL)
585  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__);
586 
587  return tp;
588 }
589 
590 const char *
591 etheraddr_string(netdissect_options *ndo, const uint8_t *ep)
592 {
593  int i;
594  char *cp;
595  struct enamemem *tp;
596  int oui;
597  char buf[BUFSIZE];
598 
599  tp = lookup_emem(ndo, ep);
600  if (tp->e_name)
601  return (tp->e_name);
602 #ifdef USE_ETHER_NTOHOST
603  if (!ndo->ndo_nflag) {
604  char buf2[BUFSIZE];
605  /*
606  * This is a non-const copy of ep for ether_ntohost(), which
607  * has its second argument non-const in OpenBSD. Also saves a
608  * type cast.
609  */
610  struct ether_addr ea;
611 
612  memcpy (&ea, ep, MAC_ADDR_LEN);
613  if (ether_ntohost(buf2, &ea) == 0) {
614  tp->e_name = strdup(buf2);
615  if (tp->e_name == NULL)
616  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
617  "%s: strdup(buf2)", __func__);
618  return (tp->e_name);
619  }
620  }
621 #endif
622  cp = buf;
623  oui = EXTRACT_BE_U_3(ep);
624  cp = octet_to_hex(cp, *ep++);
625  for (i = 5; --i >= 0;) {
626  *cp++ = ':';
627  cp = octet_to_hex(cp, *ep++);
628  }
629 
630  if (!ndo->ndo_nflag) {
631  snprintf(cp, BUFSIZE - (2 + 5*3), " (oui %s)",
632  tok2str(oui_values, "Unknown", oui));
633  } else
634  *cp = '\0';
635  tp->e_name = strdup(buf);
636  if (tp->e_name == NULL)
637  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
638  "%s: strdup(buf)", __func__);
639  return (tp->e_name);
640 }
641 
642 const char *
643 le64addr_string(netdissect_options *ndo, const uint8_t *ep)
644 {
645  const unsigned int len = 8;
646  u_int i;
647  char *cp;
648  struct bsnamemem *tp;
649  char buf[BUFSIZE];
650 
651  tp = lookup_bytestring(ndo, ep, len);
652  if (tp->bs_name)
653  return (tp->bs_name);
654 
655  cp = buf;
656  for (i = len; i > 0 ; --i) {
657  cp = octet_to_hex(cp, *(ep + i - 1));
658  *cp++ = ':';
659  }
660  cp --;
661 
662  *cp = '\0';
663 
664  tp->bs_name = strdup(buf);
665  if (tp->bs_name == NULL)
666  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
667  "%s: strdup(buf)", __func__);
668 
669  return (tp->bs_name);
670 }
671 
672 const char *
673 linkaddr_string(netdissect_options *ndo, const uint8_t *ep,
674  const unsigned int type, const unsigned int len)
675 {
676  u_int i;
677  char *cp;
678  struct bsnamemem *tp;
679 
680  if (len == 0)
681  return ("<empty>");
682 
683  if (type == LINKADDR_ETHER && len == MAC_ADDR_LEN)
684  return (etheraddr_string(ndo, ep));
685 
686  if (type == LINKADDR_FRELAY)
687  return (q922_string(ndo, ep, len));
688 
689  tp = lookup_bytestring(ndo, ep, len);
690  if (tp->bs_name)
691  return (tp->bs_name);
692 
693  tp->bs_name = cp = (char *)malloc(len*3);
694  if (tp->bs_name == NULL)
695  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
696  "%s: malloc", __func__);
697  cp = octet_to_hex(cp, *ep++);
698  for (i = len-1; i > 0 ; --i) {
699  *cp++ = ':';
700  cp = octet_to_hex(cp, *ep++);
701  }
702  *cp = '\0';
703  return (tp->bs_name);
704 }
705 
706 #define ISONSAP_MAX_LENGTH 20
707 const char *
708 isonsap_string(netdissect_options *ndo, const uint8_t *nsap,
709  u_int nsap_length)
710 {
711  u_int nsap_idx;
712  char *cp;
713  struct enamemem *tp;
714 
715  if (nsap_length < 1 || nsap_length > ISONSAP_MAX_LENGTH)
716  return ("isonsap_string: illegal length");
717 
718  tp = lookup_nsap(ndo, nsap, nsap_length);
719  if (tp->e_name)
720  return tp->e_name;
721 
722  tp->e_name = cp = (char *)malloc(sizeof("xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx"));
723  if (cp == NULL)
724  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
725  "%s: malloc", __func__);
726 
727  for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) {
728  cp = octet_to_hex(cp, *nsap++);
729  if (((nsap_idx & 1) == 0) &&
730  (nsap_idx + 1 < nsap_length)) {
731  *cp++ = '.';
732  }
733  }
734  *cp = '\0';
735  return (tp->e_name);
736 }
737 
738 const char *
740 {
741  struct hnamemem *tp;
742  uint32_t i = port;
743  char buf[sizeof("00000")];
744 
745  for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
746  if (tp->addr == i)
747  return (tp->name);
748 
749  tp->addr = i;
750  tp->nxt = newhnamemem(ndo);
751 
752  (void)snprintf(buf, sizeof(buf), "%u", i);
753  tp->name = strdup(buf);
754  if (tp->name == NULL)
755  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
756  "%s: strdup(buf)", __func__);
757  return (tp->name);
758 }
759 
760 const char *
762 {
763  struct hnamemem *tp;
764  uint32_t i = port;
765  char buf[sizeof("00000")];
766 
767  for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
768  if (tp->addr == i)
769  return (tp->name);
770 
771  tp->addr = i;
772  tp->nxt = newhnamemem(ndo);
773 
774  (void)snprintf(buf, sizeof(buf), "%u", i);
775  tp->name = strdup(buf);
776  if (tp->name == NULL)
777  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
778  "%s: strdup(buf)", __func__);
779  return (tp->name);
780 }
781 
782 const char *
784 {
785  char *cp;
786  struct hnamemem *tp;
787  uint32_t i = port;
788  char buf[sizeof("0000")];
789 
790  for (tp = &ipxsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
791  if (tp->addr == i)
792  return (tp->name);
793 
794  tp->addr = i;
795  tp->nxt = newhnamemem(ndo);
796 
797  cp = buf;
798  port = ntohs(port);
799  *cp++ = hex[port >> 12 & 0xf];
800  *cp++ = hex[port >> 8 & 0xf];
801  *cp++ = hex[port >> 4 & 0xf];
802  *cp++ = hex[port & 0xf];
803  *cp++ = '\0';
804  tp->name = strdup(buf);
805  if (tp->name == NULL)
806  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
807  "%s: strdup(buf)", __func__);
808  return (tp->name);
809 }
810 
811 static void
813 {
814  struct servent *sv;
815  struct hnamemem *table;
816  int i;
817  char buf[sizeof("0000000000")];
818 
819  while ((sv = getservent()) != NULL) {
820  int port = ntohs(sv->s_port);
821  i = port & (HASHNAMESIZE-1);
822  if (strcmp(sv->s_proto, "tcp") == 0)
823  table = &tporttable[i];
824  else if (strcmp(sv->s_proto, "udp") == 0)
825  table = &uporttable[i];
826  else
827  continue;
828 
829  while (table->name)
830  table = table->nxt;
831  if (ndo->ndo_nflag) {
832  (void)snprintf(buf, sizeof(buf), "%d", port);
833  table->name = strdup(buf);
834  } else
835  table->name = strdup(sv->s_name);
836  if (table->name == NULL)
837  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
838  "%s: strdup", __func__);
839 
840  table->addr = port;
841  table->nxt = newhnamemem(ndo);
842  }
843  endservent();
844 }
845 
846 static const struct eproto {
847  const char *s;
848  u_short p;
849 } eproto_db[] = {
850  { "aarp", ETHERTYPE_AARP },
851  { "arp", ETHERTYPE_ARP },
852  { "atalk", ETHERTYPE_ATALK },
853  { "decnet", ETHERTYPE_DN },
854  { "ip", ETHERTYPE_IP },
855  { "ip6", ETHERTYPE_IPV6 },
856  { "lat", ETHERTYPE_LAT },
857  { "loopback", ETHERTYPE_LOOPBACK },
858  { "mopdl", ETHERTYPE_MOPDL },
859  { "moprc", ETHERTYPE_MOPRC },
860  { "rarp", ETHERTYPE_REVARP },
861  { "sca", ETHERTYPE_SCA },
862  { (char *)0, 0 }
863 };
864 
865 static void
867 {
868  int i;
869  struct hnamemem *table;
870 
871  for (i = 0; eproto_db[i].s; i++) {
872  int j = htons(eproto_db[i].p) & (HASHNAMESIZE-1);
873  table = &eprototable[j];
874  while (table->name)
875  table = table->nxt;
876  table->name = eproto_db[i].s;
877  table->addr = htons(eproto_db[i].p);
878  table->nxt = newhnamemem(ndo);
879  }
880 }
881 
882 static const struct protoidlist {
883  const u_char protoid[5];
884  const char *name;
885 } protoidlist[] = {
886  {{ 0x00, 0x00, 0x0c, 0x01, 0x07 }, "CiscoMLS" },
887  {{ 0x00, 0x00, 0x0c, 0x20, 0x00 }, "CiscoCDP" },
888  {{ 0x00, 0x00, 0x0c, 0x20, 0x01 }, "CiscoCGMP" },
889  {{ 0x00, 0x00, 0x0c, 0x20, 0x03 }, "CiscoVTP" },
890  {{ 0x00, 0xe0, 0x2b, 0x00, 0xbb }, "ExtremeEDP" },
891  {{ 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
892 };
893 
894 /*
895  * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
896  * types.
897  */
898 static void
900 {
901  int i;
902  struct protoidmem *tp;
903  const struct protoidlist *pl;
904  u_char protoid[5];
905 
906  protoid[0] = 0;
907  protoid[1] = 0;
908  protoid[2] = 0;
909  for (i = 0; eproto_db[i].s; i++) {
910  u_short etype = htons(eproto_db[i].p);
911 
912  memcpy((char *)&protoid[3], (char *)&etype, 2);
913  tp = lookup_protoid(ndo, protoid);
914  tp->p_name = strdup(eproto_db[i].s);
915  if (tp->p_name == NULL)
916  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
917  "%s: strdup(eproto_db[i].s)", __func__);
918  }
919  /* Hardwire some SNAP proto ID names */
920  for (pl = protoidlist; pl->name != NULL; ++pl) {
921  tp = lookup_protoid(ndo, pl->protoid);
922  /* Don't override existing name */
923  if (tp->p_name != NULL)
924  continue;
925 
926  tp->p_name = pl->name;
927  }
928 }
929 
930 static const struct etherlist {
932  const char *name;
933 } etherlist[] = {
934  {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
935  {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
936 };
937 
938 /*
939  * Initialize the ethers hash table. We take two different approaches
940  * depending on whether or not the system provides the ethers name
941  * service. If it does, we just wire in a few names at startup,
942  * and etheraddr_string() fills in the table on demand. If it doesn't,
943  * then we suck in the entire /etc/ethers file at startup. The idea
944  * is that parsing the local file will be fast, but spinning through
945  * all the ethers entries via NIS & next_etherent might be very slow.
946  *
947  * XXX pcap_next_etherent doesn't belong in the pcap interface, but
948  * since the pcap module already does name-to-address translation,
949  * it's already does most of the work for the ethernet address-to-name
950  * translation, so we just pcap_next_etherent as a convenience.
951  */
952 static void
954 {
955  const struct etherlist *el;
956  struct enamemem *tp;
957 #ifdef USE_ETHER_NTOHOST
958  char name[256];
959 #else
960  struct pcap_etherent *ep;
961  FILE *fp;
962 
963  /* Suck in entire ethers file */
964  fp = fopen(PCAP_ETHERS_FILE, "r");
965  if (fp != NULL) {
966  while ((ep = pcap_next_etherent(fp)) != NULL) {
967  tp = lookup_emem(ndo, ep->addr);
968  tp->e_name = strdup(ep->name);
969  if (tp->e_name == NULL)
970  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
971  "%s: strdup(ep->addr)", __func__);
972  }
973  (void)fclose(fp);
974  }
975 #endif
976 
977  /* Hardwire some ethernet names */
978  for (el = etherlist; el->name != NULL; ++el) {
979  tp = lookup_emem(ndo, el->addr);
980  /* Don't override existing name */
981  if (tp->e_name != NULL)
982  continue;
983 
984 #ifdef USE_ETHER_NTOHOST
985  /*
986  * Use YP/NIS version of name if available.
987  */
988  /* Same workaround as in etheraddr_string(). */
989  struct ether_addr ea;
990  memcpy (&ea, el->addr, MAC_ADDR_LEN);
991  if (ether_ntohost(name, &ea) == 0) {
992  tp->e_name = strdup(name);
993  if (tp->e_name == NULL)
994  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
995  "%s: strdup(name)", __func__);
996  continue;
997  }
998 #endif
999  tp->e_name = el->name;
1000  }
1001 }
1002 
1003 static const struct ipxsap_ent {
1004  uint16_t v;
1005  const char *s;
1006 } ipxsap_db[] = {
1007  { 0x0000, "Unknown" },
1008  { 0x0001, "User" },
1009  { 0x0002, "User Group" },
1010  { 0x0003, "PrintQueue" },
1011  { 0x0004, "FileServer" },
1012  { 0x0005, "JobServer" },
1013  { 0x0006, "Gateway" },
1014  { 0x0007, "PrintServer" },
1015  { 0x0008, "ArchiveQueue" },
1016  { 0x0009, "ArchiveServer" },
1017  { 0x000a, "JobQueue" },
1018  { 0x000b, "Administration" },
1019  { 0x000F, "Novell TI-RPC" },
1020  { 0x0017, "Diagnostics" },
1021  { 0x0020, "NetBIOS" },
1022  { 0x0021, "NAS SNA Gateway" },
1023  { 0x0023, "NACS AsyncGateway" },
1024  { 0x0024, "RemoteBridge/RoutingService" },
1025  { 0x0026, "BridgeServer" },
1026  { 0x0027, "TCP/IP Gateway" },
1027  { 0x0028, "Point-to-point X.25 BridgeServer" },
1028  { 0x0029, "3270 Gateway" },
1029  { 0x002a, "CHI Corp" },
1030  { 0x002c, "PC Chalkboard" },
1031  { 0x002d, "TimeSynchServer" },
1032  { 0x002e, "ARCserve5.0/PalindromeBackup" },
1033  { 0x0045, "DI3270 Gateway" },
1034  { 0x0047, "AdvertisingPrintServer" },
1035  { 0x004a, "NetBlazerModems" },
1036  { 0x004b, "BtrieveVAP" },
1037  { 0x004c, "NetwareSQL" },
1038  { 0x004d, "XtreeNetwork" },
1039  { 0x0050, "BtrieveVAP4.11" },
1040  { 0x0052, "QuickLink" },
1041  { 0x0053, "PrintQueueUser" },
1042  { 0x0058, "Multipoint X.25 Router" },
1043  { 0x0060, "STLB/NLM" },
1044  { 0x0064, "ARCserve" },
1045  { 0x0066, "ARCserve3.0" },
1046  { 0x0072, "WAN CopyUtility" },
1047  { 0x007a, "TES-NetwareVMS" },
1048  { 0x0092, "WATCOM Debugger/EmeraldTapeBackupServer" },
1049  { 0x0095, "DDA OBGYN" },
1050  { 0x0098, "NetwareAccessServer" },
1051  { 0x009a, "Netware for VMS II/NamedPipeServer" },
1052  { 0x009b, "NetwareAccessServer" },
1053  { 0x009e, "PortableNetwareServer/SunLinkNVT" },
1054  { 0x00a1, "PowerchuteAPC UPS" },
1055  { 0x00aa, "LAWserve" },
1056  { 0x00ac, "CompaqIDA StatusMonitor" },
1057  { 0x0100, "PIPE STAIL" },
1058  { 0x0102, "LAN ProtectBindery" },
1059  { 0x0103, "OracleDataBaseServer" },
1060  { 0x0107, "Netware386/RSPX RemoteConsole" },
1061  { 0x010f, "NovellSNA Gateway" },
1062  { 0x0111, "TestServer" },
1063  { 0x0112, "HP PrintServer" },
1064  { 0x0114, "CSA MUX" },
1065  { 0x0115, "CSA LCA" },
1066  { 0x0116, "CSA CM" },
1067  { 0x0117, "CSA SMA" },
1068  { 0x0118, "CSA DBA" },
1069  { 0x0119, "CSA NMA" },
1070  { 0x011a, "CSA SSA" },
1071  { 0x011b, "CSA STATUS" },
1072  { 0x011e, "CSA APPC" },
1073  { 0x0126, "SNA TEST SSA Profile" },
1074  { 0x012a, "CSA TRACE" },
1075  { 0x012b, "NetwareSAA" },
1076  { 0x012e, "IKARUS VirusScan" },
1077  { 0x0130, "CommunicationsExecutive" },
1078  { 0x0133, "NNS DomainServer/NetwareNamingServicesDomain" },
1079  { 0x0135, "NetwareNamingServicesProfile" },
1080  { 0x0137, "Netware386 PrintQueue/NNS PrintQueue" },
1081  { 0x0141, "LAN SpoolServer" },
1082  { 0x0152, "IRMALAN Gateway" },
1083  { 0x0154, "NamedPipeServer" },
1084  { 0x0166, "NetWareManagement" },
1085  { 0x0168, "Intel PICKIT CommServer/Intel CAS TalkServer" },
1086  { 0x0173, "Compaq" },
1087  { 0x0174, "Compaq SNMP Agent" },
1088  { 0x0175, "Compaq" },
1089  { 0x0180, "XTreeServer/XTreeTools" },
1090  { 0x018A, "NASI ServicesBroadcastServer" },
1091  { 0x01b0, "GARP Gateway" },
1092  { 0x01b1, "Binfview" },
1093  { 0x01bf, "IntelLanDeskManager" },
1094  { 0x01ca, "AXTEC" },
1095  { 0x01cb, "ShivaNetModem/E" },
1096  { 0x01cc, "ShivaLanRover/E" },
1097  { 0x01cd, "ShivaLanRover/T" },
1098  { 0x01ce, "ShivaUniversal" },
1099  { 0x01d8, "CastelleFAXPressServer" },
1100  { 0x01da, "CastelleLANPressPrintServer" },
1101  { 0x01dc, "CastelleFAX/Xerox7033 FaxServer/ExcelLanFax" },
1102  { 0x01f0, "LEGATO" },
1103  { 0x01f5, "LEGATO" },
1104  { 0x0233, "NMS Agent/NetwareManagementAgent" },
1105  { 0x0237, "NMS IPX Discovery/LANternReadWriteChannel" },
1106  { 0x0238, "NMS IP Discovery/LANternTrapAlarmChannel" },
1107  { 0x023a, "LANtern" },
1108  { 0x023c, "MAVERICK" },
1109  { 0x023f, "NovellSMDR" },
1110  { 0x024e, "NetwareConnect" },
1111  { 0x024f, "NASI ServerBroadcast Cisco" },
1112  { 0x026a, "NMS ServiceConsole" },
1113  { 0x026b, "TimeSynchronizationServer Netware 4.x" },
1114  { 0x0278, "DirectoryServer Netware 4.x" },
1115  { 0x027b, "NetwareManagementAgent" },
1116  { 0x0280, "Novell File and Printer Sharing Service for PC" },
1117  { 0x0304, "NovellSAA Gateway" },
1118  { 0x0308, "COM/VERMED" },
1119  { 0x030a, "GalacticommWorldgroupServer" },
1120  { 0x030c, "IntelNetport2/HP JetDirect/HP Quicksilver" },
1121  { 0x0320, "AttachmateGateway" },
1122  { 0x0327, "MicrosoftDiagnostiocs" },
1123  { 0x0328, "WATCOM SQL Server" },
1124  { 0x0335, "MultiTechSystems MultisynchCommServer" },
1125  { 0x0343, "Xylogics RemoteAccessServer/LANModem" },
1126  { 0x0355, "ArcadaBackupExec" },
1127  { 0x0358, "MSLCD1" },
1128  { 0x0361, "NETINELO" },
1129  { 0x037e, "Powerchute UPS Monitoring" },
1130  { 0x037f, "ViruSafeNotify" },
1131  { 0x0386, "HP Bridge" },
1132  { 0x0387, "HP Hub" },
1133  { 0x0394, "NetWare SAA Gateway" },
1134  { 0x039b, "LotusNotes" },
1135  { 0x03b7, "CertusAntiVirus" },
1136  { 0x03c4, "ARCserve4.0" },
1137  { 0x03c7, "LANspool3.5" },
1138  { 0x03d7, "LexmarkPrinterServer" },
1139  { 0x03d8, "LexmarkXLE PrinterServer" },
1140  { 0x03dd, "BanyanENS NetwareClient" },
1141  { 0x03de, "GuptaSequelBaseServer/NetWareSQL" },
1142  { 0x03e1, "UnivelUnixware" },
1143  { 0x03e4, "UnivelUnixware" },
1144  { 0x03fc, "IntelNetport" },
1145  { 0x03fd, "PrintServerQueue" },
1146  { 0x040A, "ipnServer" },
1147  { 0x040D, "LVERRMAN" },
1148  { 0x040E, "LVLIC" },
1149  { 0x0414, "NET Silicon (DPI)/Kyocera" },
1150  { 0x0429, "SiteLockVirus" },
1151  { 0x0432, "UFHELPR???" },
1152  { 0x0433, "Synoptics281xAdvancedSNMPAgent" },
1153  { 0x0444, "MicrosoftNT SNA Server" },
1154  { 0x0448, "Oracle" },
1155  { 0x044c, "ARCserve5.01" },
1156  { 0x0457, "CanonGP55" },
1157  { 0x045a, "QMS Printers" },
1158  { 0x045b, "DellSCSI Array" },
1159  { 0x0491, "NetBlazerModems" },
1160  { 0x04ac, "OnTimeScheduler" },
1161  { 0x04b0, "CD-Net" },
1162  { 0x0513, "EmulexNQA" },
1163  { 0x0520, "SiteLockChecks" },
1164  { 0x0529, "SiteLockChecks" },
1165  { 0x052d, "CitrixOS2 AppServer" },
1166  { 0x0535, "Tektronix" },
1167  { 0x0536, "Milan" },
1168  { 0x055d, "Attachmate SNA gateway" },
1169  { 0x056b, "IBM8235 ModemServer" },
1170  { 0x056c, "ShivaLanRover/E PLUS" },
1171  { 0x056d, "ShivaLanRover/T PLUS" },
1172  { 0x0580, "McAfeeNetShield" },
1173  { 0x05B8, "NLM to workstation communication (Revelation Software)" },
1174  { 0x05BA, "CompatibleSystemsRouters" },
1175  { 0x05BE, "CheyenneHierarchicalStorageManager" },
1176  { 0x0606, "JCWatermarkImaging" },
1177  { 0x060c, "AXISNetworkPrinter" },
1178  { 0x0610, "AdaptecSCSIManagement" },
1179  { 0x0621, "IBM AntiVirus" },
1180  { 0x0640, "Windows95 RemoteRegistryService" },
1181  { 0x064e, "MicrosoftIIS" },
1182  { 0x067b, "Microsoft Win95/98 File and Print Sharing for NetWare" },
1183  { 0x067c, "Microsoft Win95/98 File and Print Sharing for NetWare" },
1184  { 0x076C, "Xerox" },
1185  { 0x079b, "ShivaLanRover/E 115" },
1186  { 0x079c, "ShivaLanRover/T 115" },
1187  { 0x07B4, "CubixWorldDesk" },
1188  { 0x07c2, "Quarterdeck IWare Connect V2.x NLM" },
1189  { 0x07c1, "Quarterdeck IWare Connect V3.x NLM" },
1190  { 0x0810, "ELAN License Server Demo" },
1191  { 0x0824, "ShivaLanRoverAccessSwitch/E" },
1192  { 0x086a, "ISSC Collector" },
1193  { 0x087f, "ISSC DAS AgentAIX" },
1194  { 0x0880, "Intel Netport PRO" },
1195  { 0x0881, "Intel Netport PRO" },
1196  { 0x0b29, "SiteLock" },
1197  { 0x0c29, "SiteLockApplications" },
1198  { 0x0c2c, "LicensingServer" },
1199  { 0x2101, "PerformanceTechnologyInstantInternet" },
1200  { 0x2380, "LAI SiteLock" },
1201  { 0x238c, "MeetingMaker" },
1202  { 0x4808, "SiteLockServer/SiteLockMetering" },
1203  { 0x5555, "SiteLockUser" },
1204  { 0x6312, "Tapeware" },
1205  { 0x6f00, "RabbitGateway" },
1206  { 0x7703, "MODEM" },
1207  { 0x8002, "NetPortPrinters" },
1208  { 0x8008, "WordPerfectNetworkVersion" },
1209  { 0x85BE, "Cisco EIGRP" },
1210  { 0x8888, "WordPerfectNetworkVersion/QuickNetworkManagement" },
1211  { 0x9000, "McAfeeNetShield" },
1212  { 0x9604, "CSA-NT_MON" },
1213  { 0xb6a8, "OceanIsleReachoutRemoteControl" },
1214  { 0xf11f, "SiteLockMetering" },
1215  { 0xf1ff, "SiteLock" },
1216  { 0xf503, "Microsoft SQL Server" },
1217  { 0xF905, "IBM TimeAndPlace" },
1218  { 0xfbfb, "TopCallIII FaxServer" },
1219  { 0xffff, "AnyService/Wildcard" },
1220  { 0, (char *)0 }
1221 };
1222 
1223 static void
1225 {
1226  int i;
1227  struct hnamemem *table;
1228 
1229  for (i = 0; ipxsap_db[i].s != NULL; i++) {
1230  u_int j = htons(ipxsap_db[i].v) & (HASHNAMESIZE-1);
1231  table = &ipxsaptable[j];
1232  while (table->name)
1233  table = table->nxt;
1234  table->name = ipxsap_db[i].s;
1235  table->addr = htons(ipxsap_db[i].v);
1236  table->nxt = newhnamemem(ndo);
1237  }
1238 }
1239 
1240 /*
1241  * Initialize the address to name translation machinery. We map all
1242  * non-local IP addresses to numeric addresses if ndo->ndo_fflag is true
1243  * (i.e., to prevent blocking on the nameserver). localnet is the IP address
1244  * of the local network. mask is its subnet mask.
1245  */
1246 void
1247 init_addrtoname(netdissect_options *ndo, uint32_t localnet, uint32_t mask)
1248 {
1249  if (ndo->ndo_fflag) {
1250  f_localnet = localnet;
1251  f_netmask = mask;
1252  }
1253  if (ndo->ndo_nflag)
1254  /*
1255  * Simplest way to suppress names.
1256  */
1257  return;
1258 
1259  init_etherarray(ndo);
1260  init_servarray(ndo);
1261  init_eprotoarray(ndo);
1262  init_protoidarray(ndo);
1263  init_ipxsaparray(ndo);
1264 }
1265 
1266 const char *
1267 dnaddr_string(netdissect_options *ndo, u_short dnaddr)
1268 {
1269  struct hnamemem *tp;
1270 
1271  for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != NULL;
1272  tp = tp->nxt)
1273  if (tp->addr == dnaddr)
1274  return (tp->name);
1275 
1276  tp->addr = dnaddr;
1277  tp->nxt = newhnamemem(ndo);
1278  tp->name = dnnum_string(ndo, dnaddr);
1279 
1280  return(tp->name);
1281 }
1282 
1283 /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
1284 struct hnamemem *
1286 {
1287  struct hnamemem *p;
1288  static struct hnamemem *ptr = NULL;
1289  static u_int num = 0;
1290 
1291  if (num <= 0) {
1292  num = 64;
1293  ptr = (struct hnamemem *)calloc(num, sizeof (*ptr));
1294  if (ptr == NULL)
1295  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
1296  "%s: calloc", __func__);
1297  }
1298  --num;
1299  p = ptr++;
1300  return (p);
1301 }
1302 
1303 /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */
1304 struct h6namemem *
1306 {
1307  struct h6namemem *p;
1308  static struct h6namemem *ptr = NULL;
1309  static u_int num = 0;
1310 
1311  if (num <= 0) {
1312  num = 64;
1313  ptr = (struct h6namemem *)calloc(num, sizeof (*ptr));
1314  if (ptr == NULL)
1315  (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
1316  "%s: calloc", __func__);
1317  }
1318  --num;
1319  p = ptr++;
1320  return (p);
1321 }
1322 
1323 /* Represent TCI part of the 802.1Q 4-octet tag as text. */
1324 const char *
1325 ieee8021q_tci_string(const uint16_t tci)
1326 {
1327  static char buf[128];
1328  snprintf(buf, sizeof(buf), "vlan %u, p %u%s",
1329  tci & 0xfff,
1330  tci >> 13,
1331  (tci & 0x1000) ? ", DEI" : "");
1332  return buf;
1333 }
const char * dnaddr_string(netdissect_options *ndo, u_short dnaddr)
Definition: addrtoname.c:1267
const char * tcpport_string(netdissect_options *ndo, u_short port)
Definition: addrtoname.c:739
static struct protoidmem protoidtable[4096]
Definition: addrtoname.c:219
const char * intoa(uint32_t addr)
Definition: addrtoname.c:225
const char * linkaddr_string(netdissect_options *ndo, const uint8_t *ep, const unsigned int type, const unsigned int len)
Definition: addrtoname.c:673
struct hnamemem * newhnamemem(netdissect_options *ndo)
Definition: addrtoname.c:1285
static struct hnamemem uporttable[4096]
Definition: addrtoname.c:135
const char * ipaddr_string(netdissect_options *ndo, const u_char *ap)
Definition: addrtoname.c:279
static struct hnamemem ipxsaptable[4096]
Definition: addrtoname.c:138
struct h6namemem * newh6namemem(netdissect_options *ndo)
Definition: addrtoname.c:1305
const char * isonsap_string(netdissect_options *ndo, const uint8_t *nsap, u_int nsap_length)
Definition: addrtoname.c:708
const char * ipxsap_string(netdissect_options *ndo, u_short port)
Definition: addrtoname.c:783
static void init_servarray(netdissect_options *ndo)
Definition: addrtoname.c:812
static uint32_t f_localnet
Definition: addrtoname.c:255
static struct enamemem * lookup_emem(netdissect_options *ndo, const u_char *ep)
Definition: addrtoname.c:437
static struct hnamemem eprototable[4096]
Definition: addrtoname.c:136
static struct h6namemem h6nametable[4096]
Definition: addrtoname.c:186
const char * ip6addr_string(netdissect_options *ndo, const u_char *ap)
Definition: addrtoname.c:338
const char * udpport_string(netdissect_options *ndo, u_short port)
Definition: addrtoname.c:761
static const struct eproto eproto_db[]
const char * le64addr_string(netdissect_options *ndo, const uint8_t *ep)
Definition: addrtoname.c:643
static struct protoidmem * lookup_protoid(netdissect_options *ndo, const u_char *pi)
Definition: addrtoname.c:565
static const struct ipxsap_ent ipxsap_db[]
static struct hnamemem dnaddrtable[4096]
Definition: addrtoname.c:137
static char * octet_to_hex(char *cp, uint8_t octet)
Definition: addrtoname.c:427
#define ISONSAP_MAX_LENGTH
Definition: addrtoname.c:706
static struct enamemem enametable[4096]
Definition: addrtoname.c:197
static void init_etherarray(netdissect_options *ndo)
Definition: addrtoname.c:953
const char * etheraddr_string(netdissect_options *ndo, const uint8_t *ep)
Definition: addrtoname.c:591
static struct bsnamemem * lookup_bytestring(netdissect_options *ndo, const u_char *bs, const unsigned int nlen)
Definition: addrtoname.c:470
static struct enamemem nsaptable[4096]
Definition: addrtoname.c:198
static struct bsnamemem bytestringtable[4096]
Definition: addrtoname.c:210
static struct hnamemem hnametable[4096]
Definition: addrtoname.c:133
static void init_eprotoarray(netdissect_options *ndo)
Definition: addrtoname.c:866
static struct enamemem * lookup_nsap(netdissect_options *ndo, const u_char *nsap, u_int nsap_length)
Definition: addrtoname.c:520
#define HASHNAMESIZE
Definition: addrtoname.c:125
static void init_protoidarray(netdissect_options *ndo)
Definition: addrtoname.c:899
static uint32_t f_netmask
Definition: addrtoname.c:254
static const char hex[16]
Definition: addrtoname.c:397
static void init_ipxsaparray(netdissect_options *ndo)
Definition: addrtoname.c:1224
const char * ieee8021q_tci_string(const uint16_t tci)
Definition: addrtoname.c:1325
void init_addrtoname(netdissect_options *ndo, uint32_t localnet, uint32_t mask)
Definition: addrtoname.c:1247
static struct hnamemem tporttable[4096]
Definition: addrtoname.c:134
@ LINKADDR_FRELAY
Definition: addrtoname.h:36
@ LINKADDR_ETHER
Definition: addrtoname.h:35
#define BUFSIZE
Definition: addrtoname.h:42
#define INET6_ADDRSTRLEN
Definition: addrtoname.h:29
const char * addrtostr6(const void *src, char *dst, size_t size)
Definition: addrtostr.c:99
#define ETHERTYPE_ATALK
Definition: ethertype.h:103
#define ETHERTYPE_REVARP
Definition: ethertype.h:58
#define ETHERTYPE_ARP
Definition: ethertype.h:55
#define ETHERTYPE_DN
Definition: ethertype.h:76
#define ETHERTYPE_MOPRC
Definition: ethertype.h:73
#define ETHERTYPE_LOOPBACK
Definition: ethertype.h:189
#define ETHERTYPE_MOPDL
Definition: ethertype.h:70
#define ETHERTYPE_AARP
Definition: ethertype.h:106
#define ETHERTYPE_IPV6
Definition: ethertype.h:135
#define ETHERTYPE_LAT
Definition: ethertype.h:79
#define ETHERTYPE_IP
Definition: ethertype.h:52
#define ETHERTYPE_SCA
Definition: ethertype.h:82
#define EXTRACT_BE_U_3(p)
Definition: extract.h:388
void endservent(void)
Definition: getservent.c:86
struct servent * getservent(void)
Definition: getservent.c:96
char * strdup(const char *)
size_t strlcpy(char *, const char *, size_t)
Definition: strlcpy.c:47
#define AF_INET6
#define NI_MAXHOST
const char * dnnum_string(netdissect_options *, u_short)
const char * tok2str(const struct tok *, const char *, u_int)
Definition: util-print.c:485
unsigned char nd_mac_addr[6U]
Definition: netdissect.h:103
#define MAC_ADDR_LEN
Definition: netdissect.h:102
unsigned char nd_ipv6[16]
Definition: netdissect.h:97
const char * q922_string(netdissect_options *, const u_char *, u_int)
Definition: print-fr.c:145
int snprintf(char *, size_t, const char *,...)
const struct tok oui_values[]
Definition: oui.c:26
nd_uint8_t byte
Definition: print-decnet.c:40
const char * name
Definition: print-mptcp.c:452
@ S_ERR_ND_MEM_ALLOC
struct bsnamemem * bs_nxt
Definition: addrtoname.c:207
u_short bs_addr1
Definition: addrtoname.c:202
u_short bs_addr0
Definition: addrtoname.c:201
const char * bs_name
Definition: addrtoname.c:204
unsigned int bs_nbytes
Definition: addrtoname.c:206
u_short bs_addr2
Definition: addrtoname.c:203
u_char * bs_bytes
Definition: addrtoname.c:205
const char * e_name
Definition: addrtoname.c:192
u_short e_addr0
Definition: addrtoname.c:189
struct enamemem * e_nxt
Definition: addrtoname.c:194
u_short e_addr2
Definition: addrtoname.c:191
u_short e_addr1
Definition: addrtoname.c:190
u_char * e_nsap
Definition: addrtoname.c:193
const char * s
Definition: addrtoname.c:847
u_short p
Definition: addrtoname.c:848
const char * name
Definition: addrtoname.c:932
const nd_mac_addr addr
Definition: addrtoname.c:931
nd_ipv6 addr
Definition: addrtoname.c:181
struct h6namemem * nxt
Definition: addrtoname.c:183
char * name
Definition: addrtoname.c:182
uint32_t addr
Definition: addrtoname.c:128
const char * name
Definition: addrtoname.c:129
struct hnamemem * nxt
Definition: addrtoname.c:130
uint16_t v
Definition: addrtoname.c:1004
const char * s
Definition: addrtoname.c:1005
int(*) void NORETURN_FUNCPTR(* ndo_error)(netdissect_options *, status_exit_codes_t status, const char *fmt,...) PRINTFLIKE_FUNCPTR(3
Definition: netdissect.h:256
const char * name
Definition: addrtoname.c:884
const u_char protoid[5]
Definition: addrtoname.c:883
uint32_t p_oui
Definition: addrtoname.c:213
struct protoidmem * p_nxt
Definition: addrtoname.c:216
const char * p_name
Definition: addrtoname.c:215
u_short p_proto
Definition: addrtoname.c:214
int ether_ntohost(char *name, struct ether_addr *e)