xref: /freebsd/contrib/tcpdump/addrtoname.c (revision 7524a0790d23f2ecfad3e98c058f58d7dc01a655)
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
23a88113a8SBill Fenner  *
24a88113a8SBill Fenner  * $FreeBSD$
254edb46e9SPaul Traina  */
264edb46e9SPaul Traina #ifndef lint
272ebf6c05SBill Fenner static const char rcsid[] =
28a88113a8SBill Fenner     "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.64 1999/11/21 09:36:44 fenner Exp $ (LBL)";
29a88113a8SBill Fenner #endif
30a88113a8SBill Fenner 
31a88113a8SBill Fenner #ifdef HAVE_CONFIG_H
32a88113a8SBill Fenner #include "config.h"
334edb46e9SPaul Traina #endif
344edb46e9SPaul Traina 
354edb46e9SPaul Traina #include <sys/types.h>
364edb46e9SPaul Traina #include <sys/socket.h>
374edb46e9SPaul Traina #include <sys/time.h>
384edb46e9SPaul Traina 
394edb46e9SPaul Traina #if __STDC__
404edb46e9SPaul Traina struct mbuf;
414edb46e9SPaul Traina struct rtentry;
424edb46e9SPaul Traina #endif
434edb46e9SPaul Traina #include <net/if.h>
444edb46e9SPaul Traina 
454edb46e9SPaul Traina #include <netinet/in.h>
46ee3e7633SGarrett Wollman #include <net/ethernet.h>
474edb46e9SPaul Traina 
48a88113a8SBill Fenner #ifdef INET6
49bb1ba417SBill Fenner #include <netinet/ip6.h>
50a88113a8SBill Fenner #endif
51a88113a8SBill Fenner 
524edb46e9SPaul Traina #include <arpa/inet.h>
534edb46e9SPaul Traina 
544edb46e9SPaul Traina #include <ctype.h>
554edb46e9SPaul Traina #include <netdb.h>
564edb46e9SPaul Traina #include <pcap.h>
574edb46e9SPaul Traina #include <pcap-namedb.h>
58699fc314SBill Fenner #ifdef HAVE_MALLOC_H
59699fc314SBill Fenner #include <malloc.h>
60699fc314SBill Fenner #endif
61699fc314SBill Fenner #ifdef HAVE_MEMORY_H
62699fc314SBill Fenner #include <memory.h>
63699fc314SBill Fenner #endif
644edb46e9SPaul Traina #include <signal.h>
654edb46e9SPaul Traina #include <stdio.h>
664edb46e9SPaul Traina #include <string.h>
674edb46e9SPaul Traina #include <stdlib.h>
684edb46e9SPaul Traina #include <unistd.h>
694edb46e9SPaul Traina 
704edb46e9SPaul Traina #include "interface.h"
714edb46e9SPaul Traina #include "addrtoname.h"
724edb46e9SPaul Traina #include "llc.h"
73699fc314SBill Fenner #include "savestr.h"
74699fc314SBill Fenner #include "setsignal.h"
754edb46e9SPaul Traina 
764edb46e9SPaul Traina /* Forwards */
774edb46e9SPaul Traina static RETSIGTYPE nohostname(int);
784edb46e9SPaul Traina 
794edb46e9SPaul Traina /*
804edb46e9SPaul Traina  * hash tables for whatever-to-name translations
814edb46e9SPaul Traina  */
824edb46e9SPaul Traina 
834edb46e9SPaul Traina #define HASHNAMESIZE 4096
844edb46e9SPaul Traina 
854edb46e9SPaul Traina struct hnamemem {
864edb46e9SPaul Traina 	u_int32_t addr;
874edb46e9SPaul Traina 	char *name;
884edb46e9SPaul Traina 	struct hnamemem *nxt;
894edb46e9SPaul Traina };
904edb46e9SPaul Traina 
914edb46e9SPaul Traina struct hnamemem hnametable[HASHNAMESIZE];
924edb46e9SPaul Traina struct hnamemem tporttable[HASHNAMESIZE];
934edb46e9SPaul Traina struct hnamemem uporttable[HASHNAMESIZE];
944edb46e9SPaul Traina struct hnamemem eprototable[HASHNAMESIZE];
954edb46e9SPaul Traina struct hnamemem dnaddrtable[HASHNAMESIZE];
964edb46e9SPaul Traina struct hnamemem llcsaptable[HASHNAMESIZE];
974edb46e9SPaul Traina 
98a88113a8SBill Fenner #ifdef INET6
99a88113a8SBill Fenner struct h6namemem {
100a88113a8SBill Fenner 	struct in6_addr addr;
101a88113a8SBill Fenner 	char *name;
102a88113a8SBill Fenner 	struct h6namemem *nxt;
103a88113a8SBill Fenner };
104a88113a8SBill Fenner 
105a88113a8SBill Fenner struct h6namemem h6nametable[HASHNAMESIZE];
106a88113a8SBill Fenner #endif /* INET6 */
107a88113a8SBill Fenner 
1084edb46e9SPaul Traina struct enamemem {
1094edb46e9SPaul Traina 	u_short e_addr0;
1104edb46e9SPaul Traina 	u_short e_addr1;
1114edb46e9SPaul Traina 	u_short e_addr2;
1124edb46e9SPaul Traina 	char *e_name;
1134edb46e9SPaul Traina 	u_char *e_nsap;			/* used only for nsaptable[] */
1144edb46e9SPaul Traina 	struct enamemem *e_nxt;
1154edb46e9SPaul Traina };
1164edb46e9SPaul Traina 
1174edb46e9SPaul Traina struct enamemem enametable[HASHNAMESIZE];
1184edb46e9SPaul Traina struct enamemem nsaptable[HASHNAMESIZE];
1194edb46e9SPaul Traina 
1204edb46e9SPaul Traina struct protoidmem {
1214edb46e9SPaul Traina 	u_int32_t p_oui;
1224edb46e9SPaul Traina 	u_short p_proto;
1234edb46e9SPaul Traina 	char *p_name;
1244edb46e9SPaul Traina 	struct protoidmem *p_nxt;
1254edb46e9SPaul Traina };
1264edb46e9SPaul Traina 
1274edb46e9SPaul Traina struct protoidmem protoidtable[HASHNAMESIZE];
1284edb46e9SPaul Traina 
1294edb46e9SPaul Traina /*
1304edb46e9SPaul Traina  * A faster replacement for inet_ntoa().
1314edb46e9SPaul Traina  */
1324edb46e9SPaul Traina char *
1334edb46e9SPaul Traina intoa(u_int32_t addr)
1344edb46e9SPaul Traina {
1354edb46e9SPaul Traina 	register char *cp;
1364edb46e9SPaul Traina 	register u_int byte;
1374edb46e9SPaul Traina 	register int n;
1384edb46e9SPaul Traina 	static char buf[sizeof(".xxx.xxx.xxx.xxx")];
1394edb46e9SPaul Traina 
1404edb46e9SPaul Traina 	NTOHL(addr);
1414edb46e9SPaul Traina 	cp = &buf[sizeof buf];
1424edb46e9SPaul Traina 	*--cp = '\0';
1434edb46e9SPaul Traina 
1444edb46e9SPaul Traina 	n = 4;
1454edb46e9SPaul Traina 	do {
1464edb46e9SPaul Traina 		byte = addr & 0xff;
1474edb46e9SPaul Traina 		*--cp = byte % 10 + '0';
1484edb46e9SPaul Traina 		byte /= 10;
1494edb46e9SPaul Traina 		if (byte > 0) {
1504edb46e9SPaul Traina 			*--cp = byte % 10 + '0';
1514edb46e9SPaul Traina 			byte /= 10;
1524edb46e9SPaul Traina 			if (byte > 0)
1534edb46e9SPaul Traina 				*--cp = byte + '0';
1544edb46e9SPaul Traina 		}
1554edb46e9SPaul Traina 		*--cp = '.';
1564edb46e9SPaul Traina 		addr >>= 8;
1574edb46e9SPaul Traina 	} while (--n > 0);
1584edb46e9SPaul Traina 
1594edb46e9SPaul Traina 	return cp + 1;
1604edb46e9SPaul Traina }
1614edb46e9SPaul Traina 
1624edb46e9SPaul Traina static u_int32_t f_netmask;
1634edb46e9SPaul Traina static u_int32_t f_localnet;
1644edb46e9SPaul Traina static u_int32_t netmask;
1654edb46e9SPaul Traina 
1664edb46e9SPaul Traina /*
1674edb46e9SPaul Traina  * "getname" is written in this atrocious way to make sure we don't
1684edb46e9SPaul Traina  * wait forever while trying to get hostnames from yp.
1694edb46e9SPaul Traina  */
1704edb46e9SPaul Traina #include <setjmp.h>
1714edb46e9SPaul Traina 
1724edb46e9SPaul Traina jmp_buf getname_env;
1734edb46e9SPaul Traina 
1744edb46e9SPaul Traina static RETSIGTYPE
1754edb46e9SPaul Traina nohostname(int signo)
1764edb46e9SPaul Traina {
1774edb46e9SPaul Traina 	longjmp(getname_env, 1);
1784edb46e9SPaul Traina }
1794edb46e9SPaul Traina 
1804edb46e9SPaul Traina /*
1814edb46e9SPaul Traina  * Return a name for the IP address pointed to by ap.  This address
1824edb46e9SPaul Traina  * is assumed to be in network byte order.
1834edb46e9SPaul Traina  */
1844edb46e9SPaul Traina char *
1854edb46e9SPaul Traina getname(const u_char *ap)
1864edb46e9SPaul Traina {
1874edb46e9SPaul Traina 	register struct hostent *hp;
1884edb46e9SPaul Traina 	u_int32_t addr;
1894edb46e9SPaul Traina 	static struct hnamemem *p;		/* static for longjmp() */
1904edb46e9SPaul Traina 
1914edb46e9SPaul Traina #ifndef LBL_ALIGN
1924edb46e9SPaul Traina 	addr = *(const u_int32_t *)ap;
1934edb46e9SPaul Traina #else
194a88113a8SBill Fenner 	memcpy(&addr, ap, sizeof(addr));
1954edb46e9SPaul Traina #endif
1964edb46e9SPaul Traina 	p = &hnametable[addr & (HASHNAMESIZE-1)];
1974edb46e9SPaul Traina 	for (; p->nxt; p = p->nxt) {
1984edb46e9SPaul Traina 		if (p->addr == addr)
1994edb46e9SPaul Traina 			return (p->name);
2004edb46e9SPaul Traina 	}
2014edb46e9SPaul Traina 	p->addr = addr;
2024edb46e9SPaul Traina 	p->nxt = newhnamemem();
2034edb46e9SPaul Traina 
2044edb46e9SPaul Traina 	/*
2054edb46e9SPaul Traina 	 * Only print names when:
2064edb46e9SPaul Traina 	 *	(1) -n was not given.
207699fc314SBill Fenner 	 *      (2) Address is foreign and -f was given. (If -f was not
208699fc314SBill Fenner 	 *	    give, f_netmask and f_local are 0 and the test
209699fc314SBill Fenner 	 *	    evaluates to true)
210699fc314SBill Fenner 	 *      (3) -a was given or the host portion is not all ones
211699fc314SBill Fenner 	 *          nor all zeros (i.e. not a network or broadcast address)
2124edb46e9SPaul Traina 	 */
213699fc314SBill Fenner 	if (!nflag &&
214699fc314SBill Fenner 	    (addr & f_netmask) == f_localnet &&
215699fc314SBill Fenner 	    (aflag ||
216699fc314SBill Fenner 	    !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))) {
2174edb46e9SPaul Traina 		if (!setjmp(getname_env)) {
218699fc314SBill Fenner 			(void)setsignal(SIGALRM, nohostname);
2194edb46e9SPaul Traina 			(void)alarm(20);
2204edb46e9SPaul Traina 			hp = gethostbyaddr((char *)&addr, 4, AF_INET);
2214edb46e9SPaul Traina 			(void)alarm(0);
2224edb46e9SPaul Traina 			if (hp) {
2234edb46e9SPaul Traina 				char *dotp;
2244edb46e9SPaul Traina 
2254edb46e9SPaul Traina 				p->name = savestr(hp->h_name);
2264edb46e9SPaul Traina 				if (Nflag) {
2274edb46e9SPaul Traina 					/* Remove domain qualifications */
2284edb46e9SPaul Traina 					dotp = strchr(p->name, '.');
2294edb46e9SPaul Traina 					if (dotp)
2304edb46e9SPaul Traina 						*dotp = '\0';
2314edb46e9SPaul Traina 				}
2324edb46e9SPaul Traina 				return (p->name);
2334edb46e9SPaul Traina 			}
2344edb46e9SPaul Traina 		}
2354edb46e9SPaul Traina 	}
2364edb46e9SPaul Traina 	p->name = savestr(intoa(addr));
2374edb46e9SPaul Traina 	return (p->name);
2384edb46e9SPaul Traina }
2394edb46e9SPaul Traina 
240a88113a8SBill Fenner #ifdef INET6
241a88113a8SBill Fenner /*
242a88113a8SBill Fenner  * Return a name for the IP6 address pointed to by ap.  This address
243a88113a8SBill Fenner  * is assumed to be in network byte order.
244a88113a8SBill Fenner  */
245a88113a8SBill Fenner char *
246a88113a8SBill Fenner getname6(const u_char *ap)
247a88113a8SBill Fenner {
248a88113a8SBill Fenner 	register struct hostent *hp;
249a88113a8SBill Fenner 	struct in6_addr addr;
250a88113a8SBill Fenner 	static struct h6namemem *p;		/* static for longjmp() */
251a88113a8SBill Fenner 	register char *cp;
252a88113a8SBill Fenner 	char ntop_buf[INET6_ADDRSTRLEN];
253a88113a8SBill Fenner 
254a88113a8SBill Fenner 	memcpy(&addr, ap, sizeof(addr));
255a88113a8SBill Fenner 	p = &h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)];
256a88113a8SBill Fenner 	for (; p->nxt; p = p->nxt) {
257a88113a8SBill Fenner 		if (memcmp(&p->addr, &addr, sizeof(addr)) == 0)
258a88113a8SBill Fenner 			return (p->name);
259a88113a8SBill Fenner 	}
260a88113a8SBill Fenner 	p->addr = addr;
261a88113a8SBill Fenner 	p->nxt = newh6namemem();
262a88113a8SBill Fenner 
263a88113a8SBill Fenner 	/*
264a88113a8SBill Fenner 	 * Only print names when:
265a88113a8SBill Fenner 	 *	(1) -n was not given.
266a88113a8SBill Fenner 	 *      (2) Address is foreign and -f was given. (If -f was not
267a88113a8SBill Fenner 	 *	    give, f_netmask and f_local are 0 and the test
268a88113a8SBill Fenner 	 *	    evaluates to true)
269a88113a8SBill Fenner 	 *      (3) -a was given or the host portion is not all ones
270a88113a8SBill Fenner 	 *          nor all zeros (i.e. not a network or broadcast address)
271a88113a8SBill Fenner 	 */
272a88113a8SBill Fenner 	if (!nflag
273a88113a8SBill Fenner #if 0
274a88113a8SBill Fenner 	&&
275a88113a8SBill Fenner 	    (addr & f_netmask) == f_localnet &&
276a88113a8SBill Fenner 	    (aflag ||
277a88113a8SBill Fenner 	    !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))
278a88113a8SBill Fenner #endif
279a88113a8SBill Fenner 	    ) {
280a88113a8SBill Fenner 		if (!setjmp(getname_env)) {
281a88113a8SBill Fenner 			(void)setsignal(SIGALRM, nohostname);
282a88113a8SBill Fenner 			(void)alarm(20);
283a88113a8SBill Fenner 			hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6);
284a88113a8SBill Fenner 			(void)alarm(0);
285a88113a8SBill Fenner 			if (hp) {
286a88113a8SBill Fenner 				char *dotp;
287a88113a8SBill Fenner 
288a88113a8SBill Fenner 				p->name = savestr(hp->h_name);
289a88113a8SBill Fenner 				if (Nflag) {
290a88113a8SBill Fenner 					/* Remove domain qualifications */
291a88113a8SBill Fenner 					dotp = strchr(p->name, '.');
292a88113a8SBill Fenner 					if (dotp)
293a88113a8SBill Fenner 						*dotp = '\0';
294a88113a8SBill Fenner 				}
295a88113a8SBill Fenner 				return (p->name);
296a88113a8SBill Fenner 			}
297a88113a8SBill Fenner 		}
298a88113a8SBill Fenner 	}
299a88113a8SBill Fenner 	cp = (char *)inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf));
300a88113a8SBill Fenner 	p->name = savestr(cp);
301a88113a8SBill Fenner 	return (p->name);
302a88113a8SBill Fenner }
303a88113a8SBill Fenner #endif /* INET6 */
304a88113a8SBill Fenner 
3054edb46e9SPaul Traina static char hex[] = "0123456789abcdef";
3064edb46e9SPaul Traina 
3074edb46e9SPaul Traina 
3084edb46e9SPaul Traina /* Find the hash node that corresponds the ether address 'ep' */
3094edb46e9SPaul Traina 
3104edb46e9SPaul Traina static inline struct enamemem *
3114edb46e9SPaul Traina lookup_emem(const u_char *ep)
3124edb46e9SPaul Traina {
3134edb46e9SPaul Traina 	register u_int i, j, k;
3144edb46e9SPaul Traina 	struct enamemem *tp;
3154edb46e9SPaul Traina 
3164edb46e9SPaul Traina 	k = (ep[0] << 8) | ep[1];
3174edb46e9SPaul Traina 	j = (ep[2] << 8) | ep[3];
3184edb46e9SPaul Traina 	i = (ep[4] << 8) | ep[5];
3194edb46e9SPaul Traina 
3204edb46e9SPaul Traina 	tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
3214edb46e9SPaul Traina 	while (tp->e_nxt)
3224edb46e9SPaul Traina 		if (tp->e_addr0 == i &&
3234edb46e9SPaul Traina 		    tp->e_addr1 == j &&
3244edb46e9SPaul Traina 		    tp->e_addr2 == k)
3254edb46e9SPaul Traina 			return tp;
3264edb46e9SPaul Traina 		else
3274edb46e9SPaul Traina 			tp = tp->e_nxt;
3284edb46e9SPaul Traina 	tp->e_addr0 = i;
3294edb46e9SPaul Traina 	tp->e_addr1 = j;
3304edb46e9SPaul Traina 	tp->e_addr2 = k;
3314edb46e9SPaul Traina 	tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
3324edb46e9SPaul Traina 	if (tp->e_nxt == NULL)
3334edb46e9SPaul Traina 		error("lookup_emem: calloc");
3344edb46e9SPaul Traina 
3354edb46e9SPaul Traina 	return tp;
3364edb46e9SPaul Traina }
3374edb46e9SPaul Traina 
3384edb46e9SPaul Traina /* Find the hash node that corresponds the NSAP 'nsap' */
3394edb46e9SPaul Traina 
3404edb46e9SPaul Traina static inline struct enamemem *
3414edb46e9SPaul Traina lookup_nsap(register const u_char *nsap)
3424edb46e9SPaul Traina {
3434edb46e9SPaul Traina 	register u_int i, j, k;
3444edb46e9SPaul Traina 	int nlen = *nsap;
3454edb46e9SPaul Traina 	struct enamemem *tp;
3464edb46e9SPaul Traina 	const u_char *ensap = nsap + nlen - 6;
3474edb46e9SPaul Traina 
3484edb46e9SPaul Traina 	if (nlen > 6) {
3494edb46e9SPaul Traina 		k = (ensap[0] << 8) | ensap[1];
3504edb46e9SPaul Traina 		j = (ensap[2] << 8) | ensap[3];
3514edb46e9SPaul Traina 		i = (ensap[4] << 8) | ensap[5];
3524edb46e9SPaul Traina 	}
3534edb46e9SPaul Traina 	else
3544edb46e9SPaul Traina 		i = j = k = 0;
3554edb46e9SPaul Traina 
3564edb46e9SPaul Traina 	tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
3574edb46e9SPaul Traina 	while (tp->e_nxt)
3584edb46e9SPaul Traina 		if (tp->e_addr0 == i &&
3594edb46e9SPaul Traina 		    tp->e_addr1 == j &&
3604edb46e9SPaul Traina 		    tp->e_addr2 == k &&
3614edb46e9SPaul Traina 		    tp->e_nsap[0] == nlen &&
3624edb46e9SPaul Traina 		    memcmp((char *)&(nsap[1]),
3634edb46e9SPaul Traina 			(char *)&(tp->e_nsap[1]), nlen) == 0)
3644edb46e9SPaul Traina 			return tp;
3654edb46e9SPaul Traina 		else
3664edb46e9SPaul Traina 			tp = tp->e_nxt;
3674edb46e9SPaul Traina 	tp->e_addr0 = i;
3684edb46e9SPaul Traina 	tp->e_addr1 = j;
3694edb46e9SPaul Traina 	tp->e_addr2 = k;
3704edb46e9SPaul Traina 	tp->e_nsap = (u_char *)malloc(nlen + 1);
3714edb46e9SPaul Traina 	if (tp->e_nsap == NULL)
3724edb46e9SPaul Traina 		error("lookup_nsap: malloc");
373699fc314SBill Fenner 	memcpy((char *)tp->e_nsap, (char *)nsap, nlen + 1);
3744edb46e9SPaul Traina 	tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
3754edb46e9SPaul Traina 	if (tp->e_nxt == NULL)
3764edb46e9SPaul Traina 		error("lookup_nsap: calloc");
3774edb46e9SPaul Traina 
3784edb46e9SPaul Traina 	return tp;
3794edb46e9SPaul Traina }
3804edb46e9SPaul Traina 
3814edb46e9SPaul Traina /* Find the hash node that corresponds the protoid 'pi'. */
3824edb46e9SPaul Traina 
3834edb46e9SPaul Traina static inline struct protoidmem *
3844edb46e9SPaul Traina lookup_protoid(const u_char *pi)
3854edb46e9SPaul Traina {
3864edb46e9SPaul Traina 	register u_int i, j;
3874edb46e9SPaul Traina 	struct protoidmem *tp;
3884edb46e9SPaul Traina 
3894edb46e9SPaul Traina 	/* 5 octets won't be aligned */
3904edb46e9SPaul Traina 	i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
3914edb46e9SPaul Traina 	j =   (pi[3] << 8) + pi[4];
3924edb46e9SPaul Traina 	/* XXX should be endian-insensitive, but do big-endian testing  XXX */
3934edb46e9SPaul Traina 
3944edb46e9SPaul Traina 	tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
3954edb46e9SPaul Traina 	while (tp->p_nxt)
3964edb46e9SPaul Traina 		if (tp->p_oui == i && tp->p_proto == j)
3974edb46e9SPaul Traina 			return tp;
3984edb46e9SPaul Traina 		else
3994edb46e9SPaul Traina 			tp = tp->p_nxt;
4004edb46e9SPaul Traina 	tp->p_oui = i;
4014edb46e9SPaul Traina 	tp->p_proto = j;
4024edb46e9SPaul Traina 	tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
4034edb46e9SPaul Traina 	if (tp->p_nxt == NULL)
4044edb46e9SPaul Traina 		error("lookup_protoid: calloc");
4054edb46e9SPaul Traina 
4064edb46e9SPaul Traina 	return tp;
4074edb46e9SPaul Traina }
4084edb46e9SPaul Traina 
4094edb46e9SPaul Traina char *
4104edb46e9SPaul Traina etheraddr_string(register const u_char *ep)
4114edb46e9SPaul Traina {
4124edb46e9SPaul Traina 	register u_int i, j;
4134edb46e9SPaul Traina 	register char *cp;
4144edb46e9SPaul Traina 	register struct enamemem *tp;
4154edb46e9SPaul Traina 	char buf[sizeof("00:00:00:00:00:00")];
4164edb46e9SPaul Traina 
4174edb46e9SPaul Traina 	tp = lookup_emem(ep);
4184edb46e9SPaul Traina 	if (tp->e_name)
4194edb46e9SPaul Traina 		return (tp->e_name);
4204edb46e9SPaul Traina #ifdef HAVE_ETHER_NTOHOST
4214edb46e9SPaul Traina 	if (!nflag) {
4224edb46e9SPaul Traina 		char buf[128];
4234edb46e9SPaul Traina 		if (ether_ntohost(buf, (struct ether_addr *)ep) == 0) {
4244edb46e9SPaul Traina 			tp->e_name = savestr(buf);
4254edb46e9SPaul Traina 			return (tp->e_name);
4264edb46e9SPaul Traina 		}
4274edb46e9SPaul Traina 	}
4284edb46e9SPaul Traina #endif
4294edb46e9SPaul Traina 	cp = buf;
4304edb46e9SPaul Traina 	if ((j = *ep >> 4) != 0)
4314edb46e9SPaul Traina 		*cp++ = hex[j];
4324edb46e9SPaul Traina 	*cp++ = hex[*ep++ & 0xf];
4334edb46e9SPaul Traina 	for (i = 5; (int)--i >= 0;) {
4344edb46e9SPaul Traina 		*cp++ = ':';
4354edb46e9SPaul Traina 		if ((j = *ep >> 4) != 0)
4364edb46e9SPaul Traina 			*cp++ = hex[j];
4374edb46e9SPaul Traina 		*cp++ = hex[*ep++ & 0xf];
4384edb46e9SPaul Traina 	}
4394edb46e9SPaul Traina 	*cp = '\0';
4404edb46e9SPaul Traina 	tp->e_name = savestr(buf);
4414edb46e9SPaul Traina 	return (tp->e_name);
4424edb46e9SPaul Traina }
4434edb46e9SPaul Traina 
4444edb46e9SPaul Traina char *
4454edb46e9SPaul Traina etherproto_string(u_short port)
4464edb46e9SPaul Traina {
4474edb46e9SPaul Traina 	register char *cp;
4484edb46e9SPaul Traina 	register struct hnamemem *tp;
4494edb46e9SPaul Traina 	register u_int32_t i = port;
4504edb46e9SPaul Traina 	char buf[sizeof("0000")];
4514edb46e9SPaul Traina 
4524edb46e9SPaul Traina 	for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
4534edb46e9SPaul Traina 		if (tp->addr == i)
4544edb46e9SPaul Traina 			return (tp->name);
4554edb46e9SPaul Traina 
4564edb46e9SPaul Traina 	tp->addr = i;
4574edb46e9SPaul Traina 	tp->nxt = newhnamemem();
4584edb46e9SPaul Traina 
4594edb46e9SPaul Traina 	cp = buf;
4604edb46e9SPaul Traina 	NTOHS(port);
4614edb46e9SPaul Traina 	*cp++ = hex[port >> 12 & 0xf];
4624edb46e9SPaul Traina 	*cp++ = hex[port >> 8 & 0xf];
4634edb46e9SPaul Traina 	*cp++ = hex[port >> 4 & 0xf];
4644edb46e9SPaul Traina 	*cp++ = hex[port & 0xf];
4654edb46e9SPaul Traina 	*cp++ = '\0';
4664edb46e9SPaul Traina 	tp->name = savestr(buf);
4674edb46e9SPaul Traina 	return (tp->name);
4684edb46e9SPaul Traina }
4694edb46e9SPaul Traina 
4704edb46e9SPaul Traina char *
4714edb46e9SPaul Traina protoid_string(register const u_char *pi)
4724edb46e9SPaul Traina {
4734edb46e9SPaul Traina 	register u_int i, j;
4744edb46e9SPaul Traina 	register char *cp;
4754edb46e9SPaul Traina 	register struct protoidmem *tp;
4764edb46e9SPaul Traina 	char buf[sizeof("00:00:00:00:00")];
4774edb46e9SPaul Traina 
4784edb46e9SPaul Traina 	tp = lookup_protoid(pi);
4794edb46e9SPaul Traina 	if (tp->p_name)
4804edb46e9SPaul Traina 		return tp->p_name;
4814edb46e9SPaul Traina 
4824edb46e9SPaul Traina 	cp = buf;
4834edb46e9SPaul Traina 	if ((j = *pi >> 4) != 0)
4844edb46e9SPaul Traina 		*cp++ = hex[j];
4854edb46e9SPaul Traina 	*cp++ = hex[*pi++ & 0xf];
4864edb46e9SPaul Traina 	for (i = 4; (int)--i >= 0;) {
4874edb46e9SPaul Traina 		*cp++ = ':';
4884edb46e9SPaul Traina 		if ((j = *pi >> 4) != 0)
4894edb46e9SPaul Traina 			*cp++ = hex[j];
4904edb46e9SPaul Traina 		*cp++ = hex[*pi++ & 0xf];
4914edb46e9SPaul Traina 	}
4924edb46e9SPaul Traina 	*cp = '\0';
4934edb46e9SPaul Traina 	tp->p_name = savestr(buf);
4944edb46e9SPaul Traina 	return (tp->p_name);
4954edb46e9SPaul Traina }
4964edb46e9SPaul Traina 
4974edb46e9SPaul Traina char *
4984edb46e9SPaul Traina llcsap_string(u_char sap)
4994edb46e9SPaul Traina {
5004edb46e9SPaul Traina 	register char *cp;
5014edb46e9SPaul Traina 	register struct hnamemem *tp;
5024edb46e9SPaul Traina 	register u_int32_t i = sap;
5034edb46e9SPaul Traina 	char buf[sizeof("sap 00")];
5044edb46e9SPaul Traina 
5054edb46e9SPaul Traina 	for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
5064edb46e9SPaul Traina 		if (tp->addr == i)
5074edb46e9SPaul Traina 			return (tp->name);
5084edb46e9SPaul Traina 
5094edb46e9SPaul Traina 	tp->addr = i;
5104edb46e9SPaul Traina 	tp->nxt = newhnamemem();
5114edb46e9SPaul Traina 
5124edb46e9SPaul Traina 	cp = buf;
5134edb46e9SPaul Traina 	(void)strcpy(cp, "sap ");
5144edb46e9SPaul Traina 	cp += strlen(cp);
5154edb46e9SPaul Traina 	*cp++ = hex[sap >> 4 & 0xf];
5164edb46e9SPaul Traina 	*cp++ = hex[sap & 0xf];
5174edb46e9SPaul Traina 	*cp++ = '\0';
5184edb46e9SPaul Traina 	tp->name = savestr(buf);
5194edb46e9SPaul Traina 	return (tp->name);
5204edb46e9SPaul Traina }
5214edb46e9SPaul Traina 
5224edb46e9SPaul Traina char *
5234edb46e9SPaul Traina isonsap_string(const u_char *nsap)
5244edb46e9SPaul Traina {
5254edb46e9SPaul Traina 	register u_int i, nlen = nsap[0];
5264edb46e9SPaul Traina 	register char *cp;
5274edb46e9SPaul Traina 	register struct enamemem *tp;
5284edb46e9SPaul Traina 
5294edb46e9SPaul Traina 	tp = lookup_nsap(nsap);
5304edb46e9SPaul Traina 	if (tp->e_name)
5314edb46e9SPaul Traina 		return tp->e_name;
5324edb46e9SPaul Traina 
53301bd0dbcSPaul Traina 	tp->e_name = cp = (char *)malloc(nlen * 2 + 2 + (nlen>>1));
5344edb46e9SPaul Traina 	if (cp == NULL)
5354edb46e9SPaul Traina 		error("isonsap_string: malloc");
5364edb46e9SPaul Traina 
5374edb46e9SPaul Traina 	nsap++;
53801bd0dbcSPaul Traina 	for (i = 0; i < nlen; i++) {
5394edb46e9SPaul Traina 		*cp++ = hex[*nsap >> 4];
5404edb46e9SPaul Traina 		*cp++ = hex[*nsap++ & 0xf];
54101bd0dbcSPaul Traina 		if (((i & 1) == 0) && (i + 1 < nlen))
54201bd0dbcSPaul Traina 			*cp++ = '.';
5434edb46e9SPaul Traina 	}
5444edb46e9SPaul Traina 	*cp = '\0';
5454edb46e9SPaul Traina 	return (tp->e_name);
5464edb46e9SPaul Traina }
5474edb46e9SPaul Traina 
5484edb46e9SPaul Traina char *
5494edb46e9SPaul Traina tcpport_string(u_short port)
5504edb46e9SPaul Traina {
5514edb46e9SPaul Traina 	register struct hnamemem *tp;
5524edb46e9SPaul Traina 	register u_int32_t i = port;
5534edb46e9SPaul Traina 	char buf[sizeof("00000")];
5544edb46e9SPaul Traina 
5554edb46e9SPaul Traina 	for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
5564edb46e9SPaul Traina 		if (tp->addr == i)
5574edb46e9SPaul Traina 			return (tp->name);
5584edb46e9SPaul Traina 
5594edb46e9SPaul Traina 	tp->addr = i;
5604edb46e9SPaul Traina 	tp->nxt = newhnamemem();
5614edb46e9SPaul Traina 
5627524a079SKris Kennaway 	(void)snprintf(buf, sizeof(buf), "%u", i);
5634edb46e9SPaul Traina 	tp->name = savestr(buf);
5644edb46e9SPaul Traina 	return (tp->name);
5654edb46e9SPaul Traina }
5664edb46e9SPaul Traina 
5674edb46e9SPaul Traina char *
5684edb46e9SPaul Traina udpport_string(register u_short port)
5694edb46e9SPaul Traina {
5704edb46e9SPaul Traina 	register struct hnamemem *tp;
5714edb46e9SPaul Traina 	register u_int32_t i = port;
5724edb46e9SPaul Traina 	char buf[sizeof("00000")];
5734edb46e9SPaul Traina 
5744edb46e9SPaul Traina 	for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
5754edb46e9SPaul Traina 		if (tp->addr == i)
5764edb46e9SPaul Traina 			return (tp->name);
5774edb46e9SPaul Traina 
5784edb46e9SPaul Traina 	tp->addr = i;
5794edb46e9SPaul Traina 	tp->nxt = newhnamemem();
5804edb46e9SPaul Traina 
5817524a079SKris Kennaway 	(void)snprintf(buf, sizeof(buf), "%u", i);
5824edb46e9SPaul Traina 	tp->name = savestr(buf);
5834edb46e9SPaul Traina 	return (tp->name);
5844edb46e9SPaul Traina }
5854edb46e9SPaul Traina 
5864edb46e9SPaul Traina static void
5874edb46e9SPaul Traina init_servarray(void)
5884edb46e9SPaul Traina {
5894edb46e9SPaul Traina 	struct servent *sv;
5904edb46e9SPaul Traina 	register struct hnamemem *table;
5914edb46e9SPaul Traina 	register int i;
5924edb46e9SPaul Traina 	char buf[sizeof("0000000000")];
5934edb46e9SPaul Traina 
5944edb46e9SPaul Traina 	while ((sv = getservent()) != NULL) {
5954edb46e9SPaul Traina 		int port = ntohs(sv->s_port);
5964edb46e9SPaul Traina 		i = port & (HASHNAMESIZE-1);
5974edb46e9SPaul Traina 		if (strcmp(sv->s_proto, "tcp") == 0)
5984edb46e9SPaul Traina 			table = &tporttable[i];
5994edb46e9SPaul Traina 		else if (strcmp(sv->s_proto, "udp") == 0)
6004edb46e9SPaul Traina 			table = &uporttable[i];
6014edb46e9SPaul Traina 		else
6024edb46e9SPaul Traina 			continue;
6034edb46e9SPaul Traina 
6044edb46e9SPaul Traina 		while (table->name)
6054edb46e9SPaul Traina 			table = table->nxt;
6064edb46e9SPaul Traina 		if (nflag) {
6077524a079SKris Kennaway 			(void)snprintf(buf, sizeof(buf), "%d", port);
6084edb46e9SPaul Traina 			table->name = savestr(buf);
6094edb46e9SPaul Traina 		} else
6104edb46e9SPaul Traina 			table->name = savestr(sv->s_name);
6114edb46e9SPaul Traina 		table->addr = port;
6124edb46e9SPaul Traina 		table->nxt = newhnamemem();
6134edb46e9SPaul Traina 	}
6144edb46e9SPaul Traina 	endservent();
6154edb46e9SPaul Traina }
6164edb46e9SPaul Traina 
6174edb46e9SPaul Traina /*XXX from libbpfc.a */
6184edb46e9SPaul Traina extern struct eproto {
6194edb46e9SPaul Traina 	char *s;
6204edb46e9SPaul Traina 	u_short p;
6214edb46e9SPaul Traina } eproto_db[];
6224edb46e9SPaul Traina 
6234edb46e9SPaul Traina static void
6244edb46e9SPaul Traina init_eprotoarray(void)
6254edb46e9SPaul Traina {
6264edb46e9SPaul Traina 	register int i;
6274edb46e9SPaul Traina 	register struct hnamemem *table;
6284edb46e9SPaul Traina 
6294edb46e9SPaul Traina 	for (i = 0; eproto_db[i].s; i++) {
6304edb46e9SPaul Traina 		int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1);
6314edb46e9SPaul Traina 		table = &eprototable[j];
6324edb46e9SPaul Traina 		while (table->name)
6334edb46e9SPaul Traina 			table = table->nxt;
6344edb46e9SPaul Traina 		table->name = eproto_db[i].s;
6354edb46e9SPaul Traina 		table->addr = ntohs(eproto_db[i].p);
6364edb46e9SPaul Traina 		table->nxt = newhnamemem();
6374edb46e9SPaul Traina 	}
6384edb46e9SPaul Traina }
6394edb46e9SPaul Traina 
6404edb46e9SPaul Traina /*
6414edb46e9SPaul Traina  * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
6424edb46e9SPaul Traina  * types.
6434edb46e9SPaul Traina  */
6444edb46e9SPaul Traina static void
6454edb46e9SPaul Traina init_protoidarray(void)
6464edb46e9SPaul Traina {
6474edb46e9SPaul Traina 	register int i;
6484edb46e9SPaul Traina 	register struct protoidmem *tp;
6494edb46e9SPaul Traina 	u_char protoid[5];
6504edb46e9SPaul Traina 
6514edb46e9SPaul Traina 	protoid[0] = 0;
6524edb46e9SPaul Traina 	protoid[1] = 0;
6534edb46e9SPaul Traina 	protoid[2] = 0;
6544edb46e9SPaul Traina 	for (i = 0; eproto_db[i].s; i++) {
6554edb46e9SPaul Traina 		u_short etype = htons(eproto_db[i].p);
6564edb46e9SPaul Traina 
6574edb46e9SPaul Traina 		memcpy((char *)&protoid[3], (char *)&etype, 2);
6584edb46e9SPaul Traina 		tp = lookup_protoid(protoid);
6594edb46e9SPaul Traina 		tp->p_name = savestr(eproto_db[i].s);
6604edb46e9SPaul Traina 	}
6614edb46e9SPaul Traina }
6624edb46e9SPaul Traina 
6634edb46e9SPaul Traina static struct etherlist {
6644edb46e9SPaul Traina 	u_char addr[6];
6654edb46e9SPaul Traina 	char *name;
6664edb46e9SPaul Traina } etherlist[] = {
6674edb46e9SPaul Traina 	{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
6684edb46e9SPaul Traina 	{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
6694edb46e9SPaul Traina };
6704edb46e9SPaul Traina 
6714edb46e9SPaul Traina /*
6724edb46e9SPaul Traina  * Initialize the ethers hash table.  We take two different approaches
6734edb46e9SPaul Traina  * depending on whether or not the system provides the ethers name
6744edb46e9SPaul Traina  * service.  If it does, we just wire in a few names at startup,
6754edb46e9SPaul Traina  * and etheraddr_string() fills in the table on demand.  If it doesn't,
6764edb46e9SPaul Traina  * then we suck in the entire /etc/ethers file at startup.  The idea
6774edb46e9SPaul Traina  * is that parsing the local file will be fast, but spinning through
6784edb46e9SPaul Traina  * all the ethers entries via NIS & next_etherent might be very slow.
6794edb46e9SPaul Traina  *
6804edb46e9SPaul Traina  * XXX pcap_next_etherent doesn't belong in the pcap interface, but
6814edb46e9SPaul Traina  * since the pcap module already does name-to-address translation,
6824edb46e9SPaul Traina  * it's already does most of the work for the ethernet address-to-name
6834edb46e9SPaul Traina  * translation, so we just pcap_next_etherent as a convenience.
6844edb46e9SPaul Traina  */
6854edb46e9SPaul Traina static void
6864edb46e9SPaul Traina init_etherarray(void)
6874edb46e9SPaul Traina {
6884edb46e9SPaul Traina 	register struct etherlist *el;
6894edb46e9SPaul Traina 	register struct enamemem *tp;
6904edb46e9SPaul Traina #ifdef HAVE_ETHER_NTOHOST
6914edb46e9SPaul Traina 	char name[256];
6924edb46e9SPaul Traina #else
6934edb46e9SPaul Traina 	register struct pcap_etherent *ep;
6944edb46e9SPaul Traina 	register FILE *fp;
6954edb46e9SPaul Traina 
6964edb46e9SPaul Traina 	/* Suck in entire ethers file */
6974edb46e9SPaul Traina 	fp = fopen(PCAP_ETHERS_FILE, "r");
6984edb46e9SPaul Traina 	if (fp != NULL) {
6994edb46e9SPaul Traina 		while ((ep = pcap_next_etherent(fp)) != NULL) {
7004edb46e9SPaul Traina 			tp = lookup_emem(ep->addr);
7014edb46e9SPaul Traina 			tp->e_name = savestr(ep->name);
7024edb46e9SPaul Traina 		}
7034edb46e9SPaul Traina 		(void)fclose(fp);
7044edb46e9SPaul Traina 	}
7054edb46e9SPaul Traina #endif
7064edb46e9SPaul Traina 
7074edb46e9SPaul Traina 	/* Hardwire some ethernet names */
7084edb46e9SPaul Traina 	for (el = etherlist; el->name != NULL; ++el) {
7094edb46e9SPaul Traina 		tp = lookup_emem(el->addr);
7104edb46e9SPaul Traina 		/* Don't override existing name */
7114edb46e9SPaul Traina 		if (tp->e_name != NULL)
7124edb46e9SPaul Traina 			continue;
7134edb46e9SPaul Traina 
7144edb46e9SPaul Traina #ifdef HAVE_ETHER_NTOHOST
7154edb46e9SPaul Traina                 /* Use yp/nis version of name if available */
7164edb46e9SPaul Traina                 if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) {
7174edb46e9SPaul Traina                         tp->e_name = savestr(name);
7184edb46e9SPaul Traina 			continue;
7194edb46e9SPaul Traina 		}
7204edb46e9SPaul Traina #endif
7214edb46e9SPaul Traina 		tp->e_name = el->name;
7224edb46e9SPaul Traina 	}
7234edb46e9SPaul Traina }
7244edb46e9SPaul Traina 
7254edb46e9SPaul Traina static struct tok llcsap_db[] = {
7264edb46e9SPaul Traina 	{ LLCSAP_NULL,		"null" },
7274edb46e9SPaul Traina 	{ LLCSAP_8021B_I,	"802.1b-gsap" },
7284edb46e9SPaul Traina 	{ LLCSAP_8021B_G,	"802.1b-isap" },
7294edb46e9SPaul Traina 	{ LLCSAP_IP,		"ip-sap" },
7304edb46e9SPaul Traina 	{ LLCSAP_PROWAYNM,	"proway-nm" },
7314edb46e9SPaul Traina 	{ LLCSAP_8021D,		"802.1d" },
7324edb46e9SPaul Traina 	{ LLCSAP_RS511,		"eia-rs511" },
7334edb46e9SPaul Traina 	{ LLCSAP_ISO8208,	"x.25/llc2" },
7344edb46e9SPaul Traina 	{ LLCSAP_PROWAY,	"proway" },
7354edb46e9SPaul Traina 	{ LLCSAP_ISONS,		"iso-clns" },
7364edb46e9SPaul Traina 	{ LLCSAP_GLOBAL,	"global" },
7374edb46e9SPaul Traina 	{ 0,			NULL }
7384edb46e9SPaul Traina };
7394edb46e9SPaul Traina 
7404edb46e9SPaul Traina static void
7414edb46e9SPaul Traina init_llcsaparray(void)
7424edb46e9SPaul Traina {
7434edb46e9SPaul Traina 	register int i;
7444edb46e9SPaul Traina 	register struct hnamemem *table;
7454edb46e9SPaul Traina 
7464edb46e9SPaul Traina 	for (i = 0; llcsap_db[i].s != NULL; i++) {
7474edb46e9SPaul Traina 		table = &llcsaptable[llcsap_db[i].v];
7484edb46e9SPaul Traina 		while (table->name)
7494edb46e9SPaul Traina 			table = table->nxt;
7504edb46e9SPaul Traina 		table->name = llcsap_db[i].s;
7514edb46e9SPaul Traina 		table->addr = llcsap_db[i].v;
7524edb46e9SPaul Traina 		table->nxt = newhnamemem();
7534edb46e9SPaul Traina 	}
7544edb46e9SPaul Traina }
7554edb46e9SPaul Traina 
7564edb46e9SPaul Traina /*
7574edb46e9SPaul Traina  * Initialize the address to name translation machinery.  We map all
7584edb46e9SPaul Traina  * non-local IP addresses to numeric addresses if fflag is true (i.e.,
7594edb46e9SPaul Traina  * to prevent blocking on the nameserver).  localnet is the IP address
7604edb46e9SPaul Traina  * of the local network.  mask is its subnet mask.
7614edb46e9SPaul Traina  */
7624edb46e9SPaul Traina void
763699fc314SBill Fenner init_addrtoname(u_int32_t localnet, u_int32_t mask)
7644edb46e9SPaul Traina {
7654edb46e9SPaul Traina 	netmask = mask;
7664edb46e9SPaul Traina 	if (fflag) {
7674edb46e9SPaul Traina 		f_localnet = localnet;
7684edb46e9SPaul Traina 		f_netmask = mask;
7694edb46e9SPaul Traina 	}
7704edb46e9SPaul Traina 	if (nflag)
7714edb46e9SPaul Traina 		/*
7724edb46e9SPaul Traina 		 * Simplest way to suppress names.
7734edb46e9SPaul Traina 		 */
7744edb46e9SPaul Traina 		return;
7754edb46e9SPaul Traina 
7764edb46e9SPaul Traina 	init_etherarray();
7774edb46e9SPaul Traina 	init_servarray();
7784edb46e9SPaul Traina 	init_eprotoarray();
7794edb46e9SPaul Traina 	init_llcsaparray();
7804edb46e9SPaul Traina 	init_protoidarray();
7814edb46e9SPaul Traina }
7824edb46e9SPaul Traina 
7834edb46e9SPaul Traina char *
7844edb46e9SPaul Traina dnaddr_string(u_short dnaddr)
7854edb46e9SPaul Traina {
7864edb46e9SPaul Traina 	register struct hnamemem *tp;
7874edb46e9SPaul Traina 
7884edb46e9SPaul Traina 	for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0;
7894edb46e9SPaul Traina 	     tp = tp->nxt)
7904edb46e9SPaul Traina 		if (tp->addr == dnaddr)
7914edb46e9SPaul Traina 			return (tp->name);
7924edb46e9SPaul Traina 
7934edb46e9SPaul Traina 	tp->addr = dnaddr;
7944edb46e9SPaul Traina 	tp->nxt = newhnamemem();
7954edb46e9SPaul Traina 	if (nflag)
7964edb46e9SPaul Traina 		tp->name = dnnum_string(dnaddr);
7974edb46e9SPaul Traina 	else
7984edb46e9SPaul Traina 		tp->name = dnname_string(dnaddr);
7994edb46e9SPaul Traina 
8004edb46e9SPaul Traina 	return(tp->name);
8014edb46e9SPaul Traina }
8024edb46e9SPaul Traina 
8034edb46e9SPaul Traina /* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
8044edb46e9SPaul Traina struct hnamemem *
8052ebf6c05SBill Fenner newhnamemem(void)
8064edb46e9SPaul Traina {
8074edb46e9SPaul Traina 	register struct hnamemem *p;
8084edb46e9SPaul Traina 	static struct hnamemem *ptr = NULL;
8094edb46e9SPaul Traina 	static u_int num = 0;
8104edb46e9SPaul Traina 
8114edb46e9SPaul Traina 	if (num  <= 0) {
8124edb46e9SPaul Traina 		num = 64;
8134edb46e9SPaul Traina 		ptr = (struct hnamemem *)calloc(num, sizeof (*ptr));
8144edb46e9SPaul Traina 		if (ptr == NULL)
8154edb46e9SPaul Traina 			error("newhnamemem: calloc");
8164edb46e9SPaul Traina 	}
8174edb46e9SPaul Traina 	--num;
8184edb46e9SPaul Traina 	p = ptr++;
8194edb46e9SPaul Traina 	return (p);
8204edb46e9SPaul Traina }
821a88113a8SBill Fenner 
822a88113a8SBill Fenner #ifdef INET6
823a88113a8SBill Fenner /* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */
824a88113a8SBill Fenner struct h6namemem *
825a88113a8SBill Fenner newh6namemem(void)
826a88113a8SBill Fenner {
827a88113a8SBill Fenner 	register struct h6namemem *p;
828a88113a8SBill Fenner 	static struct h6namemem *ptr = NULL;
829a88113a8SBill Fenner 	static u_int num = 0;
830a88113a8SBill Fenner 
831a88113a8SBill Fenner 	if (num  <= 0) {
832a88113a8SBill Fenner 		num = 64;
833a88113a8SBill Fenner 		ptr = (struct h6namemem *)calloc(num, sizeof (*ptr));
834a88113a8SBill Fenner 		if (ptr == NULL)
835a88113a8SBill Fenner 			error("newh6namemem: calloc");
836a88113a8SBill Fenner 	}
837a88113a8SBill Fenner 	--num;
838a88113a8SBill Fenner 	p = ptr++;
839a88113a8SBill Fenner 	return (p);
840a88113a8SBill Fenner }
841a88113a8SBill Fenner #endif /* INET6 */
842