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