GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/tcpdump/addrtoname.c Lines: 0 367 0.0 %
Date: 2017-11-13 Branches: 0 201 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: addrtoname.c,v 1.37 2016/12/14 19:12:16 jca Exp $	*/
2
3
/*
4
 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
5
 *	The Regents of the University of California.  All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that: (1) source code distributions
9
 * retain the above copyright notice and this paragraph in its entirety, (2)
10
 * distributions including binary code include the above copyright notice and
11
 * this paragraph in its entirety in the documentation or other materials
12
 * provided with the distribution, and (3) all advertising materials mentioning
13
 * features or use of this software display the following acknowledgement:
14
 * ``This product includes software developed by the University of California,
15
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16
 * the University nor the names of its contributors may be used to endorse
17
 * or promote products derived from this software without specific prior
18
 * written permission.
19
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22
 *
23
 *  Internet, ethernet, port, and protocol string to address
24
 *  and address to string conversion routines
25
 */
26
27
#include <sys/socket.h>
28
#include <sys/time.h>
29
#include <sys/types.h>
30
31
struct mbuf;
32
struct rtentry;
33
#include <net/if.h>
34
35
#include <netinet/in.h>
36
#include <netinet/if_ether.h>
37
38
#ifdef INET6
39
#include <netinet/ip6.h>
40
#endif
41
42
#include <arpa/inet.h>
43
44
#include <ctype.h>
45
#include <inttypes.h>
46
#include <netdb.h>
47
#include <pcap.h>
48
#include <pcap-namedb.h>
49
#include <signal.h>
50
#include <stdio.h>
51
#include <string.h>
52
#include <stdlib.h>
53
#include <unistd.h>
54
#include <limits.h>
55
56
#include "interface.h"
57
#include "addrtoname.h"
58
#include "llc.h"
59
#include "privsep.h"
60
#include "savestr.h"
61
62
/*
63
 * hash tables for whatever-to-name translations
64
 */
65
66
#define HASHNAMESIZE 4096
67
68
struct hnamemem {
69
	u_int32_t addr;
70
	char *name;
71
	struct hnamemem *nxt;
72
};
73
74
struct hnamemem hnametable[HASHNAMESIZE];
75
struct hnamemem tporttable[HASHNAMESIZE];
76
struct hnamemem uporttable[HASHNAMESIZE];
77
struct hnamemem eprototable[HASHNAMESIZE];
78
struct hnamemem dnaddrtable[HASHNAMESIZE];
79
struct hnamemem llcsaptable[HASHNAMESIZE];
80
81
#ifdef INET6
82
struct h6namemem {
83
	struct in6_addr addr;
84
	char *name;
85
	struct h6namemem *nxt;
86
};
87
88
struct h6namemem h6nametable[HASHNAMESIZE];
89
#endif /* INET6 */
90
91
struct enamemem {
92
	u_short e_addr0;
93
	u_short e_addr1;
94
	u_short e_addr2;
95
	char *e_name;
96
	u_char *e_nsap;			/* used only for nsaptable[] */
97
#define e_bs e_nsap			/* for bytestringtable */
98
	struct enamemem *e_nxt;
99
};
100
101
struct enamemem enametable[HASHNAMESIZE];
102
struct enamemem nsaptable[HASHNAMESIZE];
103
struct enamemem bytestringtable[HASHNAMESIZE];
104
static char *ipprototable[256];
105
106
struct protoidmem {
107
	u_int32_t p_oui;
108
	u_short p_proto;
109
	char *p_name;
110
	struct protoidmem *p_nxt;
111
};
112
113
struct protoidmem protoidtable[HASHNAMESIZE];
114
115
/*
116
 * A faster replacement for inet_ntoa().
117
 */
118
char *
119
intoa(u_int32_t addr)
120
{
121
	char *cp;
122
	u_int byte;
123
	int n;
124
	static char buf[sizeof(".xxx.xxx.xxx.xxx")];
125
126
	NTOHL(addr);
127
	cp = &buf[sizeof buf];
128
	*--cp = '\0';
129
130
	n = 4;
131
	do {
132
		byte = addr & 0xff;
133
		*--cp = byte % 10 + '0';
134
		byte /= 10;
135
		if (byte > 0) {
136
			*--cp = byte % 10 + '0';
137
			byte /= 10;
138
			if (byte > 0)
139
				*--cp = byte + '0';
140
		}
141
		*--cp = '.';
142
		addr >>= 8;
143
	} while (--n > 0);
144
145
	return cp + 1;
146
}
147
148
static u_int32_t f_netmask;
149
static u_int32_t f_localnet;
150
static u_int32_t netmask;
151
152
/*
153
 * Return a name for the IP address pointed to by ap.  This address
154
 * is assumed to be in network byte order.
155
 */
156
char *
157
getname(const u_char *ap)
158
{
159
	char host[HOST_NAME_MAX+1];
160
	u_int32_t addr;
161
	struct hnamemem *p;
162
163
	/*
164
	 * Extract 32 bits in network order, dealing with alignment.
165
	 */
166
	switch ((intptr_t)ap & (sizeof(u_int32_t)-1)) {
167
168
	case 0:
169
		addr = *(u_int32_t *)ap;
170
		break;
171
172
	case 2:
173
#if BYTE_ORDER == BIG_ENDIAN
174
		addr = ((u_int32_t)*(u_short *)ap << 16) |
175
			(u_int32_t)*(u_short *)(ap + 2);
176
#else
177
		addr = ((u_int32_t)*(u_short *)(ap + 2) << 16) |
178
			(u_int32_t)*(u_short *)ap;
179
#endif
180
		break;
181
182
	default:
183
#if BYTE_ORDER == BIG_ENDIAN
184
		addr = ((u_int32_t)ap[0] << 24) |
185
			((u_int32_t)ap[1] << 16) |
186
			((u_int32_t)ap[2] << 8) |
187
			(u_int32_t)ap[3];
188
#else
189
		addr = ((u_int32_t)ap[3] << 24) |
190
			((u_int32_t)ap[2] << 16) |
191
			((u_int32_t)ap[1] << 8) |
192
			(u_int32_t)ap[0];
193
#endif
194
		break;
195
	}
196
197
	p = &hnametable[addr & (HASHNAMESIZE-1)];
198
	for (; p->nxt; p = p->nxt) {
199
		if (p->addr == addr)
200
			return (p->name);
201
	}
202
	p->addr = addr;
203
	p->nxt = newhnamemem();
204
205
	/*
206
	 * Only print names when:
207
	 *	(1) -n was not given
208
	 *      (2) Address is foreign and -f was given. (If -f was not
209
	 *	    give, f_netmask and f_local are 0 and the test
210
	 *	    evaluates to true)
211
	 *      (3) -a was given or the host portion is not all ones
212
	 *          nor all zeros (i.e. not a network or broadcast address)
213
	 */
214
	if (!nflag &&
215
	    (addr & f_netmask) == f_localnet &&
216
	    (aflag ||
217
	    !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))) {
218
		size_t n = priv_gethostbyaddr((char *)&addr, sizeof(addr),
219
		    AF_INET, host, sizeof(host));
220
		if (n > 0) {
221
			char *dotp;
222
223
			p->name = savestr(host);
224
			if (Nflag) {
225
				/* Remove domain qualifications */
226
				dotp = strchr(p->name, '.');
227
				if (dotp)
228
					*dotp = '\0';
229
			}
230
			return (p->name);
231
		}
232
	}
233
	p->name = savestr(intoa(addr));
234
	return (p->name);
235
}
236
237
#ifdef INET6
238
/*
239
 * Return a name for the IP6 address pointed to by ap.  This address
240
 * is assumed to be in network byte order.
241
 */
242
char *
243
getname6(const u_char *ap)
244
{
245
	char host[HOST_NAME_MAX+1];
246
	struct in6_addr addr;
247
	struct h6namemem *p;
248
	char *cp;
249
	char ntop_buf[INET6_ADDRSTRLEN];
250
251
	memcpy(&addr, ap, sizeof(addr));
252
	p = &h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)];
253
	for (; p->nxt; p = p->nxt) {
254
		if (memcmp(&p->addr, &addr, sizeof(addr)) == 0)
255
			return (p->name);
256
	}
257
	p->addr = addr;
258
	p->nxt = newh6namemem();
259
260
	/*
261
	 * Only print names when:
262
	 *	(1) -n was not given
263
	 *      (2) Address is foreign and -f was given. (If -f was not
264
	 *	    give, f_netmask and f_local are 0 and the test
265
	 *	    evaluates to true)
266
	 *      (3) -a was given or the host portion is not all ones
267
	 *          nor all zeros (i.e. not a network or broadcast address)
268
	 */
269
	if (!nflag
270
#if 0
271
	&&
272
	    (addr & f_netmask) == f_localnet &&
273
	    (aflag ||
274
	    !((addr & ~netmask) == 0 || (addr | netmask) == 0xffffffff))
275
#endif
276
	    ) {
277
		size_t n = priv_gethostbyaddr((char *)&addr, sizeof(addr),
278
		    AF_INET6, host, sizeof(host));
279
		if (n > 0) {
280
			char *dotp;
281
282
			p->name = savestr(host);
283
			if (Nflag) {
284
				/* Remove domain qualifications */
285
				dotp = strchr(p->name, '.');
286
				if (dotp)
287
					*dotp = '\0';
288
			}
289
			return (p->name);
290
		}
291
	}
292
	cp = (char *)inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf));
293
	p->name = savestr(cp);
294
	return (p->name);
295
}
296
#endif /* INET6 */
297
298
static char hex[] = "0123456789abcdef";
299
300
301
/* Find the hash node that corresponds the ether address 'ep' */
302
303
static inline struct enamemem *
304
lookup_emem(const u_char *ep)
305
{
306
	u_int i, j, k;
307
	struct enamemem *tp;
308
309
	k = (ep[0] << 8) | ep[1];
310
	j = (ep[2] << 8) | ep[3];
311
	i = (ep[4] << 8) | ep[5];
312
313
	tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
314
	while (tp->e_nxt)
315
		if (tp->e_addr0 == i &&
316
		    tp->e_addr1 == j &&
317
		    tp->e_addr2 == k)
318
			return tp;
319
		else
320
			tp = tp->e_nxt;
321
	tp->e_addr0 = i;
322
	tp->e_addr1 = j;
323
	tp->e_addr2 = k;
324
	tp->e_nxt = calloc(1, sizeof(*tp));
325
	if (tp->e_nxt == NULL)
326
		error("lookup_emem: calloc");
327
328
	return tp;
329
}
330
331
/*
332
 * Find the hash node that corresponds to the bytestring 'bs'
333
 * with length 'nlen'
334
 */
335
336
static inline struct enamemem *
337
lookup_bytestring(const u_char *bs, const int nlen)
338
{
339
	struct enamemem *tp;
340
	u_int i, j, k;
341
342
	if (nlen >= 6) {
343
		k = (bs[0] << 8) | bs[1];
344
		j = (bs[2] << 8) | bs[3];
345
		i = (bs[4] << 8) | bs[5];
346
	} else if (nlen >= 4) {
347
		k = (bs[0] << 8) | bs[1];
348
		j = (bs[2] << 8) | bs[3];
349
		i = 0;
350
	} else
351
		i = j = k = 0;
352
353
	tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)];
354
	while (tp->e_nxt)
355
		if (tp->e_addr0 == i &&
356
		    tp->e_addr1 == j &&
357
		    tp->e_addr2 == k &&
358
		    bcmp((char *)bs, (char *)(tp->e_bs), nlen) == 0)
359
			return tp;
360
		else
361
			tp = tp->e_nxt;
362
363
	tp->e_addr0 = i;
364
	tp->e_addr1 = j;
365
	tp->e_addr2 = k;
366
367
	tp->e_bs = calloc(1, nlen + 1);
368
	if (tp->e_bs == NULL)
369
		error("lookup_bytestring: calloc");
370
	bcopy(bs, tp->e_bs, nlen);
371
	tp->e_nxt = calloc(1, sizeof(*tp));
372
	if (tp->e_nxt == NULL)
373
		error("lookup_bytestring: calloc");
374
375
	return tp;
376
}
377
378
/* Find the hash node that corresponds the NSAP 'nsap' */
379
380
static inline struct enamemem *
381
lookup_nsap(const u_char *nsap)
382
{
383
	u_int i, j, k;
384
	int nlen = *nsap;
385
	struct enamemem *tp;
386
	const u_char *ensap = nsap + nlen - 6;
387
388
	if (nlen > 6) {
389
		k = (ensap[0] << 8) | ensap[1];
390
		j = (ensap[2] << 8) | ensap[3];
391
		i = (ensap[4] << 8) | ensap[5];
392
	}
393
	else
394
		i = j = k = 0;
395
396
	tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
397
	while (tp->e_nxt)
398
		if (tp->e_addr0 == i &&
399
		    tp->e_addr1 == j &&
400
		    tp->e_addr2 == k &&
401
		    tp->e_nsap[0] == nlen &&
402
		    memcmp((char *)&(nsap[1]),
403
			(char *)&(tp->e_nsap[1]), nlen) == 0)
404
			return tp;
405
		else
406
			tp = tp->e_nxt;
407
	tp->e_addr0 = i;
408
	tp->e_addr1 = j;
409
	tp->e_addr2 = k;
410
	tp->e_nsap = malloc(nlen + 1);
411
	if (tp->e_nsap == NULL)
412
		error("lookup_nsap: malloc");
413
	memcpy((char *)tp->e_nsap, (char *)nsap, nlen + 1);
414
	tp->e_nxt = calloc(1, sizeof(*tp));
415
	if (tp->e_nxt == NULL)
416
		error("lookup_nsap: calloc");
417
418
	return tp;
419
}
420
421
/* Find the hash node that corresponds the protoid 'pi'. */
422
423
static inline struct protoidmem *
424
lookup_protoid(const u_char *pi)
425
{
426
	u_int i, j;
427
	struct protoidmem *tp;
428
429
	/* 5 octets won't be aligned */
430
	i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
431
	j =   (pi[3] << 8) + pi[4];
432
	/* XXX should be endian-insensitive, but do big-endian testing  XXX */
433
434
	tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
435
	while (tp->p_nxt)
436
		if (tp->p_oui == i && tp->p_proto == j)
437
			return tp;
438
		else
439
			tp = tp->p_nxt;
440
	tp->p_oui = i;
441
	tp->p_proto = j;
442
	tp->p_nxt = calloc(1, sizeof(*tp));
443
	if (tp->p_nxt == NULL)
444
		error("lookup_protoid: calloc");
445
446
	return tp;
447
}
448
449
char *
450
etheraddr_string(const u_char *ep)
451
{
452
	struct enamemem *tp;
453
	struct ether_addr e;
454
455
	tp = lookup_emem(ep);
456
	if (tp->e_name)
457
		return (tp->e_name);
458
#ifdef HAVE_ETHER_NTOHOST
459
	if (!nflag) {
460
		char buf[HOST_NAME_MAX+1 + 1];
461
		if (priv_ether_ntohost(buf, sizeof(buf),
462
		    (struct ether_addr *)ep) > 0) {
463
			tp->e_name = savestr(buf);
464
			return (tp->e_name);
465
		}
466
	}
467
#endif
468
	memcpy(e.ether_addr_octet, ep, sizeof(e.ether_addr_octet));
469
	tp->e_name = savestr(ether_ntoa(&e));
470
	return (tp->e_name);
471
}
472
473
char *
474
linkaddr_string(const u_char *ep, const int len)
475
{
476
	u_int i, j;
477
	char *cp;
478
	struct enamemem *tp;
479
480
	if (len == 6)	/* XXX not totally correct... */
481
		return etheraddr_string(ep);
482
483
	tp = lookup_bytestring(ep, len);
484
	if (tp->e_name)
485
		return (tp->e_name);
486
487
	tp->e_name = cp = reallocarray(NULL, len, 3);
488
	if (tp->e_name == NULL)
489
		error("linkaddr_string: malloc");
490
	if ((j = *ep >> 4) != 0)
491
		*cp++ = hex[j];
492
	*cp++ = hex[*ep++ & 0xf];
493
	for (i = len-1; i > 0 ; --i) {
494
		*cp++ = ':';
495
		if ((j = *ep >> 4) != 0)
496
			*cp++ = hex[j];
497
		*cp++ = hex[*ep++ & 0xf];
498
	}
499
	*cp = '\0';
500
	return (tp->e_name);
501
}
502
503
char *
504
etherproto_string(u_short port)
505
{
506
	char *cp;
507
	struct hnamemem *tp;
508
	u_int32_t i = port;
509
	char buf[sizeof("0000")];
510
511
	for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
512
		if (tp->addr == i)
513
			return (tp->name);
514
515
	tp->addr = i;
516
	tp->nxt = newhnamemem();
517
518
	cp = buf;
519
	NTOHS(port);
520
	*cp++ = hex[port >> 12 & 0xf];
521
	*cp++ = hex[port >> 8 & 0xf];
522
	*cp++ = hex[port >> 4 & 0xf];
523
	*cp++ = hex[port & 0xf];
524
	*cp++ = '\0';
525
	tp->name = savestr(buf);
526
	return (tp->name);
527
}
528
529
char *
530
protoid_string(const u_char *pi)
531
{
532
	u_int i, j;
533
	char *cp;
534
	struct protoidmem *tp;
535
	char buf[sizeof("00:00:00:00:00")];
536
537
	tp = lookup_protoid(pi);
538
	if (tp->p_name)
539
		return tp->p_name;
540
541
	cp = buf;
542
	if ((j = *pi >> 4) != 0)
543
		*cp++ = hex[j];
544
	*cp++ = hex[*pi++ & 0xf];
545
	for (i = 4; (int)--i >= 0;) {
546
		*cp++ = ':';
547
		if ((j = *pi >> 4) != 0)
548
			*cp++ = hex[j];
549
		*cp++ = hex[*pi++ & 0xf];
550
	}
551
	*cp = '\0';
552
	tp->p_name = savestr(buf);
553
	return (tp->p_name);
554
}
555
556
char *
557
llcsap_string(u_char sap)
558
{
559
	struct hnamemem *tp;
560
	u_int32_t i = sap;
561
	char buf[sizeof("sap 00")];
562
563
	for (tp = &llcsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
564
		if (tp->addr == i)
565
			return (tp->name);
566
567
	tp->addr = i;
568
	tp->nxt = newhnamemem();
569
570
	snprintf(buf, sizeof(buf), "sap %02x", sap & 0xff);
571
	tp->name = savestr(buf);
572
	return (tp->name);
573
}
574
575
char *
576
isonsap_string(const u_char *nsap)
577
{
578
	u_int i, nlen = nsap[0];
579
	char *cp;
580
	struct enamemem *tp;
581
582
	tp = lookup_nsap(nsap);
583
	if (tp->e_name)
584
		return tp->e_name;
585
586
	tp->e_name = cp = malloc(nlen * 2 + 2);
587
	if (cp == NULL)
588
		error("isonsap_string: malloc");
589
590
	nsap++;
591
	*cp++ = '/';
592
	for (i = nlen; (int)--i >= 0;) {
593
		*cp++ = hex[*nsap >> 4];
594
		*cp++ = hex[*nsap++ & 0xf];
595
	}
596
	*cp = '\0';
597
	return (tp->e_name);
598
}
599
600
char *
601
tcpport_string(u_short port)
602
{
603
	struct hnamemem *tp;
604
	u_int32_t i = port;
605
	char buf[sizeof("00000")];
606
607
	for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
608
		if (tp->addr == i)
609
			return (tp->name);
610
611
	tp->addr = i;
612
	tp->nxt = newhnamemem();
613
614
	(void)snprintf(buf, sizeof(buf), "%u", i);
615
	tp->name = savestr(buf);
616
	return (tp->name);
617
}
618
619
char *
620
udpport_string(u_short port)
621
{
622
	struct hnamemem *tp;
623
	u_int32_t i = port;
624
	char buf[sizeof("00000")];
625
626
	for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
627
		if (tp->addr == i)
628
			return (tp->name);
629
630
	tp->addr = i;
631
	tp->nxt = newhnamemem();
632
633
	(void)snprintf(buf, sizeof(buf), "%u", i);
634
	tp->name = savestr(buf);
635
	return (tp->name);
636
}
637
638
char *
639
ipproto_string(u_int proto)
640
{
641
	return ipprototable[proto & 0xff];
642
}
643
644
static void
645
init_servarray(void)
646
{
647
	struct hnamemem *table;
648
	int i, port;
649
	char buf[sizeof("0000000000")];
650
	char service[BUFSIZ];
651
	char protocol[BUFSIZ];
652
653
	priv_getserventries();
654
	while (priv_getserventry(service, sizeof(service), &port, protocol,
655
	    sizeof(protocol)) != 0) {
656
		port = ntohs(port);
657
		i = port & (HASHNAMESIZE-1);
658
		if (strcmp(protocol, "tcp") == 0)
659
			table = &tporttable[i];
660
		else if (strcmp(protocol, "udp") == 0)
661
			table = &uporttable[i];
662
		else
663
			continue;
664
665
		while (table->name)
666
			table = table->nxt;
667
		if (nflag) {
668
			(void)snprintf(buf, sizeof(buf), "%d", port);
669
			table->name = savestr(buf);
670
		} else
671
			table->name = savestr(service);
672
		table->addr = port;
673
		table->nxt = newhnamemem();
674
	}
675
}
676
677
static void
678
init_ipprotoarray(void)
679
{
680
	int i;
681
	char buf[sizeof("000")];
682
	char prot[BUFSIZ];
683
684
	if (!nflag) {
685
		priv_getprotoentries();
686
		while (priv_getprotoentry(prot, sizeof(prot), &i) != 0)
687
			ipprototable[i & 0xff] = savestr(prot);
688
	}
689
	for (i = 0; i < 256; i++)
690
		if (ipprototable[i] == NULL) {
691
			(void)snprintf(buf, sizeof(buf), "%d", i);
692
			ipprototable[i] = savestr(buf);
693
		}
694
}
695
696
/* XXX from libpcap */
697
extern const struct eproto {
698
	char *s;
699
	u_short p;
700
} * const eproto_db;
701
702
static void
703
init_eprotoarray(void)
704
{
705
	int i;
706
	struct hnamemem *table;
707
708
	for (i = 0; eproto_db[i].s; i++) {
709
		int j = ntohs(eproto_db[i].p) & (HASHNAMESIZE-1);
710
		table = &eprototable[j];
711
		while (table->name)
712
			table = table->nxt;
713
		table->name = eproto_db[i].s;
714
		table->addr = ntohs(eproto_db[i].p);
715
		table->nxt = newhnamemem();
716
	}
717
}
718
719
/*
720
 * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
721
 * types.
722
 */
723
static void
724
init_protoidarray(void)
725
{
726
	int i;
727
	struct protoidmem *tp;
728
	u_char protoid[5];
729
730
	protoid[0] = 0;
731
	protoid[1] = 0;
732
	protoid[2] = 0;
733
	for (i = 0; eproto_db[i].s; i++) {
734
		u_short etype = htons(eproto_db[i].p);
735
736
		memcpy((char *)&protoid[3], (char *)&etype, 2);
737
		tp = lookup_protoid(protoid);
738
		tp->p_name = savestr(eproto_db[i].s);
739
	}
740
}
741
742
static struct etherlist {
743
	u_char addr[6];
744
	char *name;
745
} etherlist[] = {
746
	{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
747
	{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
748
};
749
750
/*
751
 * Initialize the ethers hash table.  We take two different approaches
752
 * depending on whether or not the system provides the ethers name
753
 * service.  If it does, we just wire in a few names at startup,
754
 * and etheraddr_string() fills in the table on demand.  If it doesn't,
755
 * then we suck in the entire /etc/ethers file at startup.  The idea
756
 * is that parsing the local file will be fast, but spinning through
757
 * all the ethers entries via NIS & next_etherent might be very slow.
758
 *
759
 * XXX pcap_next_etherent doesn't belong in the pcap interface, but
760
 * since the pcap module already does name-to-address translation,
761
 * it's already does most of the work for the ethernet address-to-name
762
 * translation, so we just pcap_next_etherent as a convenience.
763
 */
764
static void
765
init_etherarray(void)
766
{
767
	struct etherlist *el;
768
	struct enamemem *tp;
769
#ifdef HAVE_ETHER_NTOHOST
770
	char name[HOST_NAME_MAX+1 + 1];
771
#else
772
	struct pcap_etherent *ep;
773
	FILE *fp;
774
775
	/* Suck in entire ethers file */
776
	fp = fopen(PCAP_ETHERS_FILE, "r");
777
	if (fp != NULL) {
778
		while ((ep = pcap_next_etherent(fp)) != NULL) {
779
			tp = lookup_emem(ep->addr);
780
			tp->e_name = savestr(ep->name);
781
		}
782
		(void)fclose(fp);
783
	}
784
#endif
785
786
	/* Hardwire some ethernet names */
787
	for (el = etherlist; el->name != NULL; ++el) {
788
		tp = lookup_emem(el->addr);
789
		/* Don't override existing name */
790
		if (tp->e_name != NULL)
791
			continue;
792
793
#ifdef HAVE_ETHER_NTOHOST
794
                /* Use yp/nis version of name if available */
795
                if (priv_ether_ntohost(name, sizeof(name),
796
		    (struct ether_addr *)el->addr) > 0) {
797
                        tp->e_name = savestr(name);
798
			continue;
799
		}
800
#endif
801
		tp->e_name = el->name;
802
	}
803
}
804
805
static struct tok llcsap_db[] = {
806
	{ LLCSAP_NULL,		"null" },
807
	{ LLCSAP_8021B_I,	"802.1b-gsap" },
808
	{ LLCSAP_8021B_G,	"802.1b-isap" },
809
	{ LLCSAP_IP,		"ip-sap" },
810
	{ LLCSAP_PROWAYNM,	"proway-nm" },
811
	{ LLCSAP_8021D,		"802.1d" },
812
	{ LLCSAP_RS511,		"eia-rs511" },
813
	{ LLCSAP_ISO8208,	"x.25/llc2" },
814
	{ LLCSAP_PROWAY,	"proway" },
815
	{ LLCSAP_ISONS,		"iso-clns" },
816
	{ LLCSAP_GLOBAL,	"global" },
817
	{ 0,			NULL }
818
};
819
820
static void
821
init_llcsaparray(void)
822
{
823
	int i;
824
	struct hnamemem *table;
825
826
	for (i = 0; llcsap_db[i].s != NULL; i++) {
827
		table = &llcsaptable[llcsap_db[i].v];
828
		while (table->name)
829
			table = table->nxt;
830
		table->name = llcsap_db[i].s;
831
		table->addr = llcsap_db[i].v;
832
		table->nxt = newhnamemem();
833
	}
834
}
835
836
/*
837
 * Initialize the address to name translation machinery.  We map all
838
 * non-local IP addresses to numeric addresses if fflag is true (i.e.,
839
 * to prevent blocking on the nameserver).  localnet is the IP address
840
 * of the local network.  mask is its subnet mask.
841
 */
842
void
843
init_addrtoname(u_int32_t localnet, u_int32_t mask)
844
{
845
	netmask = mask;
846
	if (fflag) {
847
		f_localnet = localnet;
848
		f_netmask = mask;
849
	}
850
851
	init_servarray();
852
	init_ipprotoarray();
853
854
	if (nflag)
855
		/*
856
		 * Simplest way to suppress names.
857
		 */
858
		return;
859
860
	init_etherarray();
861
	init_eprotoarray();
862
	init_llcsaparray();
863
	init_protoidarray();
864
}
865
866
char *
867
dnaddr_string(u_short dnaddr)
868
{
869
	struct hnamemem *tp;
870
871
	for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0;
872
	     tp = tp->nxt)
873
		if (tp->addr == dnaddr)
874
			return (tp->name);
875
876
	tp->addr = dnaddr;
877
	tp->nxt = newhnamemem();
878
	if (nflag)
879
		tp->name = dnnum_string(dnaddr);
880
	else
881
		tp->name = dnname_string(dnaddr);
882
883
	return(tp->name);
884
}
885
886
/* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
887
struct hnamemem *
888
newhnamemem(void)
889
{
890
	struct hnamemem *p;
891
	static struct hnamemem *ptr = NULL;
892
	static u_int num = 0;
893
894
	if (num  <= 0) {
895
		num = 64;
896
		ptr = calloc(num, sizeof (*ptr));
897
		if (ptr == NULL)
898
			error("newhnamemem: calloc");
899
	}
900
	--num;
901
	p = ptr++;
902
	return (p);
903
}
904
905
#ifdef INET6
906
/* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */
907
struct h6namemem *
908
newh6namemem(void)
909
{
910
	struct h6namemem *p;
911
	static struct h6namemem *ptr = NULL;
912
	static u_int num = 0;
913
914
	if (num  <= 0) {
915
		num = 64;
916
		ptr = calloc(num, sizeof (*ptr));
917
		if (ptr == NULL)
918
			error("newh6namemem: calloc");
919
	}
920
	--num;
921
	p = ptr++;
922
	return (p);
923
}
924
#endif /* INET6 */