14edb46e9SPaul Traina /*
2699fc314SBill Fenner * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
34edb46e9SPaul Traina * The Regents of the University of California. All rights reserved.
44edb46e9SPaul Traina *
54edb46e9SPaul Traina * Redistribution and use in source and binary forms, with or without
64edb46e9SPaul Traina * modification, are permitted provided that: (1) source code distributions
74edb46e9SPaul Traina * retain the above copyright notice and this paragraph in its entirety, (2)
84edb46e9SPaul Traina * distributions including binary code include the above copyright notice and
94edb46e9SPaul Traina * this paragraph in its entirety in the documentation or other materials
104edb46e9SPaul Traina * provided with the distribution, and (3) all advertising materials mentioning
114edb46e9SPaul Traina * features or use of this software display the following acknowledgement:
124edb46e9SPaul Traina * ``This product includes software developed by the University of California,
134edb46e9SPaul Traina * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
144edb46e9SPaul Traina * the University nor the names of its contributors may be used to endorse
154edb46e9SPaul Traina * or promote products derived from this software without specific prior
164edb46e9SPaul Traina * written permission.
174edb46e9SPaul Traina * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
184edb46e9SPaul Traina * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
194edb46e9SPaul Traina * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
204edb46e9SPaul Traina *
214edb46e9SPaul Traina * Internet, ethernet, port, and protocol string to address
224edb46e9SPaul Traina * and address to string conversion routines
234edb46e9SPaul Traina */
24a88113a8SBill Fenner
25ee67461eSJoseph Mingrone #include <config.h>
264edb46e9SPaul Traina
27b01988a5SMariusz Zaborski #ifdef HAVE_CASPER
28c501d73cSMariusz Zaborski #include <libcasper.h>
29c501d73cSMariusz Zaborski #include <casper/cap_dns.h>
30b01988a5SMariusz Zaborski #endif /* HAVE_CASPER */
313340d773SGleb Smirnoff
32ee67461eSJoseph Mingrone #include "netdissect-stdinc.h"
330e0def19SBill Fenner
340e0def19SBill Fenner #ifdef USE_ETHER_NTOHOST
35ee67461eSJoseph Mingrone #if defined(NET_ETHERNET_H_DECLARES_ETHER_NTOHOST)
36ee67461eSJoseph Mingrone /*
37ee67461eSJoseph Mingrone * OK, just include <net/ethernet.h>.
38ee67461eSJoseph Mingrone */
39ee67461eSJoseph Mingrone #include <net/ethernet.h>
40ee67461eSJoseph Mingrone #elif defined(NETINET_ETHER_H_DECLARES_ETHER_NTOHOST)
41ee67461eSJoseph Mingrone /*
42ee67461eSJoseph Mingrone * OK, just include <netinet/ether.h>
43ee67461eSJoseph Mingrone */
44c1ad1296SSam Leffler #include <netinet/ether.h>
45ee67461eSJoseph Mingrone #elif defined(SYS_ETHERNET_H_DECLARES_ETHER_NTOHOST)
46ee67461eSJoseph Mingrone /*
47ee67461eSJoseph Mingrone * OK, just include <sys/ethernet.h>
48ee67461eSJoseph Mingrone */
49ee67461eSJoseph Mingrone #include <sys/ethernet.h>
50ee67461eSJoseph Mingrone #elif defined(ARPA_INET_H_DECLARES_ETHER_NTOHOST)
51ee67461eSJoseph Mingrone /*
52ee67461eSJoseph Mingrone * OK, just include <arpa/inet.h>
53ee67461eSJoseph Mingrone */
54ee67461eSJoseph Mingrone #include <arpa/inet.h>
55ee67461eSJoseph Mingrone #elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_NTOHOST)
56ee67461eSJoseph Mingrone /*
57ee67461eSJoseph Mingrone * OK, include <netinet/if_ether.h>, after all the other stuff we
58ee67461eSJoseph Mingrone * need to include or define for its benefit.
59ee67461eSJoseph Mingrone */
60ee67461eSJoseph Mingrone #define NEED_NETINET_IF_ETHER_H
61ee67461eSJoseph Mingrone #else
62ee67461eSJoseph Mingrone /*
63ee67461eSJoseph Mingrone * We'll have to declare it ourselves.
64ee67461eSJoseph Mingrone * If <netinet/if_ether.h> defines struct ether_addr, include
65ee67461eSJoseph Mingrone * it. Otherwise, define it ourselves.
66ee67461eSJoseph Mingrone */
67ee67461eSJoseph Mingrone #ifdef HAVE_STRUCT_ETHER_ADDR
68ee67461eSJoseph Mingrone #define NEED_NETINET_IF_ETHER_H
69ee67461eSJoseph Mingrone #else /* HAVE_STRUCT_ETHER_ADDR */
7029292c17SSam Leffler struct ether_addr {
71ee67461eSJoseph Mingrone /* Beware FreeBSD calls this "octet". */
72ee67461eSJoseph Mingrone unsigned char ether_addr_octet[MAC_ADDR_LEN];
7329292c17SSam Leffler };
74ee67461eSJoseph Mingrone #endif /* HAVE_STRUCT_ETHER_ADDR */
75ee67461eSJoseph Mingrone #endif /* what declares ether_ntohost() */
76c1ad1296SSam Leffler
77ee67461eSJoseph Mingrone #ifdef NEED_NETINET_IF_ETHER_H
78ee67461eSJoseph Mingrone /*
79ee67461eSJoseph Mingrone * Include diag-control.h before <net/if.h>, which too defines a macro
80ee67461eSJoseph Mingrone * named ND_UNREACHABLE.
81ee67461eSJoseph Mingrone */
82ee67461eSJoseph Mingrone #include "diag-control.h"
83ee67461eSJoseph Mingrone #include <net/if.h> /* Needed on some platforms */
84ee67461eSJoseph Mingrone #include <netinet/in.h> /* Needed on some platforms */
85ee67461eSJoseph Mingrone #include <netinet/if_ether.h>
86ee67461eSJoseph Mingrone #endif /* NEED_NETINET_IF_ETHER_H */
87ee67461eSJoseph Mingrone
88ee67461eSJoseph Mingrone #ifndef HAVE_DECL_ETHER_NTOHOST
89ee67461eSJoseph Mingrone /*
90ee67461eSJoseph Mingrone * No header declares it, so declare it ourselves.
91ee67461eSJoseph Mingrone */
92ee67461eSJoseph Mingrone extern int ether_ntohost(char *, const struct ether_addr *);
93ee67461eSJoseph Mingrone #endif /* !defined(HAVE_DECL_ETHER_NTOHOST) */
9429292c17SSam Leffler #endif /* USE_ETHER_NTOHOST */
9529292c17SSam Leffler
964edb46e9SPaul Traina #include <pcap.h>
974edb46e9SPaul Traina #include <pcap-namedb.h>
98ee67461eSJoseph Mingrone #ifndef HAVE_GETSERVENT
99ee67461eSJoseph Mingrone #include <getservent.h>
100ee67461eSJoseph Mingrone #endif
1014edb46e9SPaul Traina #include <signal.h>
1024edb46e9SPaul Traina #include <stdio.h>
1034edb46e9SPaul Traina #include <string.h>
1044edb46e9SPaul Traina #include <stdlib.h>
1054edb46e9SPaul Traina
1063340d773SGleb Smirnoff #include "netdissect.h"
1074edb46e9SPaul Traina #include "addrtoname.h"
1083340d773SGleb Smirnoff #include "addrtostr.h"
1093340d773SGleb Smirnoff #include "ethertype.h"
1104edb46e9SPaul Traina #include "llc.h"
11129292c17SSam Leffler #include "extract.h"
11229292c17SSam Leffler #include "oui.h"
1134edb46e9SPaul Traina
1144edb46e9SPaul Traina /*
1154edb46e9SPaul Traina * hash tables for whatever-to-name translations
116cc391cceSBruce M Simpson *
117ee67461eSJoseph Mingrone * ndo_error() called on strdup(3) failure with S_ERR_ND_MEM_ALLOC status
1184edb46e9SPaul Traina */
1194edb46e9SPaul Traina
1204edb46e9SPaul Traina #define HASHNAMESIZE 4096
1214edb46e9SPaul Traina
1224edb46e9SPaul Traina struct hnamemem {
1233c602fabSXin LI uint32_t addr;
124a1c2090eSBill Fenner const char *name;
1254edb46e9SPaul Traina struct hnamemem *nxt;
1264edb46e9SPaul Traina };
1274edb46e9SPaul Traina
12827df3f5dSRui Paulo static struct hnamemem hnametable[HASHNAMESIZE];
12927df3f5dSRui Paulo static struct hnamemem tporttable[HASHNAMESIZE];
13027df3f5dSRui Paulo static struct hnamemem uporttable[HASHNAMESIZE];
13127df3f5dSRui Paulo static struct hnamemem eprototable[HASHNAMESIZE];
13227df3f5dSRui Paulo static struct hnamemem dnaddrtable[HASHNAMESIZE];
13327df3f5dSRui Paulo static struct hnamemem ipxsaptable[HASHNAMESIZE];
134cc391cceSBruce M Simpson
1353340d773SGleb Smirnoff #ifdef _WIN32
136cc391cceSBruce M Simpson /*
137cc391cceSBruce M Simpson * fake gethostbyaddr for Win2k/XP
138cc391cceSBruce M Simpson * gethostbyaddr() returns incorrect value when AF_INET6 is passed
139cc391cceSBruce M Simpson * to 3rd argument.
140cc391cceSBruce M Simpson *
141cc391cceSBruce M Simpson * h_name in struct hostent is only valid.
142cc391cceSBruce M Simpson */
143cc391cceSBruce M Simpson static struct hostent *
win32_gethostbyaddr(const char * addr,int len,int type)144cc391cceSBruce M Simpson win32_gethostbyaddr(const char *addr, int len, int type)
145cc391cceSBruce M Simpson {
146cc391cceSBruce M Simpson static struct hostent host;
147cc391cceSBruce M Simpson static char hostbuf[NI_MAXHOST];
148cc391cceSBruce M Simpson char hname[NI_MAXHOST];
149cc391cceSBruce M Simpson struct sockaddr_in6 addr6;
150cc391cceSBruce M Simpson
151cc391cceSBruce M Simpson host.h_name = hostbuf;
152cc391cceSBruce M Simpson switch (type) {
153cc391cceSBruce M Simpson case AF_INET:
154cc391cceSBruce M Simpson return gethostbyaddr(addr, len, type);
155cc391cceSBruce M Simpson break;
156cc391cceSBruce M Simpson case AF_INET6:
157cc391cceSBruce M Simpson memset(&addr6, 0, sizeof(addr6));
158cc391cceSBruce M Simpson addr6.sin6_family = AF_INET6;
159cc391cceSBruce M Simpson memcpy(&addr6.sin6_addr, addr, len);
160cc391cceSBruce M Simpson if (getnameinfo((struct sockaddr *)&addr6, sizeof(addr6),
161cc391cceSBruce M Simpson hname, sizeof(hname), NULL, 0, 0)) {
162cc391cceSBruce M Simpson return NULL;
163cc391cceSBruce M Simpson } else {
16439e421e8SCy Schubert strlcpy(host.h_name, hname, NI_MAXHOST);
165cc391cceSBruce M Simpson return &host;
166cc391cceSBruce M Simpson }
167cc391cceSBruce M Simpson break;
168cc391cceSBruce M Simpson default:
169cc391cceSBruce M Simpson return NULL;
170cc391cceSBruce M Simpson }
171cc391cceSBruce M Simpson }
172cc391cceSBruce M Simpson #define gethostbyaddr win32_gethostbyaddr
1733340d773SGleb Smirnoff #endif /* _WIN32 */
1744edb46e9SPaul Traina
175a88113a8SBill Fenner struct h6namemem {
176ee67461eSJoseph Mingrone nd_ipv6 addr;
177a88113a8SBill Fenner char *name;
178a88113a8SBill Fenner struct h6namemem *nxt;
179a88113a8SBill Fenner };
180a88113a8SBill Fenner
18127df3f5dSRui Paulo static struct h6namemem h6nametable[HASHNAMESIZE];
182a88113a8SBill Fenner
1834edb46e9SPaul Traina struct enamemem {
1844edb46e9SPaul Traina u_short e_addr0;
1854edb46e9SPaul Traina u_short e_addr1;
1864edb46e9SPaul Traina u_short e_addr2;
187a1c2090eSBill Fenner const char *e_name;
1884edb46e9SPaul Traina u_char *e_nsap; /* used only for nsaptable[] */
1894edb46e9SPaul Traina struct enamemem *e_nxt;
1904edb46e9SPaul Traina };
1914edb46e9SPaul Traina
19227df3f5dSRui Paulo static struct enamemem enametable[HASHNAMESIZE];
19327df3f5dSRui Paulo static struct enamemem nsaptable[HASHNAMESIZE];
1940bff6a5aSEd Maste
1950bff6a5aSEd Maste struct bsnamemem {
1960bff6a5aSEd Maste u_short bs_addr0;
1970bff6a5aSEd Maste u_short bs_addr1;
1980bff6a5aSEd Maste u_short bs_addr2;
1990bff6a5aSEd Maste const char *bs_name;
2000bff6a5aSEd Maste u_char *bs_bytes;
2010bff6a5aSEd Maste unsigned int bs_nbytes;
2020bff6a5aSEd Maste struct bsnamemem *bs_nxt;
2030bff6a5aSEd Maste };
2040bff6a5aSEd Maste
2050bff6a5aSEd Maste static struct bsnamemem bytestringtable[HASHNAMESIZE];
2064edb46e9SPaul Traina
2074edb46e9SPaul Traina struct protoidmem {
2083c602fabSXin LI uint32_t p_oui;
2094edb46e9SPaul Traina u_short p_proto;
210a1c2090eSBill Fenner const char *p_name;
2114edb46e9SPaul Traina struct protoidmem *p_nxt;
2124edb46e9SPaul Traina };
2134edb46e9SPaul Traina
21427df3f5dSRui Paulo static struct protoidmem protoidtable[HASHNAMESIZE];
2154edb46e9SPaul Traina
2164edb46e9SPaul Traina /*
2174edb46e9SPaul Traina * A faster replacement for inet_ntoa().
2184edb46e9SPaul Traina */
219a1c2090eSBill Fenner const char *
intoa(uint32_t addr)2203c602fabSXin LI intoa(uint32_t addr)
2214edb46e9SPaul Traina {
222ee67461eSJoseph Mingrone char *cp;
223ee67461eSJoseph Mingrone u_int byte;
224ee67461eSJoseph Mingrone int n;
2254edb46e9SPaul Traina static char buf[sizeof(".xxx.xxx.xxx.xxx")];
2264edb46e9SPaul Traina
227ee67461eSJoseph Mingrone addr = ntohl(addr);
22829292c17SSam Leffler cp = buf + sizeof(buf);
2294edb46e9SPaul Traina *--cp = '\0';
2304edb46e9SPaul Traina
2314edb46e9SPaul Traina n = 4;
2324edb46e9SPaul Traina do {
2334edb46e9SPaul Traina byte = addr & 0xff;
234ee67461eSJoseph Mingrone *--cp = (char)(byte % 10) + '0';
2354edb46e9SPaul Traina byte /= 10;
2364edb46e9SPaul Traina if (byte > 0) {
237ee67461eSJoseph Mingrone *--cp = (char)(byte % 10) + '0';
2384edb46e9SPaul Traina byte /= 10;
2394edb46e9SPaul Traina if (byte > 0)
240ee67461eSJoseph Mingrone *--cp = (char)byte + '0';
2414edb46e9SPaul Traina }
2424edb46e9SPaul Traina *--cp = '.';
2434edb46e9SPaul Traina addr >>= 8;
2444edb46e9SPaul Traina } while (--n > 0);
2454edb46e9SPaul Traina
2464edb46e9SPaul Traina return cp + 1;
2474edb46e9SPaul Traina }
2484edb46e9SPaul Traina
2493c602fabSXin LI static uint32_t f_netmask;
2503c602fabSXin LI static uint32_t f_localnet;
251b01988a5SMariusz Zaborski #ifdef HAVE_CASPER
252ee67461eSJoseph Mingrone cap_channel_t *capdns;
253197731f6SPawel Jakub Dawidek #endif
2544edb46e9SPaul Traina
2554edb46e9SPaul Traina /*
2564edb46e9SPaul Traina * Return a name for the IP address pointed to by ap. This address
2574edb46e9SPaul Traina * is assumed to be in network byte order.
258cc391cceSBruce M Simpson *
259ee67461eSJoseph Mingrone * NOTE: ap is *NOT* necessarily part of the packet data, so you
260ee67461eSJoseph Mingrone * *CANNOT* use the ND_TCHECK_* or ND_TTEST_* macros on it. Furthermore,
261cc391cceSBruce M Simpson * even in cases where it *is* part of the packet data, the caller
262cc391cceSBruce M Simpson * would still have to check for a null return value, even if it's
263cc391cceSBruce M Simpson * just printing the return value with "%s" - not all versions of
264cc391cceSBruce M Simpson * printf print "(null)" with "%s" and a null pointer, some of them
265cc391cceSBruce M Simpson * don't check for a null pointer and crash in that case.
266cc391cceSBruce M Simpson *
267cc391cceSBruce M Simpson * The callers of this routine should, before handing this routine
268cc391cceSBruce M Simpson * a pointer to packet data, be sure that the data is present in
269cc391cceSBruce M Simpson * the packet buffer. They should probably do those checks anyway,
270cc391cceSBruce M Simpson * as other data at that layer might not be IP addresses, and it
271cc391cceSBruce M Simpson * also needs to check whether they're present in the packet buffer.
2724edb46e9SPaul Traina */
273a1c2090eSBill Fenner const char *
ipaddr_string(netdissect_options * ndo,const u_char * ap)274ee67461eSJoseph Mingrone ipaddr_string(netdissect_options *ndo, const u_char *ap)
2754edb46e9SPaul Traina {
276ee67461eSJoseph Mingrone struct hostent *hp;
2773c602fabSXin LI uint32_t addr;
2783340d773SGleb Smirnoff struct hnamemem *p;
2794edb46e9SPaul Traina
280a88113a8SBill Fenner memcpy(&addr, ap, sizeof(addr));
2814edb46e9SPaul Traina p = &hnametable[addr & (HASHNAMESIZE-1)];
2824edb46e9SPaul Traina for (; p->nxt; p = p->nxt) {
2834edb46e9SPaul Traina if (p->addr == addr)
2844edb46e9SPaul Traina return (p->name);
2854edb46e9SPaul Traina }
2864edb46e9SPaul Traina p->addr = addr;
2873340d773SGleb Smirnoff p->nxt = newhnamemem(ndo);
2884edb46e9SPaul Traina
2894edb46e9SPaul Traina /*
290cc391cceSBruce M Simpson * Print names unless:
291cc391cceSBruce M Simpson * (1) -n was given.
292699fc314SBill Fenner * (2) Address is foreign and -f was given. (If -f was not
293cc391cceSBruce M Simpson * given, f_netmask and f_localnet are 0 and the test
294699fc314SBill Fenner * evaluates to true)
2954edb46e9SPaul Traina */
2963c602fabSXin LI if (!ndo->ndo_nflag &&
297cc391cceSBruce M Simpson (addr & f_netmask) == f_localnet) {
298b01988a5SMariusz Zaborski #ifdef HAVE_CASPER
299197731f6SPawel Jakub Dawidek if (capdns != NULL) {
300197731f6SPawel Jakub Dawidek hp = cap_gethostbyaddr(capdns, (char *)&addr, 4,
301197731f6SPawel Jakub Dawidek AF_INET);
302197731f6SPawel Jakub Dawidek } else
303197731f6SPawel Jakub Dawidek #endif
3044edb46e9SPaul Traina hp = gethostbyaddr((char *)&addr, 4, AF_INET);
3054edb46e9SPaul Traina if (hp) {
3064edb46e9SPaul Traina char *dotp;
3074edb46e9SPaul Traina
308a1c2090eSBill Fenner p->name = strdup(hp->h_name);
3093340d773SGleb Smirnoff if (p->name == NULL)
310ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
311ee67461eSJoseph Mingrone "%s: strdup(hp->h_name)", __func__);
3123c602fabSXin LI if (ndo->ndo_Nflag) {
3134edb46e9SPaul Traina /* Remove domain qualifications */
3144edb46e9SPaul Traina dotp = strchr(p->name, '.');
3154edb46e9SPaul Traina if (dotp)
3164edb46e9SPaul Traina *dotp = '\0';
3174edb46e9SPaul Traina }
3184edb46e9SPaul Traina return (p->name);
3194edb46e9SPaul Traina }
3204edb46e9SPaul Traina }
321a1c2090eSBill Fenner p->name = strdup(intoa(addr));
3223340d773SGleb Smirnoff if (p->name == NULL)
323ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
324ee67461eSJoseph Mingrone "%s: strdup(intoa(addr))", __func__);
3254edb46e9SPaul Traina return (p->name);
3264edb46e9SPaul Traina }
3274edb46e9SPaul Traina
328a88113a8SBill Fenner /*
329a88113a8SBill Fenner * Return a name for the IP6 address pointed to by ap. This address
330a88113a8SBill Fenner * is assumed to be in network byte order.
331a88113a8SBill Fenner */
332a1c2090eSBill Fenner const char *
ip6addr_string(netdissect_options * ndo,const u_char * ap)333ee67461eSJoseph Mingrone ip6addr_string(netdissect_options *ndo, const u_char *ap)
334a88113a8SBill Fenner {
335ee67461eSJoseph Mingrone struct hostent *hp;
3363c602fabSXin LI union {
337ee67461eSJoseph Mingrone nd_ipv6 addr;
3383c602fabSXin LI struct for_hash_addr {
3393c602fabSXin LI char fill[14];
3403c602fabSXin LI uint16_t d;
3413c602fabSXin LI } addra;
3423c602fabSXin LI } addr;
3433340d773SGleb Smirnoff struct h6namemem *p;
344ee67461eSJoseph Mingrone const char *cp;
345a88113a8SBill Fenner char ntop_buf[INET6_ADDRSTRLEN];
346a88113a8SBill Fenner
347a88113a8SBill Fenner memcpy(&addr, ap, sizeof(addr));
3483c602fabSXin LI p = &h6nametable[addr.addra.d & (HASHNAMESIZE-1)];
349a88113a8SBill Fenner for (; p->nxt; p = p->nxt) {
350a88113a8SBill Fenner if (memcmp(&p->addr, &addr, sizeof(addr)) == 0)
351a88113a8SBill Fenner return (p->name);
352a88113a8SBill Fenner }
353ee67461eSJoseph Mingrone memcpy(p->addr, addr.addr, sizeof(nd_ipv6));
3543340d773SGleb Smirnoff p->nxt = newh6namemem(ndo);
355a88113a8SBill Fenner
356a88113a8SBill Fenner /*
357cc391cceSBruce M Simpson * Do not print names if -n was given.
358a88113a8SBill Fenner */
3593c602fabSXin LI if (!ndo->ndo_nflag) {
360b01988a5SMariusz Zaborski #ifdef HAVE_CASPER
361197731f6SPawel Jakub Dawidek if (capdns != NULL) {
362197731f6SPawel Jakub Dawidek hp = cap_gethostbyaddr(capdns, (char *)&addr,
363197731f6SPawel Jakub Dawidek sizeof(addr), AF_INET6);
364197731f6SPawel Jakub Dawidek } else
365197731f6SPawel Jakub Dawidek #endif
3663340d773SGleb Smirnoff hp = gethostbyaddr((char *)&addr, sizeof(addr),
3673340d773SGleb Smirnoff AF_INET6);
368a88113a8SBill Fenner if (hp) {
369a88113a8SBill Fenner char *dotp;
370a88113a8SBill Fenner
371a1c2090eSBill Fenner p->name = strdup(hp->h_name);
3723340d773SGleb Smirnoff if (p->name == NULL)
373ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
374ee67461eSJoseph Mingrone "%s: strdup(hp->h_name)", __func__);
3753c602fabSXin LI if (ndo->ndo_Nflag) {
376a88113a8SBill Fenner /* Remove domain qualifications */
377a88113a8SBill Fenner dotp = strchr(p->name, '.');
378a88113a8SBill Fenner if (dotp)
379a88113a8SBill Fenner *dotp = '\0';
380a88113a8SBill Fenner }
381a88113a8SBill Fenner return (p->name);
382a88113a8SBill Fenner }
383a88113a8SBill Fenner }
3843340d773SGleb Smirnoff cp = addrtostr6(ap, ntop_buf, sizeof(ntop_buf));
385a1c2090eSBill Fenner p->name = strdup(cp);
3863340d773SGleb Smirnoff if (p->name == NULL)
387ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
388ee67461eSJoseph Mingrone "%s: strdup(cp)", __func__);
389a88113a8SBill Fenner return (p->name);
390a88113a8SBill Fenner }
391a88113a8SBill Fenner
392ee67461eSJoseph Mingrone static const char hex[16] = {
393ee67461eSJoseph Mingrone '0', '1', '2', '3', '4', '5', '6', '7',
394ee67461eSJoseph Mingrone '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
395ee67461eSJoseph Mingrone };
3964edb46e9SPaul Traina
397ee67461eSJoseph Mingrone /*
398ee67461eSJoseph Mingrone * Convert an octet to two hex digits.
399ee67461eSJoseph Mingrone *
400ee67461eSJoseph Mingrone * Coverity appears either:
401ee67461eSJoseph Mingrone *
402ee67461eSJoseph Mingrone * not to believe the C standard when it asserts that a uint8_t is
403ee67461eSJoseph Mingrone * exactly 8 bits in size;
404ee67461eSJoseph Mingrone *
405ee67461eSJoseph Mingrone * not to believe that an unsigned type of exactly 8 bits has a value
406ee67461eSJoseph Mingrone * in the range of 0 to 255;
407ee67461eSJoseph Mingrone *
408ee67461eSJoseph Mingrone * not to believe that, for a range of unsigned values, if you shift
409ee67461eSJoseph Mingrone * one of those values right by 4 bits, the maximum result value is
410ee67461eSJoseph Mingrone * the maximum value shifted right by 4 bits, with no stray 1's shifted
411ee67461eSJoseph Mingrone * in;
412ee67461eSJoseph Mingrone *
413ee67461eSJoseph Mingrone * not to believe that 255 >> 4 is 15;
414ee67461eSJoseph Mingrone *
415ee67461eSJoseph Mingrone * so it gets upset that we're taking a "tainted" unsigned value, shifting
416ee67461eSJoseph Mingrone * it right 4 bits, and using it as an index into a 16-element array.
417ee67461eSJoseph Mingrone *
418ee67461eSJoseph Mingrone * So we do a stupid pointless masking of the result of the shift with
419ee67461eSJoseph Mingrone * 0xf, to hammer the point home to Coverity.
420ee67461eSJoseph Mingrone */
421ee67461eSJoseph Mingrone static inline char *
octet_to_hex(char * cp,uint8_t octet)422ee67461eSJoseph Mingrone octet_to_hex(char *cp, uint8_t octet)
423ee67461eSJoseph Mingrone {
424ee67461eSJoseph Mingrone *cp++ = hex[(octet >> 4) & 0xf];
425ee67461eSJoseph Mingrone *cp++ = hex[(octet >> 0) & 0xf];
426ee67461eSJoseph Mingrone return (cp);
427ee67461eSJoseph Mingrone }
4284edb46e9SPaul Traina
4294edb46e9SPaul Traina /* Find the hash node that corresponds the ether address 'ep' */
4304edb46e9SPaul Traina
431ee67461eSJoseph Mingrone static struct enamemem *
lookup_emem(netdissect_options * ndo,const u_char * ep)4323340d773SGleb Smirnoff lookup_emem(netdissect_options *ndo, const u_char *ep)
4334edb46e9SPaul Traina {
434ee67461eSJoseph Mingrone u_int i, j, k;
4354edb46e9SPaul Traina struct enamemem *tp;
4364edb46e9SPaul Traina
4374edb46e9SPaul Traina k = (ep[0] << 8) | ep[1];
4384edb46e9SPaul Traina j = (ep[2] << 8) | ep[3];
4394edb46e9SPaul Traina i = (ep[4] << 8) | ep[5];
4404edb46e9SPaul Traina
4414edb46e9SPaul Traina tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
4424edb46e9SPaul Traina while (tp->e_nxt)
4434edb46e9SPaul Traina if (tp->e_addr0 == i &&
4444edb46e9SPaul Traina tp->e_addr1 == j &&
4454edb46e9SPaul Traina tp->e_addr2 == k)
4464edb46e9SPaul Traina return tp;
4474edb46e9SPaul Traina else
4484edb46e9SPaul Traina tp = tp->e_nxt;
449ee67461eSJoseph Mingrone tp->e_addr0 = (u_short)i;
450ee67461eSJoseph Mingrone tp->e_addr1 = (u_short)j;
451ee67461eSJoseph Mingrone tp->e_addr2 = (u_short)k;
4524edb46e9SPaul Traina tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
4534edb46e9SPaul Traina if (tp->e_nxt == NULL)
454ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__);
4554edb46e9SPaul Traina
4564edb46e9SPaul Traina return tp;
4574edb46e9SPaul Traina }
4584edb46e9SPaul Traina
459a1c2090eSBill Fenner /*
460a1c2090eSBill Fenner * Find the hash node that corresponds to the bytestring 'bs'
461a1c2090eSBill Fenner * with length 'nlen'
462a1c2090eSBill Fenner */
463a1c2090eSBill Fenner
464ee67461eSJoseph Mingrone static struct bsnamemem *
lookup_bytestring(netdissect_options * ndo,const u_char * bs,const unsigned int nlen)465ee67461eSJoseph Mingrone lookup_bytestring(netdissect_options *ndo, const u_char *bs,
4663340d773SGleb Smirnoff const unsigned int nlen)
467a1c2090eSBill Fenner {
4680bff6a5aSEd Maste struct bsnamemem *tp;
469ee67461eSJoseph Mingrone u_int i, j, k;
470a1c2090eSBill Fenner
471a1c2090eSBill Fenner if (nlen >= 6) {
472a1c2090eSBill Fenner k = (bs[0] << 8) | bs[1];
473a1c2090eSBill Fenner j = (bs[2] << 8) | bs[3];
474a1c2090eSBill Fenner i = (bs[4] << 8) | bs[5];
475a1c2090eSBill Fenner } else if (nlen >= 4) {
476a1c2090eSBill Fenner k = (bs[0] << 8) | bs[1];
477a1c2090eSBill Fenner j = (bs[2] << 8) | bs[3];
478a1c2090eSBill Fenner i = 0;
479a1c2090eSBill Fenner } else
480a1c2090eSBill Fenner i = j = k = 0;
481a1c2090eSBill Fenner
482a1c2090eSBill Fenner tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)];
4830bff6a5aSEd Maste while (tp->bs_nxt)
4840bff6a5aSEd Maste if (nlen == tp->bs_nbytes &&
4850bff6a5aSEd Maste tp->bs_addr0 == i &&
4860bff6a5aSEd Maste tp->bs_addr1 == j &&
4870bff6a5aSEd Maste tp->bs_addr2 == k &&
4880bff6a5aSEd Maste memcmp((const char *)bs, (const char *)(tp->bs_bytes), nlen) == 0)
489a1c2090eSBill Fenner return tp;
490a1c2090eSBill Fenner else
4910bff6a5aSEd Maste tp = tp->bs_nxt;
492a1c2090eSBill Fenner
493ee67461eSJoseph Mingrone tp->bs_addr0 = (u_short)i;
494ee67461eSJoseph Mingrone tp->bs_addr1 = (u_short)j;
495ee67461eSJoseph Mingrone tp->bs_addr2 = (u_short)k;
496a1c2090eSBill Fenner
4970bff6a5aSEd Maste tp->bs_bytes = (u_char *) calloc(1, nlen);
4980bff6a5aSEd Maste if (tp->bs_bytes == NULL)
499ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
500ee67461eSJoseph Mingrone "%s: calloc", __func__);
501d03c0883SXin LI
5020bff6a5aSEd Maste memcpy(tp->bs_bytes, bs, nlen);
5030bff6a5aSEd Maste tp->bs_nbytes = nlen;
5040bff6a5aSEd Maste tp->bs_nxt = (struct bsnamemem *)calloc(1, sizeof(*tp));
5050bff6a5aSEd Maste if (tp->bs_nxt == NULL)
506ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
507ee67461eSJoseph Mingrone "%s: calloc", __func__);
508a1c2090eSBill Fenner
509a1c2090eSBill Fenner return tp;
510a1c2090eSBill Fenner }
511a1c2090eSBill Fenner
5124edb46e9SPaul Traina /* Find the hash node that corresponds the NSAP 'nsap' */
5134edb46e9SPaul Traina
514ee67461eSJoseph Mingrone static struct enamemem *
lookup_nsap(netdissect_options * ndo,const u_char * nsap,u_int nsap_length)515ee67461eSJoseph Mingrone lookup_nsap(netdissect_options *ndo, const u_char *nsap,
516ee67461eSJoseph Mingrone u_int nsap_length)
5174edb46e9SPaul Traina {
518ee67461eSJoseph Mingrone u_int i, j, k;
5194edb46e9SPaul Traina struct enamemem *tp;
5203340d773SGleb Smirnoff const u_char *ensap;
5214edb46e9SPaul Traina
5223340d773SGleb Smirnoff if (nsap_length > 6) {
5233340d773SGleb Smirnoff ensap = nsap + nsap_length - 6;
5244edb46e9SPaul Traina k = (ensap[0] << 8) | ensap[1];
5254edb46e9SPaul Traina j = (ensap[2] << 8) | ensap[3];
5264edb46e9SPaul Traina i = (ensap[4] << 8) | ensap[5];
527*0a7e5f1fSJoseph Mingrone } else
5284edb46e9SPaul Traina i = j = k = 0;
5294edb46e9SPaul Traina
5304edb46e9SPaul Traina tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
5314edb46e9SPaul Traina while (tp->e_nxt)
5320bff6a5aSEd Maste if (nsap_length == tp->e_nsap[0] &&
5330bff6a5aSEd Maste tp->e_addr0 == i &&
5344edb46e9SPaul Traina tp->e_addr1 == j &&
5354edb46e9SPaul Traina tp->e_addr2 == k &&
5360bff6a5aSEd Maste memcmp((const char *)nsap,
5373340d773SGleb Smirnoff (char *)&(tp->e_nsap[1]), nsap_length) == 0)
5384edb46e9SPaul Traina return tp;
5394edb46e9SPaul Traina else
5404edb46e9SPaul Traina tp = tp->e_nxt;
541ee67461eSJoseph Mingrone tp->e_addr0 = (u_short)i;
542ee67461eSJoseph Mingrone tp->e_addr1 = (u_short)j;
543ee67461eSJoseph Mingrone tp->e_addr2 = (u_short)k;
5443340d773SGleb Smirnoff tp->e_nsap = (u_char *)malloc(nsap_length + 1);
5454edb46e9SPaul Traina if (tp->e_nsap == NULL)
546ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: malloc", __func__);
5473340d773SGleb Smirnoff tp->e_nsap[0] = (u_char)nsap_length; /* guaranteed < ISONSAP_MAX_LENGTH */
5483340d773SGleb Smirnoff memcpy((char *)&tp->e_nsap[1], (const char *)nsap, nsap_length);
5494edb46e9SPaul Traina tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
5504edb46e9SPaul Traina if (tp->e_nxt == NULL)
551ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__);
5524edb46e9SPaul Traina
5534edb46e9SPaul Traina return tp;
5544edb46e9SPaul Traina }
5554edb46e9SPaul Traina
5564edb46e9SPaul Traina /* Find the hash node that corresponds the protoid 'pi'. */
5574edb46e9SPaul Traina
558ee67461eSJoseph Mingrone static struct protoidmem *
lookup_protoid(netdissect_options * ndo,const u_char * pi)5593340d773SGleb Smirnoff lookup_protoid(netdissect_options *ndo, const u_char *pi)
5604edb46e9SPaul Traina {
561ee67461eSJoseph Mingrone u_int i, j;
5624edb46e9SPaul Traina struct protoidmem *tp;
5634edb46e9SPaul Traina
5644edb46e9SPaul Traina /* 5 octets won't be aligned */
5654edb46e9SPaul Traina i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
5664edb46e9SPaul Traina j = (pi[3] << 8) + pi[4];
5674edb46e9SPaul Traina /* XXX should be endian-insensitive, but do big-endian testing XXX */
5684edb46e9SPaul Traina
5694edb46e9SPaul Traina tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
5704edb46e9SPaul Traina while (tp->p_nxt)
5714edb46e9SPaul Traina if (tp->p_oui == i && tp->p_proto == j)
5724edb46e9SPaul Traina return tp;
5734edb46e9SPaul Traina else
5744edb46e9SPaul Traina tp = tp->p_nxt;
5754edb46e9SPaul Traina tp->p_oui = i;
576ee67461eSJoseph Mingrone tp->p_proto = (u_short)j;
5774edb46e9SPaul Traina tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
5784edb46e9SPaul Traina if (tp->p_nxt == NULL)
579ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC, "%s: calloc", __func__);
5804edb46e9SPaul Traina
5814edb46e9SPaul Traina return tp;
5824edb46e9SPaul Traina }
5834edb46e9SPaul Traina
584a1c2090eSBill Fenner const char *
etheraddr_string(netdissect_options * ndo,const uint8_t * ep)585ee67461eSJoseph Mingrone etheraddr_string(netdissect_options *ndo, const uint8_t *ep)
5864edb46e9SPaul Traina {
587ee67461eSJoseph Mingrone int i;
588ee67461eSJoseph Mingrone char *cp;
589ee67461eSJoseph Mingrone struct enamemem *tp;
59017cb103cSSam Leffler int oui;
59129292c17SSam Leffler char buf[BUFSIZE];
5924edb46e9SPaul Traina
5933340d773SGleb Smirnoff tp = lookup_emem(ndo, ep);
5944edb46e9SPaul Traina if (tp->e_name)
5954edb46e9SPaul Traina return (tp->e_name);
596a1c2090eSBill Fenner #ifdef USE_ETHER_NTOHOST
5973c602fabSXin LI if (!ndo->ndo_nflag) {
59829292c17SSam Leffler char buf2[BUFSIZE];
599ee67461eSJoseph Mingrone /*
600ee67461eSJoseph Mingrone * This is a non-const copy of ep for ether_ntohost(), which
601ee67461eSJoseph Mingrone * has its second argument non-const in OpenBSD. Also saves a
602ee67461eSJoseph Mingrone * type cast.
603ee67461eSJoseph Mingrone */
604ee67461eSJoseph Mingrone struct ether_addr ea;
605c1ad1296SSam Leffler
606ee67461eSJoseph Mingrone memcpy (&ea, ep, MAC_ADDR_LEN);
607ee67461eSJoseph Mingrone if (ether_ntohost(buf2, &ea) == 0) {
608cc391cceSBruce M Simpson tp->e_name = strdup(buf2);
6093340d773SGleb Smirnoff if (tp->e_name == NULL)
610ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
611ee67461eSJoseph Mingrone "%s: strdup(buf2)", __func__);
6124edb46e9SPaul Traina return (tp->e_name);
6134edb46e9SPaul Traina }
6144edb46e9SPaul Traina }
6154edb46e9SPaul Traina #endif
6164edb46e9SPaul Traina cp = buf;
617ee67461eSJoseph Mingrone oui = EXTRACT_BE_U_3(ep);
618ee67461eSJoseph Mingrone cp = octet_to_hex(cp, *ep++);
61917cb103cSSam Leffler for (i = 5; --i >= 0;) {
6204edb46e9SPaul Traina *cp++ = ':';
621ee67461eSJoseph Mingrone cp = octet_to_hex(cp, *ep++);
6224edb46e9SPaul Traina }
62329292c17SSam Leffler
6243c602fabSXin LI if (!ndo->ndo_nflag) {
62517cb103cSSam Leffler snprintf(cp, BUFSIZE - (2 + 5*3), " (oui %s)",
62629292c17SSam Leffler tok2str(oui_values, "Unknown", oui));
62729292c17SSam Leffler } else
6284edb46e9SPaul Traina *cp = '\0';
629a1c2090eSBill Fenner tp->e_name = strdup(buf);
6303340d773SGleb Smirnoff if (tp->e_name == NULL)
631ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
632ee67461eSJoseph Mingrone "%s: strdup(buf)", __func__);
6334edb46e9SPaul Traina return (tp->e_name);
6344edb46e9SPaul Traina }
6354edb46e9SPaul Traina
636a1c2090eSBill Fenner const char *
le64addr_string(netdissect_options * ndo,const uint8_t * ep)637ee67461eSJoseph Mingrone le64addr_string(netdissect_options *ndo, const uint8_t *ep)
638cac3dcd5SXin LI {
639cac3dcd5SXin LI const unsigned int len = 8;
640ee67461eSJoseph Mingrone u_int i;
641ee67461eSJoseph Mingrone char *cp;
642ee67461eSJoseph Mingrone struct bsnamemem *tp;
643cac3dcd5SXin LI char buf[BUFSIZE];
644cac3dcd5SXin LI
6453340d773SGleb Smirnoff tp = lookup_bytestring(ndo, ep, len);
6460bff6a5aSEd Maste if (tp->bs_name)
6470bff6a5aSEd Maste return (tp->bs_name);
648cac3dcd5SXin LI
649cac3dcd5SXin LI cp = buf;
650cac3dcd5SXin LI for (i = len; i > 0 ; --i) {
651ee67461eSJoseph Mingrone cp = octet_to_hex(cp, *(ep + i - 1));
652cac3dcd5SXin LI *cp++ = ':';
653cac3dcd5SXin LI }
654cac3dcd5SXin LI cp --;
655cac3dcd5SXin LI
656cac3dcd5SXin LI *cp = '\0';
657cac3dcd5SXin LI
6580bff6a5aSEd Maste tp->bs_name = strdup(buf);
6590bff6a5aSEd Maste if (tp->bs_name == NULL)
660ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
661ee67461eSJoseph Mingrone "%s: strdup(buf)", __func__);
662cac3dcd5SXin LI
6630bff6a5aSEd Maste return (tp->bs_name);
664cac3dcd5SXin LI }
665cac3dcd5SXin LI
666cac3dcd5SXin LI const char *
linkaddr_string(netdissect_options * ndo,const uint8_t * ep,const unsigned int type,const unsigned int len)667ee67461eSJoseph Mingrone linkaddr_string(netdissect_options *ndo, const uint8_t *ep,
6683340d773SGleb Smirnoff const unsigned int type, const unsigned int len)
669a1c2090eSBill Fenner {
670ee67461eSJoseph Mingrone u_int i;
671ee67461eSJoseph Mingrone char *cp;
672ee67461eSJoseph Mingrone struct bsnamemem *tp;
673a1c2090eSBill Fenner
67427df3f5dSRui Paulo if (len == 0)
67527df3f5dSRui Paulo return ("<empty>");
676a5779b6eSRui Paulo
677ee67461eSJoseph Mingrone if (type == LINKADDR_ETHER && len == MAC_ADDR_LEN)
6783c602fabSXin LI return (etheraddr_string(ndo, ep));
67927df3f5dSRui Paulo
68027df3f5dSRui Paulo if (type == LINKADDR_FRELAY)
6818bdc5a62SPatrick Kelsey return (q922_string(ndo, ep, len));
682a1c2090eSBill Fenner
6833340d773SGleb Smirnoff tp = lookup_bytestring(ndo, ep, len);
6840bff6a5aSEd Maste if (tp->bs_name)
6850bff6a5aSEd Maste return (tp->bs_name);
686a1c2090eSBill Fenner
6870bff6a5aSEd Maste tp->bs_name = cp = (char *)malloc(len*3);
6880bff6a5aSEd Maste if (tp->bs_name == NULL)
689ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
690ee67461eSJoseph Mingrone "%s: malloc", __func__);
691ee67461eSJoseph Mingrone cp = octet_to_hex(cp, *ep++);
692a1c2090eSBill Fenner for (i = len-1; i > 0 ; --i) {
693a1c2090eSBill Fenner *cp++ = ':';
694ee67461eSJoseph Mingrone cp = octet_to_hex(cp, *ep++);
695a1c2090eSBill Fenner }
696a1c2090eSBill Fenner *cp = '\0';
6970bff6a5aSEd Maste return (tp->bs_name);
698a1c2090eSBill Fenner }
699a1c2090eSBill Fenner
700c1ad1296SSam Leffler #define ISONSAP_MAX_LENGTH 20
701a1c2090eSBill Fenner const char *
isonsap_string(netdissect_options * ndo,const uint8_t * nsap,u_int nsap_length)702ee67461eSJoseph Mingrone isonsap_string(netdissect_options *ndo, const uint8_t *nsap,
703ee67461eSJoseph Mingrone u_int nsap_length)
7044edb46e9SPaul Traina {
705ee67461eSJoseph Mingrone u_int nsap_idx;
706ee67461eSJoseph Mingrone char *cp;
707ee67461eSJoseph Mingrone struct enamemem *tp;
7084edb46e9SPaul Traina
709c1ad1296SSam Leffler if (nsap_length < 1 || nsap_length > ISONSAP_MAX_LENGTH)
71029292c17SSam Leffler return ("isonsap_string: illegal length");
711c1ad1296SSam Leffler
7123340d773SGleb Smirnoff tp = lookup_nsap(ndo, nsap, nsap_length);
7134edb46e9SPaul Traina if (tp->e_name)
7144edb46e9SPaul Traina return tp->e_name;
7154edb46e9SPaul Traina
716c1ad1296SSam Leffler tp->e_name = cp = (char *)malloc(sizeof("xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx"));
7174edb46e9SPaul Traina if (cp == NULL)
718ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
719ee67461eSJoseph Mingrone "%s: malloc", __func__);
7204edb46e9SPaul Traina
721c1ad1296SSam Leffler for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) {
722ee67461eSJoseph Mingrone cp = octet_to_hex(cp, *nsap++);
723c1ad1296SSam Leffler if (((nsap_idx & 1) == 0) &&
724c1ad1296SSam Leffler (nsap_idx + 1 < nsap_length)) {
72501bd0dbcSPaul Traina *cp++ = '.';
7264edb46e9SPaul Traina }
727c1ad1296SSam Leffler }
7284edb46e9SPaul Traina *cp = '\0';
7294edb46e9SPaul Traina return (tp->e_name);
7304edb46e9SPaul Traina }
7314edb46e9SPaul Traina
732a1c2090eSBill Fenner const char *
tcpport_string(netdissect_options * ndo,u_short port)7333340d773SGleb Smirnoff tcpport_string(netdissect_options *ndo, u_short port)
7344edb46e9SPaul Traina {
735ee67461eSJoseph Mingrone struct hnamemem *tp;
736ee67461eSJoseph Mingrone uint32_t i = port;
7374edb46e9SPaul Traina char buf[sizeof("00000")];
7384edb46e9SPaul Traina
7394edb46e9SPaul Traina for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
7404edb46e9SPaul Traina if (tp->addr == i)
7414edb46e9SPaul Traina return (tp->name);
7424edb46e9SPaul Traina
7434edb46e9SPaul Traina tp->addr = i;
7443340d773SGleb Smirnoff tp->nxt = newhnamemem(ndo);
7454edb46e9SPaul Traina
7467524a079SKris Kennaway (void)snprintf(buf, sizeof(buf), "%u", i);
747a1c2090eSBill Fenner tp->name = strdup(buf);
7483340d773SGleb Smirnoff if (tp->name == NULL)
749ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
750ee67461eSJoseph Mingrone "%s: strdup(buf)", __func__);
7514edb46e9SPaul Traina return (tp->name);
7524edb46e9SPaul Traina }
7534edb46e9SPaul Traina
754a1c2090eSBill Fenner const char *
udpport_string(netdissect_options * ndo,u_short port)755ee67461eSJoseph Mingrone udpport_string(netdissect_options *ndo, u_short port)
7564edb46e9SPaul Traina {
757ee67461eSJoseph Mingrone struct hnamemem *tp;
758ee67461eSJoseph Mingrone uint32_t i = port;
7594edb46e9SPaul Traina char buf[sizeof("00000")];
7604edb46e9SPaul Traina
7614edb46e9SPaul Traina for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
7624edb46e9SPaul Traina if (tp->addr == i)
7634edb46e9SPaul Traina return (tp->name);
7644edb46e9SPaul Traina
7654edb46e9SPaul Traina tp->addr = i;
7663340d773SGleb Smirnoff tp->nxt = newhnamemem(ndo);
7674edb46e9SPaul Traina
7687524a079SKris Kennaway (void)snprintf(buf, sizeof(buf), "%u", i);
769a1c2090eSBill Fenner tp->name = strdup(buf);
7703340d773SGleb Smirnoff if (tp->name == NULL)
771ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
772ee67461eSJoseph Mingrone "%s: strdup(buf)", __func__);
7734edb46e9SPaul Traina return (tp->name);
7744edb46e9SPaul Traina }
7754edb46e9SPaul Traina
776cc391cceSBruce M Simpson const char *
ipxsap_string(netdissect_options * ndo,u_short port)7773340d773SGleb Smirnoff ipxsap_string(netdissect_options *ndo, u_short port)
778cc391cceSBruce M Simpson {
779ee67461eSJoseph Mingrone char *cp;
780ee67461eSJoseph Mingrone struct hnamemem *tp;
781ee67461eSJoseph Mingrone uint32_t i = port;
782cc391cceSBruce M Simpson char buf[sizeof("0000")];
783cc391cceSBruce M Simpson
784cc391cceSBruce M Simpson for (tp = &ipxsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
785cc391cceSBruce M Simpson if (tp->addr == i)
786cc391cceSBruce M Simpson return (tp->name);
787cc391cceSBruce M Simpson
788cc391cceSBruce M Simpson tp->addr = i;
7893340d773SGleb Smirnoff tp->nxt = newhnamemem(ndo);
790cc391cceSBruce M Simpson
791cc391cceSBruce M Simpson cp = buf;
792ee67461eSJoseph Mingrone port = ntohs(port);
793cc391cceSBruce M Simpson *cp++ = hex[port >> 12 & 0xf];
794cc391cceSBruce M Simpson *cp++ = hex[port >> 8 & 0xf];
795cc391cceSBruce M Simpson *cp++ = hex[port >> 4 & 0xf];
796cc391cceSBruce M Simpson *cp++ = hex[port & 0xf];
797cc391cceSBruce M Simpson *cp++ = '\0';
798cc391cceSBruce M Simpson tp->name = strdup(buf);
7993340d773SGleb Smirnoff if (tp->name == NULL)
800ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
801ee67461eSJoseph Mingrone "%s: strdup(buf)", __func__);
802cc391cceSBruce M Simpson return (tp->name);
803cc391cceSBruce M Simpson }
804cc391cceSBruce M Simpson
8054edb46e9SPaul Traina static void
init_servarray(netdissect_options * ndo)8063c602fabSXin LI init_servarray(netdissect_options *ndo)
8074edb46e9SPaul Traina {
8084edb46e9SPaul Traina struct servent *sv;
809ee67461eSJoseph Mingrone struct hnamemem *table;
810ee67461eSJoseph Mingrone int i;
8114edb46e9SPaul Traina char buf[sizeof("0000000000")];
8124edb46e9SPaul Traina
8134edb46e9SPaul Traina while ((sv = getservent()) != NULL) {
8144edb46e9SPaul Traina int port = ntohs(sv->s_port);
8154edb46e9SPaul Traina i = port & (HASHNAMESIZE-1);
8164edb46e9SPaul Traina if (strcmp(sv->s_proto, "tcp") == 0)
8174edb46e9SPaul Traina table = &tporttable[i];
8184edb46e9SPaul Traina else if (strcmp(sv->s_proto, "udp") == 0)
8194edb46e9SPaul Traina table = &uporttable[i];
8204edb46e9SPaul Traina else
8214edb46e9SPaul Traina continue;
8224edb46e9SPaul Traina
8234edb46e9SPaul Traina while (table->name)
8244edb46e9SPaul Traina table = table->nxt;
8253c602fabSXin LI if (ndo->ndo_nflag) {
8267524a079SKris Kennaway (void)snprintf(buf, sizeof(buf), "%d", port);
827a1c2090eSBill Fenner table->name = strdup(buf);
8284edb46e9SPaul Traina } else
829a1c2090eSBill Fenner table->name = strdup(sv->s_name);
8303340d773SGleb Smirnoff if (table->name == NULL)
831ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
832ee67461eSJoseph Mingrone "%s: strdup", __func__);
8333340d773SGleb Smirnoff
8344edb46e9SPaul Traina table->addr = port;
8353340d773SGleb Smirnoff table->nxt = newhnamemem(ndo);
8364edb46e9SPaul Traina }
8374edb46e9SPaul Traina endservent();
8384edb46e9SPaul Traina }
8394edb46e9SPaul Traina
8403340d773SGleb Smirnoff static const struct eproto {
841c1ad1296SSam Leffler const char *s;
8424edb46e9SPaul Traina u_short p;
8433340d773SGleb Smirnoff } eproto_db[] = {
844ee67461eSJoseph Mingrone { "aarp", ETHERTYPE_AARP },
845ee67461eSJoseph Mingrone { "arp", ETHERTYPE_ARP },
846ee67461eSJoseph Mingrone { "atalk", ETHERTYPE_ATALK },
847ee67461eSJoseph Mingrone { "decnet", ETHERTYPE_DN },
8483340d773SGleb Smirnoff { "ip", ETHERTYPE_IP },
8493340d773SGleb Smirnoff { "ip6", ETHERTYPE_IPV6 },
850ee67461eSJoseph Mingrone { "lat", ETHERTYPE_LAT },
851ee67461eSJoseph Mingrone { "loopback", ETHERTYPE_LOOPBACK },
8523340d773SGleb Smirnoff { "mopdl", ETHERTYPE_MOPDL },
8533340d773SGleb Smirnoff { "moprc", ETHERTYPE_MOPRC },
854ee67461eSJoseph Mingrone { "rarp", ETHERTYPE_REVARP },
8553340d773SGleb Smirnoff { "sca", ETHERTYPE_SCA },
8563340d773SGleb Smirnoff { (char *)0, 0 }
8573340d773SGleb Smirnoff };
8584edb46e9SPaul Traina
8594edb46e9SPaul Traina static void
init_eprotoarray(netdissect_options * ndo)8603340d773SGleb Smirnoff init_eprotoarray(netdissect_options *ndo)
8614edb46e9SPaul Traina {
862ee67461eSJoseph Mingrone int i;
863ee67461eSJoseph Mingrone struct hnamemem *table;
8644edb46e9SPaul Traina
8654edb46e9SPaul Traina for (i = 0; eproto_db[i].s; i++) {
866cc391cceSBruce M Simpson int j = htons(eproto_db[i].p) & (HASHNAMESIZE-1);
8674edb46e9SPaul Traina table = &eprototable[j];
8684edb46e9SPaul Traina while (table->name)
8694edb46e9SPaul Traina table = table->nxt;
8704edb46e9SPaul Traina table->name = eproto_db[i].s;
871cc391cceSBruce M Simpson table->addr = htons(eproto_db[i].p);
8723340d773SGleb Smirnoff table->nxt = newhnamemem(ndo);
8734edb46e9SPaul Traina }
8744edb46e9SPaul Traina }
8754edb46e9SPaul Traina
87627df3f5dSRui Paulo static const struct protoidlist {
877a1c2090eSBill Fenner const u_char protoid[5];
878a1c2090eSBill Fenner const char *name;
879a1c2090eSBill Fenner } protoidlist[] = {
880a1c2090eSBill Fenner {{ 0x00, 0x00, 0x0c, 0x01, 0x07 }, "CiscoMLS" },
881a1c2090eSBill Fenner {{ 0x00, 0x00, 0x0c, 0x20, 0x00 }, "CiscoCDP" },
882a1c2090eSBill Fenner {{ 0x00, 0x00, 0x0c, 0x20, 0x01 }, "CiscoCGMP" },
883a1c2090eSBill Fenner {{ 0x00, 0x00, 0x0c, 0x20, 0x03 }, "CiscoVTP" },
884a1c2090eSBill Fenner {{ 0x00, 0xe0, 0x2b, 0x00, 0xbb }, "ExtremeEDP" },
885a1c2090eSBill Fenner {{ 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
886a1c2090eSBill Fenner };
887a1c2090eSBill Fenner
8884edb46e9SPaul Traina /*
8894edb46e9SPaul Traina * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
8904edb46e9SPaul Traina * types.
8914edb46e9SPaul Traina */
8924edb46e9SPaul Traina static void
init_protoidarray(netdissect_options * ndo)8933340d773SGleb Smirnoff init_protoidarray(netdissect_options *ndo)
8944edb46e9SPaul Traina {
895ee67461eSJoseph Mingrone int i;
896ee67461eSJoseph Mingrone struct protoidmem *tp;
89727df3f5dSRui Paulo const struct protoidlist *pl;
8984edb46e9SPaul Traina u_char protoid[5];
8994edb46e9SPaul Traina
9004edb46e9SPaul Traina protoid[0] = 0;
9014edb46e9SPaul Traina protoid[1] = 0;
9024edb46e9SPaul Traina protoid[2] = 0;
9034edb46e9SPaul Traina for (i = 0; eproto_db[i].s; i++) {
9044edb46e9SPaul Traina u_short etype = htons(eproto_db[i].p);
9054edb46e9SPaul Traina
9064edb46e9SPaul Traina memcpy((char *)&protoid[3], (char *)&etype, 2);
9073340d773SGleb Smirnoff tp = lookup_protoid(ndo, protoid);
908a1c2090eSBill Fenner tp->p_name = strdup(eproto_db[i].s);
9093340d773SGleb Smirnoff if (tp->p_name == NULL)
910ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
911ee67461eSJoseph Mingrone "%s: strdup(eproto_db[i].s)", __func__);
912a1c2090eSBill Fenner }
913a1c2090eSBill Fenner /* Hardwire some SNAP proto ID names */
914a1c2090eSBill Fenner for (pl = protoidlist; pl->name != NULL; ++pl) {
9153340d773SGleb Smirnoff tp = lookup_protoid(ndo, pl->protoid);
916a1c2090eSBill Fenner /* Don't override existing name */
917a1c2090eSBill Fenner if (tp->p_name != NULL)
918a1c2090eSBill Fenner continue;
919a1c2090eSBill Fenner
920a1c2090eSBill Fenner tp->p_name = pl->name;
9214edb46e9SPaul Traina }
9224edb46e9SPaul Traina }
9234edb46e9SPaul Traina
92427df3f5dSRui Paulo static const struct etherlist {
925ee67461eSJoseph Mingrone const nd_mac_addr addr;
926a1c2090eSBill Fenner const char *name;
9274edb46e9SPaul Traina } etherlist[] = {
9284edb46e9SPaul Traina {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
9294edb46e9SPaul Traina {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
9304edb46e9SPaul Traina };
9314edb46e9SPaul Traina
9324edb46e9SPaul Traina /*
9334edb46e9SPaul Traina * Initialize the ethers hash table. We take two different approaches
9344edb46e9SPaul Traina * depending on whether or not the system provides the ethers name
9354edb46e9SPaul Traina * service. If it does, we just wire in a few names at startup,
9364edb46e9SPaul Traina * and etheraddr_string() fills in the table on demand. If it doesn't,
9374edb46e9SPaul Traina * then we suck in the entire /etc/ethers file at startup. The idea
9384edb46e9SPaul Traina * is that parsing the local file will be fast, but spinning through
9394edb46e9SPaul Traina * all the ethers entries via NIS & next_etherent might be very slow.
9404edb46e9SPaul Traina *
9414edb46e9SPaul Traina * XXX pcap_next_etherent doesn't belong in the pcap interface, but
9424edb46e9SPaul Traina * since the pcap module already does name-to-address translation,
9434edb46e9SPaul Traina * it's already does most of the work for the ethernet address-to-name
9444edb46e9SPaul Traina * translation, so we just pcap_next_etherent as a convenience.
9454edb46e9SPaul Traina */
9464edb46e9SPaul Traina static void
init_etherarray(netdissect_options * ndo)9473340d773SGleb Smirnoff init_etherarray(netdissect_options *ndo)
9484edb46e9SPaul Traina {
949ee67461eSJoseph Mingrone const struct etherlist *el;
950ee67461eSJoseph Mingrone struct enamemem *tp;
951a1c2090eSBill Fenner #ifdef USE_ETHER_NTOHOST
9524edb46e9SPaul Traina char name[256];
9534edb46e9SPaul Traina #else
954ee67461eSJoseph Mingrone struct pcap_etherent *ep;
955ee67461eSJoseph Mingrone FILE *fp;
9564edb46e9SPaul Traina
9574edb46e9SPaul Traina /* Suck in entire ethers file */
9584edb46e9SPaul Traina fp = fopen(PCAP_ETHERS_FILE, "r");
9594edb46e9SPaul Traina if (fp != NULL) {
9604edb46e9SPaul Traina while ((ep = pcap_next_etherent(fp)) != NULL) {
9613340d773SGleb Smirnoff tp = lookup_emem(ndo, ep->addr);
962a1c2090eSBill Fenner tp->e_name = strdup(ep->name);
9633340d773SGleb Smirnoff if (tp->e_name == NULL)
964ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
965ee67461eSJoseph Mingrone "%s: strdup(ep->addr)", __func__);
9664edb46e9SPaul Traina }
9674edb46e9SPaul Traina (void)fclose(fp);
9684edb46e9SPaul Traina }
9694edb46e9SPaul Traina #endif
9704edb46e9SPaul Traina
9714edb46e9SPaul Traina /* Hardwire some ethernet names */
9724edb46e9SPaul Traina for (el = etherlist; el->name != NULL; ++el) {
9733340d773SGleb Smirnoff tp = lookup_emem(ndo, el->addr);
9744edb46e9SPaul Traina /* Don't override existing name */
9754edb46e9SPaul Traina if (tp->e_name != NULL)
9764edb46e9SPaul Traina continue;
9774edb46e9SPaul Traina
978a1c2090eSBill Fenner #ifdef USE_ETHER_NTOHOST
979c1ad1296SSam Leffler /*
980c1ad1296SSam Leffler * Use YP/NIS version of name if available.
981c1ad1296SSam Leffler */
982ee67461eSJoseph Mingrone /* Same workaround as in etheraddr_string(). */
983ee67461eSJoseph Mingrone struct ether_addr ea;
984ee67461eSJoseph Mingrone memcpy (&ea, el->addr, MAC_ADDR_LEN);
985ee67461eSJoseph Mingrone if (ether_ntohost(name, &ea) == 0) {
986a1c2090eSBill Fenner tp->e_name = strdup(name);
9873340d773SGleb Smirnoff if (tp->e_name == NULL)
988ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
989ee67461eSJoseph Mingrone "%s: strdup(name)", __func__);
9904edb46e9SPaul Traina continue;
9914edb46e9SPaul Traina }
9924edb46e9SPaul Traina #endif
9934edb46e9SPaul Traina tp->e_name = el->name;
9944edb46e9SPaul Traina }
9954edb46e9SPaul Traina }
9964edb46e9SPaul Traina
997ee67461eSJoseph Mingrone static const struct ipxsap_ent {
998ee67461eSJoseph Mingrone uint16_t v;
999ee67461eSJoseph Mingrone const char *s;
1000ee67461eSJoseph Mingrone } ipxsap_db[] = {
1001cc391cceSBruce M Simpson { 0x0000, "Unknown" },
1002cc391cceSBruce M Simpson { 0x0001, "User" },
1003cc391cceSBruce M Simpson { 0x0002, "User Group" },
1004cc391cceSBruce M Simpson { 0x0003, "PrintQueue" },
1005cc391cceSBruce M Simpson { 0x0004, "FileServer" },
1006cc391cceSBruce M Simpson { 0x0005, "JobServer" },
1007cc391cceSBruce M Simpson { 0x0006, "Gateway" },
1008cc391cceSBruce M Simpson { 0x0007, "PrintServer" },
1009cc391cceSBruce M Simpson { 0x0008, "ArchiveQueue" },
1010cc391cceSBruce M Simpson { 0x0009, "ArchiveServer" },
1011cc391cceSBruce M Simpson { 0x000a, "JobQueue" },
1012cc391cceSBruce M Simpson { 0x000b, "Administration" },
1013cc391cceSBruce M Simpson { 0x000F, "Novell TI-RPC" },
1014cc391cceSBruce M Simpson { 0x0017, "Diagnostics" },
1015cc391cceSBruce M Simpson { 0x0020, "NetBIOS" },
1016cc391cceSBruce M Simpson { 0x0021, "NAS SNA Gateway" },
1017cc391cceSBruce M Simpson { 0x0023, "NACS AsyncGateway" },
1018cc391cceSBruce M Simpson { 0x0024, "RemoteBridge/RoutingService" },
1019cc391cceSBruce M Simpson { 0x0026, "BridgeServer" },
1020cc391cceSBruce M Simpson { 0x0027, "TCP/IP Gateway" },
1021cc391cceSBruce M Simpson { 0x0028, "Point-to-point X.25 BridgeServer" },
1022cc391cceSBruce M Simpson { 0x0029, "3270 Gateway" },
1023cc391cceSBruce M Simpson { 0x002a, "CHI Corp" },
1024cc391cceSBruce M Simpson { 0x002c, "PC Chalkboard" },
1025cc391cceSBruce M Simpson { 0x002d, "TimeSynchServer" },
1026cc391cceSBruce M Simpson { 0x002e, "ARCserve5.0/PalindromeBackup" },
1027cc391cceSBruce M Simpson { 0x0045, "DI3270 Gateway" },
1028cc391cceSBruce M Simpson { 0x0047, "AdvertisingPrintServer" },
1029cc391cceSBruce M Simpson { 0x004a, "NetBlazerModems" },
1030cc391cceSBruce M Simpson { 0x004b, "BtrieveVAP" },
1031cc391cceSBruce M Simpson { 0x004c, "NetwareSQL" },
1032cc391cceSBruce M Simpson { 0x004d, "XtreeNetwork" },
1033cc391cceSBruce M Simpson { 0x0050, "BtrieveVAP4.11" },
1034cc391cceSBruce M Simpson { 0x0052, "QuickLink" },
1035cc391cceSBruce M Simpson { 0x0053, "PrintQueueUser" },
1036cc391cceSBruce M Simpson { 0x0058, "Multipoint X.25 Router" },
1037cc391cceSBruce M Simpson { 0x0060, "STLB/NLM" },
1038cc391cceSBruce M Simpson { 0x0064, "ARCserve" },
1039cc391cceSBruce M Simpson { 0x0066, "ARCserve3.0" },
1040cc391cceSBruce M Simpson { 0x0072, "WAN CopyUtility" },
1041cc391cceSBruce M Simpson { 0x007a, "TES-NetwareVMS" },
1042cc391cceSBruce M Simpson { 0x0092, "WATCOM Debugger/EmeraldTapeBackupServer" },
1043cc391cceSBruce M Simpson { 0x0095, "DDA OBGYN" },
1044cc391cceSBruce M Simpson { 0x0098, "NetwareAccessServer" },
1045cc391cceSBruce M Simpson { 0x009a, "Netware for VMS II/NamedPipeServer" },
1046cc391cceSBruce M Simpson { 0x009b, "NetwareAccessServer" },
1047cc391cceSBruce M Simpson { 0x009e, "PortableNetwareServer/SunLinkNVT" },
1048cc391cceSBruce M Simpson { 0x00a1, "PowerchuteAPC UPS" },
1049cc391cceSBruce M Simpson { 0x00aa, "LAWserve" },
1050cc391cceSBruce M Simpson { 0x00ac, "CompaqIDA StatusMonitor" },
1051cc391cceSBruce M Simpson { 0x0100, "PIPE STAIL" },
1052cc391cceSBruce M Simpson { 0x0102, "LAN ProtectBindery" },
1053cc391cceSBruce M Simpson { 0x0103, "OracleDataBaseServer" },
1054cc391cceSBruce M Simpson { 0x0107, "Netware386/RSPX RemoteConsole" },
1055cc391cceSBruce M Simpson { 0x010f, "NovellSNA Gateway" },
1056cc391cceSBruce M Simpson { 0x0111, "TestServer" },
1057cc391cceSBruce M Simpson { 0x0112, "HP PrintServer" },
1058cc391cceSBruce M Simpson { 0x0114, "CSA MUX" },
1059cc391cceSBruce M Simpson { 0x0115, "CSA LCA" },
1060cc391cceSBruce M Simpson { 0x0116, "CSA CM" },
1061cc391cceSBruce M Simpson { 0x0117, "CSA SMA" },
1062cc391cceSBruce M Simpson { 0x0118, "CSA DBA" },
1063cc391cceSBruce M Simpson { 0x0119, "CSA NMA" },
1064cc391cceSBruce M Simpson { 0x011a, "CSA SSA" },
1065cc391cceSBruce M Simpson { 0x011b, "CSA STATUS" },
1066cc391cceSBruce M Simpson { 0x011e, "CSA APPC" },
1067cc391cceSBruce M Simpson { 0x0126, "SNA TEST SSA Profile" },
1068cc391cceSBruce M Simpson { 0x012a, "CSA TRACE" },
1069cc391cceSBruce M Simpson { 0x012b, "NetwareSAA" },
1070cc391cceSBruce M Simpson { 0x012e, "IKARUS VirusScan" },
1071cc391cceSBruce M Simpson { 0x0130, "CommunicationsExecutive" },
1072cc391cceSBruce M Simpson { 0x0133, "NNS DomainServer/NetwareNamingServicesDomain" },
1073cc391cceSBruce M Simpson { 0x0135, "NetwareNamingServicesProfile" },
1074cc391cceSBruce M Simpson { 0x0137, "Netware386 PrintQueue/NNS PrintQueue" },
1075cc391cceSBruce M Simpson { 0x0141, "LAN SpoolServer" },
1076cc391cceSBruce M Simpson { 0x0152, "IRMALAN Gateway" },
1077cc391cceSBruce M Simpson { 0x0154, "NamedPipeServer" },
1078cc391cceSBruce M Simpson { 0x0166, "NetWareManagement" },
1079cc391cceSBruce M Simpson { 0x0168, "Intel PICKIT CommServer/Intel CAS TalkServer" },
1080cc391cceSBruce M Simpson { 0x0173, "Compaq" },
1081cc391cceSBruce M Simpson { 0x0174, "Compaq SNMP Agent" },
1082cc391cceSBruce M Simpson { 0x0175, "Compaq" },
1083cc391cceSBruce M Simpson { 0x0180, "XTreeServer/XTreeTools" },
1084cc391cceSBruce M Simpson { 0x018A, "NASI ServicesBroadcastServer" },
1085cc391cceSBruce M Simpson { 0x01b0, "GARP Gateway" },
1086cc391cceSBruce M Simpson { 0x01b1, "Binfview" },
1087cc391cceSBruce M Simpson { 0x01bf, "IntelLanDeskManager" },
1088cc391cceSBruce M Simpson { 0x01ca, "AXTEC" },
1089cc391cceSBruce M Simpson { 0x01cb, "ShivaNetModem/E" },
1090cc391cceSBruce M Simpson { 0x01cc, "ShivaLanRover/E" },
1091cc391cceSBruce M Simpson { 0x01cd, "ShivaLanRover/T" },
1092cc391cceSBruce M Simpson { 0x01ce, "ShivaUniversal" },
1093cc391cceSBruce M Simpson { 0x01d8, "CastelleFAXPressServer" },
1094cc391cceSBruce M Simpson { 0x01da, "CastelleLANPressPrintServer" },
1095cc391cceSBruce M Simpson { 0x01dc, "CastelleFAX/Xerox7033 FaxServer/ExcelLanFax" },
1096cc391cceSBruce M Simpson { 0x01f0, "LEGATO" },
1097cc391cceSBruce M Simpson { 0x01f5, "LEGATO" },
1098cc391cceSBruce M Simpson { 0x0233, "NMS Agent/NetwareManagementAgent" },
1099cc391cceSBruce M Simpson { 0x0237, "NMS IPX Discovery/LANternReadWriteChannel" },
1100cc391cceSBruce M Simpson { 0x0238, "NMS IP Discovery/LANternTrapAlarmChannel" },
1101cc391cceSBruce M Simpson { 0x023a, "LANtern" },
1102cc391cceSBruce M Simpson { 0x023c, "MAVERICK" },
1103cc391cceSBruce M Simpson { 0x023f, "NovellSMDR" },
1104cc391cceSBruce M Simpson { 0x024e, "NetwareConnect" },
1105cc391cceSBruce M Simpson { 0x024f, "NASI ServerBroadcast Cisco" },
1106cc391cceSBruce M Simpson { 0x026a, "NMS ServiceConsole" },
1107cc391cceSBruce M Simpson { 0x026b, "TimeSynchronizationServer Netware 4.x" },
1108cc391cceSBruce M Simpson { 0x0278, "DirectoryServer Netware 4.x" },
1109cc391cceSBruce M Simpson { 0x027b, "NetwareManagementAgent" },
1110cc391cceSBruce M Simpson { 0x0280, "Novell File and Printer Sharing Service for PC" },
1111cc391cceSBruce M Simpson { 0x0304, "NovellSAA Gateway" },
1112cc391cceSBruce M Simpson { 0x0308, "COM/VERMED" },
1113cc391cceSBruce M Simpson { 0x030a, "GalacticommWorldgroupServer" },
1114cc391cceSBruce M Simpson { 0x030c, "IntelNetport2/HP JetDirect/HP Quicksilver" },
1115cc391cceSBruce M Simpson { 0x0320, "AttachmateGateway" },
1116*0a7e5f1fSJoseph Mingrone { 0x0327, "MicrosoftDiagnostics" },
1117cc391cceSBruce M Simpson { 0x0328, "WATCOM SQL Server" },
1118cc391cceSBruce M Simpson { 0x0335, "MultiTechSystems MultisynchCommServer" },
1119cc391cceSBruce M Simpson { 0x0343, "Xylogics RemoteAccessServer/LANModem" },
1120cc391cceSBruce M Simpson { 0x0355, "ArcadaBackupExec" },
1121cc391cceSBruce M Simpson { 0x0358, "MSLCD1" },
1122cc391cceSBruce M Simpson { 0x0361, "NETINELO" },
1123cc391cceSBruce M Simpson { 0x037e, "Powerchute UPS Monitoring" },
1124cc391cceSBruce M Simpson { 0x037f, "ViruSafeNotify" },
1125cc391cceSBruce M Simpson { 0x0386, "HP Bridge" },
1126cc391cceSBruce M Simpson { 0x0387, "HP Hub" },
1127cc391cceSBruce M Simpson { 0x0394, "NetWare SAA Gateway" },
1128cc391cceSBruce M Simpson { 0x039b, "LotusNotes" },
1129cc391cceSBruce M Simpson { 0x03b7, "CertusAntiVirus" },
1130cc391cceSBruce M Simpson { 0x03c4, "ARCserve4.0" },
1131cc391cceSBruce M Simpson { 0x03c7, "LANspool3.5" },
1132cc391cceSBruce M Simpson { 0x03d7, "LexmarkPrinterServer" },
1133cc391cceSBruce M Simpson { 0x03d8, "LexmarkXLE PrinterServer" },
1134cc391cceSBruce M Simpson { 0x03dd, "BanyanENS NetwareClient" },
1135cc391cceSBruce M Simpson { 0x03de, "GuptaSequelBaseServer/NetWareSQL" },
1136cc391cceSBruce M Simpson { 0x03e1, "UnivelUnixware" },
1137cc391cceSBruce M Simpson { 0x03e4, "UnivelUnixware" },
1138cc391cceSBruce M Simpson { 0x03fc, "IntelNetport" },
1139cc391cceSBruce M Simpson { 0x03fd, "PrintServerQueue" },
1140cc391cceSBruce M Simpson { 0x040A, "ipnServer" },
1141cc391cceSBruce M Simpson { 0x040D, "LVERRMAN" },
1142cc391cceSBruce M Simpson { 0x040E, "LVLIC" },
1143cc391cceSBruce M Simpson { 0x0414, "NET Silicon (DPI)/Kyocera" },
1144cc391cceSBruce M Simpson { 0x0429, "SiteLockVirus" },
1145cc391cceSBruce M Simpson { 0x0432, "UFHELPR???" },
1146cc391cceSBruce M Simpson { 0x0433, "Synoptics281xAdvancedSNMPAgent" },
1147cc391cceSBruce M Simpson { 0x0444, "MicrosoftNT SNA Server" },
1148cc391cceSBruce M Simpson { 0x0448, "Oracle" },
1149cc391cceSBruce M Simpson { 0x044c, "ARCserve5.01" },
1150cc391cceSBruce M Simpson { 0x0457, "CanonGP55" },
1151cc391cceSBruce M Simpson { 0x045a, "QMS Printers" },
1152cc391cceSBruce M Simpson { 0x045b, "DellSCSI Array" },
1153cc391cceSBruce M Simpson { 0x0491, "NetBlazerModems" },
1154cc391cceSBruce M Simpson { 0x04ac, "OnTimeScheduler" },
1155cc391cceSBruce M Simpson { 0x04b0, "CD-Net" },
1156cc391cceSBruce M Simpson { 0x0513, "EmulexNQA" },
1157cc391cceSBruce M Simpson { 0x0520, "SiteLockChecks" },
1158cc391cceSBruce M Simpson { 0x0529, "SiteLockChecks" },
1159cc391cceSBruce M Simpson { 0x052d, "CitrixOS2 AppServer" },
1160cc391cceSBruce M Simpson { 0x0535, "Tektronix" },
1161cc391cceSBruce M Simpson { 0x0536, "Milan" },
1162cc391cceSBruce M Simpson { 0x055d, "Attachmate SNA gateway" },
1163cc391cceSBruce M Simpson { 0x056b, "IBM8235 ModemServer" },
1164cc391cceSBruce M Simpson { 0x056c, "ShivaLanRover/E PLUS" },
1165cc391cceSBruce M Simpson { 0x056d, "ShivaLanRover/T PLUS" },
1166cc391cceSBruce M Simpson { 0x0580, "McAfeeNetShield" },
1167cc391cceSBruce M Simpson { 0x05B8, "NLM to workstation communication (Revelation Software)" },
1168cc391cceSBruce M Simpson { 0x05BA, "CompatibleSystemsRouters" },
1169cc391cceSBruce M Simpson { 0x05BE, "CheyenneHierarchicalStorageManager" },
1170cc391cceSBruce M Simpson { 0x0606, "JCWatermarkImaging" },
1171cc391cceSBruce M Simpson { 0x060c, "AXISNetworkPrinter" },
1172cc391cceSBruce M Simpson { 0x0610, "AdaptecSCSIManagement" },
1173cc391cceSBruce M Simpson { 0x0621, "IBM AntiVirus" },
1174cc391cceSBruce M Simpson { 0x0640, "Windows95 RemoteRegistryService" },
1175cc391cceSBruce M Simpson { 0x064e, "MicrosoftIIS" },
1176cc391cceSBruce M Simpson { 0x067b, "Microsoft Win95/98 File and Print Sharing for NetWare" },
1177cc391cceSBruce M Simpson { 0x067c, "Microsoft Win95/98 File and Print Sharing for NetWare" },
1178cc391cceSBruce M Simpson { 0x076C, "Xerox" },
1179cc391cceSBruce M Simpson { 0x079b, "ShivaLanRover/E 115" },
1180cc391cceSBruce M Simpson { 0x079c, "ShivaLanRover/T 115" },
1181cc391cceSBruce M Simpson { 0x07B4, "CubixWorldDesk" },
1182cc391cceSBruce M Simpson { 0x07c2, "Quarterdeck IWare Connect V2.x NLM" },
1183cc391cceSBruce M Simpson { 0x07c1, "Quarterdeck IWare Connect V3.x NLM" },
1184cc391cceSBruce M Simpson { 0x0810, "ELAN License Server Demo" },
1185cc391cceSBruce M Simpson { 0x0824, "ShivaLanRoverAccessSwitch/E" },
1186cc391cceSBruce M Simpson { 0x086a, "ISSC Collector" },
1187cc391cceSBruce M Simpson { 0x087f, "ISSC DAS AgentAIX" },
1188cc391cceSBruce M Simpson { 0x0880, "Intel Netport PRO" },
1189cc391cceSBruce M Simpson { 0x0881, "Intel Netport PRO" },
1190cc391cceSBruce M Simpson { 0x0b29, "SiteLock" },
1191cc391cceSBruce M Simpson { 0x0c29, "SiteLockApplications" },
1192cc391cceSBruce M Simpson { 0x0c2c, "LicensingServer" },
1193cc391cceSBruce M Simpson { 0x2101, "PerformanceTechnologyInstantInternet" },
1194cc391cceSBruce M Simpson { 0x2380, "LAI SiteLock" },
1195cc391cceSBruce M Simpson { 0x238c, "MeetingMaker" },
1196cc391cceSBruce M Simpson { 0x4808, "SiteLockServer/SiteLockMetering" },
1197cc391cceSBruce M Simpson { 0x5555, "SiteLockUser" },
1198cc391cceSBruce M Simpson { 0x6312, "Tapeware" },
1199cc391cceSBruce M Simpson { 0x6f00, "RabbitGateway" },
1200cc391cceSBruce M Simpson { 0x7703, "MODEM" },
1201cc391cceSBruce M Simpson { 0x8002, "NetPortPrinters" },
1202cc391cceSBruce M Simpson { 0x8008, "WordPerfectNetworkVersion" },
1203cc391cceSBruce M Simpson { 0x85BE, "Cisco EIGRP" },
1204cc391cceSBruce M Simpson { 0x8888, "WordPerfectNetworkVersion/QuickNetworkManagement" },
1205cc391cceSBruce M Simpson { 0x9000, "McAfeeNetShield" },
1206cc391cceSBruce M Simpson { 0x9604, "CSA-NT_MON" },
1207cc391cceSBruce M Simpson { 0xb6a8, "OceanIsleReachoutRemoteControl" },
1208cc391cceSBruce M Simpson { 0xf11f, "SiteLockMetering" },
1209cc391cceSBruce M Simpson { 0xf1ff, "SiteLock" },
1210cc391cceSBruce M Simpson { 0xf503, "Microsoft SQL Server" },
1211cc391cceSBruce M Simpson { 0xF905, "IBM TimeAndPlace" },
1212cc391cceSBruce M Simpson { 0xfbfb, "TopCallIII FaxServer" },
1213cc391cceSBruce M Simpson { 0xffff, "AnyService/Wildcard" },
1214cc391cceSBruce M Simpson { 0, (char *)0 }
1215cc391cceSBruce M Simpson };
1216cc391cceSBruce M Simpson
1217cc391cceSBruce M Simpson static void
init_ipxsaparray(netdissect_options * ndo)12183340d773SGleb Smirnoff init_ipxsaparray(netdissect_options *ndo)
1219cc391cceSBruce M Simpson {
1220ee67461eSJoseph Mingrone int i;
1221ee67461eSJoseph Mingrone struct hnamemem *table;
1222cc391cceSBruce M Simpson
1223cc391cceSBruce M Simpson for (i = 0; ipxsap_db[i].s != NULL; i++) {
1224ee67461eSJoseph Mingrone u_int j = htons(ipxsap_db[i].v) & (HASHNAMESIZE-1);
1225cc391cceSBruce M Simpson table = &ipxsaptable[j];
1226cc391cceSBruce M Simpson while (table->name)
1227cc391cceSBruce M Simpson table = table->nxt;
1228cc391cceSBruce M Simpson table->name = ipxsap_db[i].s;
1229cc391cceSBruce M Simpson table->addr = htons(ipxsap_db[i].v);
12303340d773SGleb Smirnoff table->nxt = newhnamemem(ndo);
1231cc391cceSBruce M Simpson }
1232cc391cceSBruce M Simpson }
1233cc391cceSBruce M Simpson
12344edb46e9SPaul Traina /*
12354edb46e9SPaul Traina * Initialize the address to name translation machinery. We map all
12363c602fabSXin LI * non-local IP addresses to numeric addresses if ndo->ndo_fflag is true
12373c602fabSXin LI * (i.e., to prevent blocking on the nameserver). localnet is the IP address
12384edb46e9SPaul Traina * of the local network. mask is its subnet mask.
12394edb46e9SPaul Traina */
12404edb46e9SPaul Traina void
init_addrtoname(netdissect_options * ndo,uint32_t localnet,uint32_t mask)12413c602fabSXin LI init_addrtoname(netdissect_options *ndo, uint32_t localnet, uint32_t mask)
12424edb46e9SPaul Traina {
12433c602fabSXin LI if (ndo->ndo_fflag) {
12444edb46e9SPaul Traina f_localnet = localnet;
12454edb46e9SPaul Traina f_netmask = mask;
12464edb46e9SPaul Traina }
12473c602fabSXin LI if (ndo->ndo_nflag)
12484edb46e9SPaul Traina /*
12494edb46e9SPaul Traina * Simplest way to suppress names.
12504edb46e9SPaul Traina */
12514edb46e9SPaul Traina return;
12524edb46e9SPaul Traina
12533340d773SGleb Smirnoff init_etherarray(ndo);
12543c602fabSXin LI init_servarray(ndo);
12553340d773SGleb Smirnoff init_eprotoarray(ndo);
12563340d773SGleb Smirnoff init_protoidarray(ndo);
12573340d773SGleb Smirnoff init_ipxsaparray(ndo);
12584edb46e9SPaul Traina }
12594edb46e9SPaul Traina
1260a1c2090eSBill Fenner const char *
dnaddr_string(netdissect_options * ndo,u_short dnaddr)12613c602fabSXin LI dnaddr_string(netdissect_options *ndo, u_short dnaddr)
12624edb46e9SPaul Traina {
1263ee67461eSJoseph Mingrone struct hnamemem *tp;
12644edb46e9SPaul Traina
12653340d773SGleb Smirnoff for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != NULL;
12664edb46e9SPaul Traina tp = tp->nxt)
12674edb46e9SPaul Traina if (tp->addr == dnaddr)
12684edb46e9SPaul Traina return (tp->name);
12694edb46e9SPaul Traina
12704edb46e9SPaul Traina tp->addr = dnaddr;
12713340d773SGleb Smirnoff tp->nxt = newhnamemem(ndo);
12723340d773SGleb Smirnoff tp->name = dnnum_string(ndo, dnaddr);
12734edb46e9SPaul Traina
12744edb46e9SPaul Traina return(tp->name);
12754edb46e9SPaul Traina }
12764edb46e9SPaul Traina
12774edb46e9SPaul Traina /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
12784edb46e9SPaul Traina struct hnamemem *
newhnamemem(netdissect_options * ndo)12793340d773SGleb Smirnoff newhnamemem(netdissect_options *ndo)
12804edb46e9SPaul Traina {
1281ee67461eSJoseph Mingrone struct hnamemem *p;
12824edb46e9SPaul Traina static struct hnamemem *ptr = NULL;
12834edb46e9SPaul Traina static u_int num = 0;
12844edb46e9SPaul Traina
1285ee67461eSJoseph Mingrone if (num == 0) {
12864edb46e9SPaul Traina num = 64;
12874edb46e9SPaul Traina ptr = (struct hnamemem *)calloc(num, sizeof (*ptr));
12884edb46e9SPaul Traina if (ptr == NULL)
1289ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
1290ee67461eSJoseph Mingrone "%s: calloc", __func__);
12914edb46e9SPaul Traina }
12924edb46e9SPaul Traina --num;
12934edb46e9SPaul Traina p = ptr++;
12944edb46e9SPaul Traina return (p);
12954edb46e9SPaul Traina }
1296a88113a8SBill Fenner
1297a88113a8SBill Fenner /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */
1298a88113a8SBill Fenner struct h6namemem *
newh6namemem(netdissect_options * ndo)12993340d773SGleb Smirnoff newh6namemem(netdissect_options *ndo)
1300a88113a8SBill Fenner {
1301ee67461eSJoseph Mingrone struct h6namemem *p;
1302a88113a8SBill Fenner static struct h6namemem *ptr = NULL;
1303a88113a8SBill Fenner static u_int num = 0;
1304a88113a8SBill Fenner
1305ee67461eSJoseph Mingrone if (num == 0) {
1306a88113a8SBill Fenner num = 64;
1307a88113a8SBill Fenner ptr = (struct h6namemem *)calloc(num, sizeof (*ptr));
1308a88113a8SBill Fenner if (ptr == NULL)
1309ee67461eSJoseph Mingrone (*ndo->ndo_error)(ndo, S_ERR_ND_MEM_ALLOC,
1310ee67461eSJoseph Mingrone "%s: calloc", __func__);
1311a88113a8SBill Fenner }
1312a88113a8SBill Fenner --num;
1313a88113a8SBill Fenner p = ptr++;
1314a88113a8SBill Fenner return (p);
1315a88113a8SBill Fenner }
13168bdc5a62SPatrick Kelsey
13178bdc5a62SPatrick Kelsey /* Represent TCI part of the 802.1Q 4-octet tag as text. */
13188bdc5a62SPatrick Kelsey const char *
ieee8021q_tci_string(const uint16_t tci)13198bdc5a62SPatrick Kelsey ieee8021q_tci_string(const uint16_t tci)
13208bdc5a62SPatrick Kelsey {
13218bdc5a62SPatrick Kelsey static char buf[128];
13228bdc5a62SPatrick Kelsey snprintf(buf, sizeof(buf), "vlan %u, p %u%s",
13238bdc5a62SPatrick Kelsey tci & 0xfff,
13248bdc5a62SPatrick Kelsey tci >> 13,
13258bdc5a62SPatrick Kelsey (tci & 0x1000) ? ", DEI" : "");
13268bdc5a62SPatrick Kelsey return buf;
13278bdc5a62SPatrick Kelsey }
1328