xref: /minix3/external/bsd/libpcap/dist/nametoaddr.c (revision d56f51ea7d8b9045e5c8e2028422523d3f9a5840)
1*d56f51eaSDavid van Moolenbroek /*	$NetBSD: nametoaddr.c,v 1.2 2014/11/19 19:33:30 christos Exp $	*/
2*d56f51eaSDavid van Moolenbroek 
3*d56f51eaSDavid van Moolenbroek /*
4*d56f51eaSDavid van Moolenbroek  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
5*d56f51eaSDavid van Moolenbroek  *	The Regents of the University of California.  All rights reserved.
6*d56f51eaSDavid van Moolenbroek  *
7*d56f51eaSDavid van Moolenbroek  * Redistribution and use in source and binary forms, with or without
8*d56f51eaSDavid van Moolenbroek  * modification, are permitted provided that: (1) source code distributions
9*d56f51eaSDavid van Moolenbroek  * retain the above copyright notice and this paragraph in its entirety, (2)
10*d56f51eaSDavid van Moolenbroek  * distributions including binary code include the above copyright notice and
11*d56f51eaSDavid van Moolenbroek  * this paragraph in its entirety in the documentation or other materials
12*d56f51eaSDavid van Moolenbroek  * provided with the distribution, and (3) all advertising materials mentioning
13*d56f51eaSDavid van Moolenbroek  * features or use of this software display the following acknowledgement:
14*d56f51eaSDavid van Moolenbroek  * ``This product includes software developed by the University of California,
15*d56f51eaSDavid van Moolenbroek  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16*d56f51eaSDavid van Moolenbroek  * the University nor the names of its contributors may be used to endorse
17*d56f51eaSDavid van Moolenbroek  * or promote products derived from this software without specific prior
18*d56f51eaSDavid van Moolenbroek  * written permission.
19*d56f51eaSDavid van Moolenbroek  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20*d56f51eaSDavid van Moolenbroek  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21*d56f51eaSDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22*d56f51eaSDavid van Moolenbroek  *
23*d56f51eaSDavid van Moolenbroek  * Name to id translation routines used by the scanner.
24*d56f51eaSDavid van Moolenbroek  * These functions are not time critical.
25*d56f51eaSDavid van Moolenbroek  */
26*d56f51eaSDavid van Moolenbroek 
27*d56f51eaSDavid van Moolenbroek #include <sys/cdefs.h>
28*d56f51eaSDavid van Moolenbroek __RCSID("$NetBSD: nametoaddr.c,v 1.2 2014/11/19 19:33:30 christos Exp $");
29*d56f51eaSDavid van Moolenbroek 
30*d56f51eaSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
31*d56f51eaSDavid van Moolenbroek #include "config.h"
32*d56f51eaSDavid van Moolenbroek #endif
33*d56f51eaSDavid van Moolenbroek 
34*d56f51eaSDavid van Moolenbroek #ifdef DECNETLIB
35*d56f51eaSDavid van Moolenbroek #include <sys/types.h>
36*d56f51eaSDavid van Moolenbroek #include <netdnet/dnetdb.h>
37*d56f51eaSDavid van Moolenbroek #endif
38*d56f51eaSDavid van Moolenbroek 
39*d56f51eaSDavid van Moolenbroek #ifdef WIN32
40*d56f51eaSDavid van Moolenbroek #include <pcap-stdinc.h>
41*d56f51eaSDavid van Moolenbroek 
42*d56f51eaSDavid van Moolenbroek #else /* WIN32 */
43*d56f51eaSDavid van Moolenbroek 
44*d56f51eaSDavid van Moolenbroek #include <sys/param.h>
45*d56f51eaSDavid van Moolenbroek #include <sys/types.h>				/* concession to AIX */
46*d56f51eaSDavid van Moolenbroek #include <sys/socket.h>
47*d56f51eaSDavid van Moolenbroek #include <sys/time.h>
48*d56f51eaSDavid van Moolenbroek 
49*d56f51eaSDavid van Moolenbroek #include <netinet/in.h>
50*d56f51eaSDavid van Moolenbroek #endif /* WIN32 */
51*d56f51eaSDavid van Moolenbroek 
52*d56f51eaSDavid van Moolenbroek #ifndef WIN32
53*d56f51eaSDavid van Moolenbroek #ifdef HAVE_ETHER_HOSTTON
54*d56f51eaSDavid van Moolenbroek /*
55*d56f51eaSDavid van Moolenbroek  * XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
56*d56f51eaSDavid van Moolenbroek  * ether_hostton()?
57*d56f51eaSDavid van Moolenbroek  */
58*d56f51eaSDavid van Moolenbroek #ifdef HAVE_NETINET_IF_ETHER_H
59*d56f51eaSDavid van Moolenbroek struct mbuf;		/* Squelch compiler warnings on some platforms for */
60*d56f51eaSDavid van Moolenbroek struct rtentry;		/* declarations in <net/if.h> */
61*d56f51eaSDavid van Moolenbroek #include <net/if.h>	/* for "struct ifnet" in "struct arpcom" on Solaris */
62*d56f51eaSDavid van Moolenbroek #include <netinet/if_ether.h>
63*d56f51eaSDavid van Moolenbroek #endif /* HAVE_NETINET_IF_ETHER_H */
64*d56f51eaSDavid van Moolenbroek #ifdef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
65*d56f51eaSDavid van Moolenbroek #include <netinet/ether.h>
66*d56f51eaSDavid van Moolenbroek #endif /* NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
67*d56f51eaSDavid van Moolenbroek #endif /* HAVE_ETHER_HOSTTON */
68*d56f51eaSDavid van Moolenbroek #include <arpa/inet.h>
69*d56f51eaSDavid van Moolenbroek #include <netdb.h>
70*d56f51eaSDavid van Moolenbroek #endif /* WIN32 */
71*d56f51eaSDavid van Moolenbroek 
72*d56f51eaSDavid van Moolenbroek #include <ctype.h>
73*d56f51eaSDavid van Moolenbroek #include <errno.h>
74*d56f51eaSDavid van Moolenbroek #include <stdlib.h>
75*d56f51eaSDavid van Moolenbroek #include <string.h>
76*d56f51eaSDavid van Moolenbroek #include <stdio.h>
77*d56f51eaSDavid van Moolenbroek 
78*d56f51eaSDavid van Moolenbroek #include "pcap-int.h"
79*d56f51eaSDavid van Moolenbroek 
80*d56f51eaSDavid van Moolenbroek #include "gencode.h"
81*d56f51eaSDavid van Moolenbroek #include <pcap/namedb.h>
82*d56f51eaSDavid van Moolenbroek 
83*d56f51eaSDavid van Moolenbroek #ifdef HAVE_OS_PROTO_H
84*d56f51eaSDavid van Moolenbroek #include "os-proto.h"
85*d56f51eaSDavid van Moolenbroek #endif
86*d56f51eaSDavid van Moolenbroek 
87*d56f51eaSDavid van Moolenbroek #ifndef NTOHL
88*d56f51eaSDavid van Moolenbroek #define NTOHL(x) (x) = ntohl(x)
89*d56f51eaSDavid van Moolenbroek #define NTOHS(x) (x) = ntohs(x)
90*d56f51eaSDavid van Moolenbroek #endif
91*d56f51eaSDavid van Moolenbroek 
92*d56f51eaSDavid van Moolenbroek static inline int xdtoi(int);
93*d56f51eaSDavid van Moolenbroek 
94*d56f51eaSDavid van Moolenbroek /*
95*d56f51eaSDavid van Moolenbroek  *  Convert host name to internet address.
96*d56f51eaSDavid van Moolenbroek  *  Return 0 upon failure.
97*d56f51eaSDavid van Moolenbroek  */
98*d56f51eaSDavid van Moolenbroek bpf_u_int32 **
pcap_nametoaddr(const char * name)99*d56f51eaSDavid van Moolenbroek pcap_nametoaddr(const char *name)
100*d56f51eaSDavid van Moolenbroek {
101*d56f51eaSDavid van Moolenbroek #ifndef h_addr
102*d56f51eaSDavid van Moolenbroek 	static bpf_u_int32 *hlist[2];
103*d56f51eaSDavid van Moolenbroek #endif
104*d56f51eaSDavid van Moolenbroek 	bpf_u_int32 **p;
105*d56f51eaSDavid van Moolenbroek 	struct hostent *hp;
106*d56f51eaSDavid van Moolenbroek 
107*d56f51eaSDavid van Moolenbroek 	if ((hp = gethostbyname(name)) != NULL) {
108*d56f51eaSDavid van Moolenbroek #ifndef h_addr
109*d56f51eaSDavid van Moolenbroek 		hlist[0] = (bpf_u_int32 *)hp->h_addr;
110*d56f51eaSDavid van Moolenbroek 		NTOHL(hp->h_addr);
111*d56f51eaSDavid van Moolenbroek 		return hlist;
112*d56f51eaSDavid van Moolenbroek #else
113*d56f51eaSDavid van Moolenbroek 		for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
114*d56f51eaSDavid van Moolenbroek 			NTOHL(**p);
115*d56f51eaSDavid van Moolenbroek 		return (bpf_u_int32 **)hp->h_addr_list;
116*d56f51eaSDavid van Moolenbroek #endif
117*d56f51eaSDavid van Moolenbroek 	}
118*d56f51eaSDavid van Moolenbroek 	else
119*d56f51eaSDavid van Moolenbroek 		return 0;
120*d56f51eaSDavid van Moolenbroek }
121*d56f51eaSDavid van Moolenbroek 
122*d56f51eaSDavid van Moolenbroek #ifdef INET6
123*d56f51eaSDavid van Moolenbroek struct addrinfo *
pcap_nametoaddrinfo(const char * name)124*d56f51eaSDavid van Moolenbroek pcap_nametoaddrinfo(const char *name)
125*d56f51eaSDavid van Moolenbroek {
126*d56f51eaSDavid van Moolenbroek 	struct addrinfo hints, *res;
127*d56f51eaSDavid van Moolenbroek 	int error;
128*d56f51eaSDavid van Moolenbroek 
129*d56f51eaSDavid van Moolenbroek 	memset(&hints, 0, sizeof(hints));
130*d56f51eaSDavid van Moolenbroek 	hints.ai_family = PF_UNSPEC;
131*d56f51eaSDavid van Moolenbroek 	hints.ai_socktype = SOCK_STREAM;	/*not really*/
132*d56f51eaSDavid van Moolenbroek 	hints.ai_protocol = IPPROTO_TCP;	/*not really*/
133*d56f51eaSDavid van Moolenbroek 	error = getaddrinfo(name, NULL, &hints, &res);
134*d56f51eaSDavid van Moolenbroek 	if (error)
135*d56f51eaSDavid van Moolenbroek 		return NULL;
136*d56f51eaSDavid van Moolenbroek 	else
137*d56f51eaSDavid van Moolenbroek 		return res;
138*d56f51eaSDavid van Moolenbroek }
139*d56f51eaSDavid van Moolenbroek #endif /*INET6*/
140*d56f51eaSDavid van Moolenbroek 
141*d56f51eaSDavid van Moolenbroek /*
142*d56f51eaSDavid van Moolenbroek  *  Convert net name to internet address.
143*d56f51eaSDavid van Moolenbroek  *  Return 0 upon failure.
144*d56f51eaSDavid van Moolenbroek  */
145*d56f51eaSDavid van Moolenbroek bpf_u_int32
pcap_nametonetaddr(const char * name)146*d56f51eaSDavid van Moolenbroek pcap_nametonetaddr(const char *name)
147*d56f51eaSDavid van Moolenbroek {
148*d56f51eaSDavid van Moolenbroek #ifndef WIN32
149*d56f51eaSDavid van Moolenbroek 	struct netent *np;
150*d56f51eaSDavid van Moolenbroek 
151*d56f51eaSDavid van Moolenbroek 	if ((np = getnetbyname(name)) != NULL)
152*d56f51eaSDavid van Moolenbroek 		return np->n_net;
153*d56f51eaSDavid van Moolenbroek 	else
154*d56f51eaSDavid van Moolenbroek 		return 0;
155*d56f51eaSDavid van Moolenbroek #else
156*d56f51eaSDavid van Moolenbroek 	/*
157*d56f51eaSDavid van Moolenbroek 	 * There's no "getnetbyname()" on Windows.
158*d56f51eaSDavid van Moolenbroek 	 */
159*d56f51eaSDavid van Moolenbroek 	return 0;
160*d56f51eaSDavid van Moolenbroek #endif
161*d56f51eaSDavid van Moolenbroek }
162*d56f51eaSDavid van Moolenbroek 
163*d56f51eaSDavid van Moolenbroek /*
164*d56f51eaSDavid van Moolenbroek  * Convert a port name to its port and protocol numbers.
165*d56f51eaSDavid van Moolenbroek  * We assume only TCP or UDP.
166*d56f51eaSDavid van Moolenbroek  * Return 0 upon failure.
167*d56f51eaSDavid van Moolenbroek  */
168*d56f51eaSDavid van Moolenbroek int
pcap_nametoport(const char * name,int * port,int * proto)169*d56f51eaSDavid van Moolenbroek pcap_nametoport(const char *name, int *port, int *proto)
170*d56f51eaSDavid van Moolenbroek {
171*d56f51eaSDavid van Moolenbroek 	struct servent *sp;
172*d56f51eaSDavid van Moolenbroek 	int tcp_port = -1;
173*d56f51eaSDavid van Moolenbroek 	int udp_port = -1;
174*d56f51eaSDavid van Moolenbroek 
175*d56f51eaSDavid van Moolenbroek 	/*
176*d56f51eaSDavid van Moolenbroek 	 * We need to check /etc/services for ambiguous entries.
177*d56f51eaSDavid van Moolenbroek 	 * If we find the ambiguous entry, and it has the
178*d56f51eaSDavid van Moolenbroek 	 * same port number, change the proto to PROTO_UNDEF
179*d56f51eaSDavid van Moolenbroek 	 * so both TCP and UDP will be checked.
180*d56f51eaSDavid van Moolenbroek 	 */
181*d56f51eaSDavid van Moolenbroek 	sp = getservbyname(name, "tcp");
182*d56f51eaSDavid van Moolenbroek 	if (sp != NULL) tcp_port = ntohs(sp->s_port);
183*d56f51eaSDavid van Moolenbroek 	sp = getservbyname(name, "udp");
184*d56f51eaSDavid van Moolenbroek 	if (sp != NULL) udp_port = ntohs(sp->s_port);
185*d56f51eaSDavid van Moolenbroek 	if (tcp_port >= 0) {
186*d56f51eaSDavid van Moolenbroek 		*port = tcp_port;
187*d56f51eaSDavid van Moolenbroek 		*proto = IPPROTO_TCP;
188*d56f51eaSDavid van Moolenbroek 		if (udp_port >= 0) {
189*d56f51eaSDavid van Moolenbroek 			if (udp_port == tcp_port)
190*d56f51eaSDavid van Moolenbroek 				*proto = PROTO_UNDEF;
191*d56f51eaSDavid van Moolenbroek #ifdef notdef
192*d56f51eaSDavid van Moolenbroek 			else
193*d56f51eaSDavid van Moolenbroek 				/* Can't handle ambiguous names that refer
194*d56f51eaSDavid van Moolenbroek 				   to different port numbers. */
195*d56f51eaSDavid van Moolenbroek 				warning("ambiguous port %s in /etc/services",
196*d56f51eaSDavid van Moolenbroek 					name);
197*d56f51eaSDavid van Moolenbroek #endif
198*d56f51eaSDavid van Moolenbroek 		}
199*d56f51eaSDavid van Moolenbroek 		return 1;
200*d56f51eaSDavid van Moolenbroek 	}
201*d56f51eaSDavid van Moolenbroek 	if (udp_port >= 0) {
202*d56f51eaSDavid van Moolenbroek 		*port = udp_port;
203*d56f51eaSDavid van Moolenbroek 		*proto = IPPROTO_UDP;
204*d56f51eaSDavid van Moolenbroek 		return 1;
205*d56f51eaSDavid van Moolenbroek 	}
206*d56f51eaSDavid van Moolenbroek #if defined(ultrix) || defined(__osf__)
207*d56f51eaSDavid van Moolenbroek 	/* Special hack in case NFS isn't in /etc/services */
208*d56f51eaSDavid van Moolenbroek 	if (strcmp(name, "nfs") == 0) {
209*d56f51eaSDavid van Moolenbroek 		*port = 2049;
210*d56f51eaSDavid van Moolenbroek 		*proto = PROTO_UNDEF;
211*d56f51eaSDavid van Moolenbroek 		return 1;
212*d56f51eaSDavid van Moolenbroek 	}
213*d56f51eaSDavid van Moolenbroek #endif
214*d56f51eaSDavid van Moolenbroek 	return 0;
215*d56f51eaSDavid van Moolenbroek }
216*d56f51eaSDavid van Moolenbroek 
217*d56f51eaSDavid van Moolenbroek /*
218*d56f51eaSDavid van Moolenbroek  * Convert a string in the form PPP-PPP, where correspond to ports, to
219*d56f51eaSDavid van Moolenbroek  * a starting and ending port in a port range.
220*d56f51eaSDavid van Moolenbroek  * Return 0 on failure.
221*d56f51eaSDavid van Moolenbroek  */
222*d56f51eaSDavid van Moolenbroek int
pcap_nametoportrange(const char * name,int * port1,int * port2,int * proto)223*d56f51eaSDavid van Moolenbroek pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
224*d56f51eaSDavid van Moolenbroek {
225*d56f51eaSDavid van Moolenbroek 	u_int p1, p2;
226*d56f51eaSDavid van Moolenbroek 	char *off, *cpy;
227*d56f51eaSDavid van Moolenbroek 	int save_proto;
228*d56f51eaSDavid van Moolenbroek 
229*d56f51eaSDavid van Moolenbroek 	if (sscanf(name, "%d-%d", &p1, &p2) != 2) {
230*d56f51eaSDavid van Moolenbroek 		if ((cpy = strdup(name)) == NULL)
231*d56f51eaSDavid van Moolenbroek 			return 0;
232*d56f51eaSDavid van Moolenbroek 
233*d56f51eaSDavid van Moolenbroek 		if ((off = strchr(cpy, '-')) == NULL) {
234*d56f51eaSDavid van Moolenbroek 			free(cpy);
235*d56f51eaSDavid van Moolenbroek 			return 0;
236*d56f51eaSDavid van Moolenbroek 		}
237*d56f51eaSDavid van Moolenbroek 
238*d56f51eaSDavid van Moolenbroek 		*off = '\0';
239*d56f51eaSDavid van Moolenbroek 
240*d56f51eaSDavid van Moolenbroek 		if (pcap_nametoport(cpy, port1, proto) == 0) {
241*d56f51eaSDavid van Moolenbroek 			free(cpy);
242*d56f51eaSDavid van Moolenbroek 			return 0;
243*d56f51eaSDavid van Moolenbroek 		}
244*d56f51eaSDavid van Moolenbroek 		save_proto = *proto;
245*d56f51eaSDavid van Moolenbroek 
246*d56f51eaSDavid van Moolenbroek 		if (pcap_nametoport(off + 1, port2, proto) == 0) {
247*d56f51eaSDavid van Moolenbroek 			free(cpy);
248*d56f51eaSDavid van Moolenbroek 			return 0;
249*d56f51eaSDavid van Moolenbroek 		}
250*d56f51eaSDavid van Moolenbroek 		free(cpy);
251*d56f51eaSDavid van Moolenbroek 
252*d56f51eaSDavid van Moolenbroek 		if (*proto != save_proto)
253*d56f51eaSDavid van Moolenbroek 			*proto = PROTO_UNDEF;
254*d56f51eaSDavid van Moolenbroek 	} else {
255*d56f51eaSDavid van Moolenbroek 		*port1 = p1;
256*d56f51eaSDavid van Moolenbroek 		*port2 = p2;
257*d56f51eaSDavid van Moolenbroek 		*proto = PROTO_UNDEF;
258*d56f51eaSDavid van Moolenbroek 	}
259*d56f51eaSDavid van Moolenbroek 
260*d56f51eaSDavid van Moolenbroek 	return 1;
261*d56f51eaSDavid van Moolenbroek }
262*d56f51eaSDavid van Moolenbroek 
263*d56f51eaSDavid van Moolenbroek int
pcap_nametoproto(const char * str)264*d56f51eaSDavid van Moolenbroek pcap_nametoproto(const char *str)
265*d56f51eaSDavid van Moolenbroek {
266*d56f51eaSDavid van Moolenbroek 	struct protoent *p;
267*d56f51eaSDavid van Moolenbroek 
268*d56f51eaSDavid van Moolenbroek 	p = getprotobyname(str);
269*d56f51eaSDavid van Moolenbroek 	if (p != 0)
270*d56f51eaSDavid van Moolenbroek 		return p->p_proto;
271*d56f51eaSDavid van Moolenbroek 	else
272*d56f51eaSDavid van Moolenbroek 		return PROTO_UNDEF;
273*d56f51eaSDavid van Moolenbroek }
274*d56f51eaSDavid van Moolenbroek 
275*d56f51eaSDavid van Moolenbroek #include "ethertype.h"
276*d56f51eaSDavid van Moolenbroek 
277*d56f51eaSDavid van Moolenbroek struct eproto {
278*d56f51eaSDavid van Moolenbroek 	const char *s;
279*d56f51eaSDavid van Moolenbroek 	u_short p;
280*d56f51eaSDavid van Moolenbroek };
281*d56f51eaSDavid van Moolenbroek 
282*d56f51eaSDavid van Moolenbroek /* Static data base of ether protocol types. */
283*d56f51eaSDavid van Moolenbroek struct eproto eproto_db[] = {
284*d56f51eaSDavid van Moolenbroek 	{ "pup", ETHERTYPE_PUP },
285*d56f51eaSDavid van Moolenbroek 	{ "xns", ETHERTYPE_NS },
286*d56f51eaSDavid van Moolenbroek 	{ "ip", ETHERTYPE_IP },
287*d56f51eaSDavid van Moolenbroek #ifdef INET6
288*d56f51eaSDavid van Moolenbroek 	{ "ip6", ETHERTYPE_IPV6 },
289*d56f51eaSDavid van Moolenbroek #endif
290*d56f51eaSDavid van Moolenbroek 	{ "arp", ETHERTYPE_ARP },
291*d56f51eaSDavid van Moolenbroek 	{ "rarp", ETHERTYPE_REVARP },
292*d56f51eaSDavid van Moolenbroek 	{ "sprite", ETHERTYPE_SPRITE },
293*d56f51eaSDavid van Moolenbroek 	{ "mopdl", ETHERTYPE_MOPDL },
294*d56f51eaSDavid van Moolenbroek 	{ "moprc", ETHERTYPE_MOPRC },
295*d56f51eaSDavid van Moolenbroek 	{ "decnet", ETHERTYPE_DN },
296*d56f51eaSDavid van Moolenbroek 	{ "lat", ETHERTYPE_LAT },
297*d56f51eaSDavid van Moolenbroek 	{ "sca", ETHERTYPE_SCA },
298*d56f51eaSDavid van Moolenbroek 	{ "lanbridge", ETHERTYPE_LANBRIDGE },
299*d56f51eaSDavid van Moolenbroek 	{ "vexp", ETHERTYPE_VEXP },
300*d56f51eaSDavid van Moolenbroek 	{ "vprod", ETHERTYPE_VPROD },
301*d56f51eaSDavid van Moolenbroek 	{ "atalk", ETHERTYPE_ATALK },
302*d56f51eaSDavid van Moolenbroek 	{ "atalkarp", ETHERTYPE_AARP },
303*d56f51eaSDavid van Moolenbroek 	{ "loopback", ETHERTYPE_LOOPBACK },
304*d56f51eaSDavid van Moolenbroek 	{ "decdts", ETHERTYPE_DECDTS },
305*d56f51eaSDavid van Moolenbroek 	{ "decdns", ETHERTYPE_DECDNS },
306*d56f51eaSDavid van Moolenbroek 	{ (char *)0, 0 }
307*d56f51eaSDavid van Moolenbroek };
308*d56f51eaSDavid van Moolenbroek 
309*d56f51eaSDavid van Moolenbroek int
pcap_nametoeproto(const char * s)310*d56f51eaSDavid van Moolenbroek pcap_nametoeproto(const char *s)
311*d56f51eaSDavid van Moolenbroek {
312*d56f51eaSDavid van Moolenbroek 	struct eproto *p = eproto_db;
313*d56f51eaSDavid van Moolenbroek 
314*d56f51eaSDavid van Moolenbroek 	while (p->s != 0) {
315*d56f51eaSDavid van Moolenbroek 		if (strcmp(p->s, s) == 0)
316*d56f51eaSDavid van Moolenbroek 			return p->p;
317*d56f51eaSDavid van Moolenbroek 		p += 1;
318*d56f51eaSDavid van Moolenbroek 	}
319*d56f51eaSDavid van Moolenbroek 	return PROTO_UNDEF;
320*d56f51eaSDavid van Moolenbroek }
321*d56f51eaSDavid van Moolenbroek 
322*d56f51eaSDavid van Moolenbroek #include "llc.h"
323*d56f51eaSDavid van Moolenbroek 
324*d56f51eaSDavid van Moolenbroek /* Static data base of LLC values. */
325*d56f51eaSDavid van Moolenbroek static struct eproto llc_db[] = {
326*d56f51eaSDavid van Moolenbroek 	{ "iso", LLCSAP_ISONS },
327*d56f51eaSDavid van Moolenbroek 	{ "stp", LLCSAP_8021D },
328*d56f51eaSDavid van Moolenbroek 	{ "ipx", LLCSAP_IPX },
329*d56f51eaSDavid van Moolenbroek 	{ "netbeui", LLCSAP_NETBEUI },
330*d56f51eaSDavid van Moolenbroek 	{ (char *)0, 0 }
331*d56f51eaSDavid van Moolenbroek };
332*d56f51eaSDavid van Moolenbroek 
333*d56f51eaSDavid van Moolenbroek int
pcap_nametollc(const char * s)334*d56f51eaSDavid van Moolenbroek pcap_nametollc(const char *s)
335*d56f51eaSDavid van Moolenbroek {
336*d56f51eaSDavid van Moolenbroek 	struct eproto *p = llc_db;
337*d56f51eaSDavid van Moolenbroek 
338*d56f51eaSDavid van Moolenbroek 	while (p->s != 0) {
339*d56f51eaSDavid van Moolenbroek 		if (strcmp(p->s, s) == 0)
340*d56f51eaSDavid van Moolenbroek 			return p->p;
341*d56f51eaSDavid van Moolenbroek 		p += 1;
342*d56f51eaSDavid van Moolenbroek 	}
343*d56f51eaSDavid van Moolenbroek 	return PROTO_UNDEF;
344*d56f51eaSDavid van Moolenbroek }
345*d56f51eaSDavid van Moolenbroek 
346*d56f51eaSDavid van Moolenbroek /* Hex digit to integer. */
347*d56f51eaSDavid van Moolenbroek static inline int
xdtoi(c)348*d56f51eaSDavid van Moolenbroek xdtoi(c)
349*d56f51eaSDavid van Moolenbroek 	register int c;
350*d56f51eaSDavid van Moolenbroek {
351*d56f51eaSDavid van Moolenbroek 	if (isdigit(c))
352*d56f51eaSDavid van Moolenbroek 		return c - '0';
353*d56f51eaSDavid van Moolenbroek 	else if (islower(c))
354*d56f51eaSDavid van Moolenbroek 		return c - 'a' + 10;
355*d56f51eaSDavid van Moolenbroek 	else
356*d56f51eaSDavid van Moolenbroek 		return c - 'A' + 10;
357*d56f51eaSDavid van Moolenbroek }
358*d56f51eaSDavid van Moolenbroek 
359*d56f51eaSDavid van Moolenbroek int
__pcap_atoin(const char * s,bpf_u_int32 * addr)360*d56f51eaSDavid van Moolenbroek __pcap_atoin(const char *s, bpf_u_int32 *addr)
361*d56f51eaSDavid van Moolenbroek {
362*d56f51eaSDavid van Moolenbroek 	u_int n;
363*d56f51eaSDavid van Moolenbroek 	int len;
364*d56f51eaSDavid van Moolenbroek 
365*d56f51eaSDavid van Moolenbroek 	*addr = 0;
366*d56f51eaSDavid van Moolenbroek 	len = 0;
367*d56f51eaSDavid van Moolenbroek 	while (1) {
368*d56f51eaSDavid van Moolenbroek 		n = 0;
369*d56f51eaSDavid van Moolenbroek 		while (*s && *s != '.')
370*d56f51eaSDavid van Moolenbroek 			n = n * 10 + *s++ - '0';
371*d56f51eaSDavid van Moolenbroek 		*addr <<= 8;
372*d56f51eaSDavid van Moolenbroek 		*addr |= n & 0xff;
373*d56f51eaSDavid van Moolenbroek 		len += 8;
374*d56f51eaSDavid van Moolenbroek 		if (*s == '\0')
375*d56f51eaSDavid van Moolenbroek 			return len;
376*d56f51eaSDavid van Moolenbroek 		++s;
377*d56f51eaSDavid van Moolenbroek 	}
378*d56f51eaSDavid van Moolenbroek 	/* NOTREACHED */
379*d56f51eaSDavid van Moolenbroek }
380*d56f51eaSDavid van Moolenbroek 
381*d56f51eaSDavid van Moolenbroek int
__pcap_atodn(const char * s,bpf_u_int32 * addr)382*d56f51eaSDavid van Moolenbroek __pcap_atodn(const char *s, bpf_u_int32 *addr)
383*d56f51eaSDavid van Moolenbroek {
384*d56f51eaSDavid van Moolenbroek #define AREASHIFT 10
385*d56f51eaSDavid van Moolenbroek #define AREAMASK 0176000
386*d56f51eaSDavid van Moolenbroek #define NODEMASK 01777
387*d56f51eaSDavid van Moolenbroek 
388*d56f51eaSDavid van Moolenbroek 	u_int node, area;
389*d56f51eaSDavid van Moolenbroek 
390*d56f51eaSDavid van Moolenbroek 	if (sscanf(s, "%d.%d", &area, &node) != 2)
391*d56f51eaSDavid van Moolenbroek 		bpf_error("malformed decnet address '%s'", s);
392*d56f51eaSDavid van Moolenbroek 
393*d56f51eaSDavid van Moolenbroek 	*addr = (area << AREASHIFT) & AREAMASK;
394*d56f51eaSDavid van Moolenbroek 	*addr |= (node & NODEMASK);
395*d56f51eaSDavid van Moolenbroek 
396*d56f51eaSDavid van Moolenbroek 	return(32);
397*d56f51eaSDavid van Moolenbroek }
398*d56f51eaSDavid van Moolenbroek 
399*d56f51eaSDavid van Moolenbroek /*
400*d56f51eaSDavid van Moolenbroek  * Convert 's', which can have the one of the forms:
401*d56f51eaSDavid van Moolenbroek  *
402*d56f51eaSDavid van Moolenbroek  *	"xx:xx:xx:xx:xx:xx"
403*d56f51eaSDavid van Moolenbroek  *	"xx.xx.xx.xx.xx.xx"
404*d56f51eaSDavid van Moolenbroek  *	"xx-xx-xx-xx-xx-xx"
405*d56f51eaSDavid van Moolenbroek  *	"xxxx.xxxx.xxxx"
406*d56f51eaSDavid van Moolenbroek  *	"xxxxxxxxxxxx"
407*d56f51eaSDavid van Moolenbroek  *
408*d56f51eaSDavid van Moolenbroek  * (or various mixes of ':', '.', and '-') into a new
409*d56f51eaSDavid van Moolenbroek  * ethernet address.  Assumes 's' is well formed.
410*d56f51eaSDavid van Moolenbroek  */
411*d56f51eaSDavid van Moolenbroek u_char *
pcap_ether_aton(const char * s)412*d56f51eaSDavid van Moolenbroek pcap_ether_aton(const char *s)
413*d56f51eaSDavid van Moolenbroek {
414*d56f51eaSDavid van Moolenbroek 	register u_char *ep, *e;
415*d56f51eaSDavid van Moolenbroek 	register u_int d;
416*d56f51eaSDavid van Moolenbroek 
417*d56f51eaSDavid van Moolenbroek 	e = ep = (u_char *)malloc(6);
418*d56f51eaSDavid van Moolenbroek 	if (e == NULL)
419*d56f51eaSDavid van Moolenbroek 		return (NULL);
420*d56f51eaSDavid van Moolenbroek 
421*d56f51eaSDavid van Moolenbroek 	while (*s) {
422*d56f51eaSDavid van Moolenbroek 		if (*s == ':' || *s == '.' || *s == '-')
423*d56f51eaSDavid van Moolenbroek 			s += 1;
424*d56f51eaSDavid van Moolenbroek 		d = xdtoi(*s++);
425*d56f51eaSDavid van Moolenbroek 		if (isxdigit((unsigned char)*s)) {
426*d56f51eaSDavid van Moolenbroek 			d <<= 4;
427*d56f51eaSDavid van Moolenbroek 			d |= xdtoi(*s++);
428*d56f51eaSDavid van Moolenbroek 		}
429*d56f51eaSDavid van Moolenbroek 		*ep++ = d;
430*d56f51eaSDavid van Moolenbroek 	}
431*d56f51eaSDavid van Moolenbroek 
432*d56f51eaSDavid van Moolenbroek 	return (e);
433*d56f51eaSDavid van Moolenbroek }
434*d56f51eaSDavid van Moolenbroek 
435*d56f51eaSDavid van Moolenbroek #ifndef HAVE_ETHER_HOSTTON
436*d56f51eaSDavid van Moolenbroek /* Roll our own */
437*d56f51eaSDavid van Moolenbroek u_char *
pcap_ether_hostton(const char * name)438*d56f51eaSDavid van Moolenbroek pcap_ether_hostton(const char *name)
439*d56f51eaSDavid van Moolenbroek {
440*d56f51eaSDavid van Moolenbroek 	register struct pcap_etherent *ep;
441*d56f51eaSDavid van Moolenbroek 	register u_char *ap;
442*d56f51eaSDavid van Moolenbroek 	static FILE *fp = NULL;
443*d56f51eaSDavid van Moolenbroek 	static int init = 0;
444*d56f51eaSDavid van Moolenbroek 
445*d56f51eaSDavid van Moolenbroek 	if (!init) {
446*d56f51eaSDavid van Moolenbroek 		fp = fopen(PCAP_ETHERS_FILE, "r");
447*d56f51eaSDavid van Moolenbroek 		++init;
448*d56f51eaSDavid van Moolenbroek 		if (fp == NULL)
449*d56f51eaSDavid van Moolenbroek 			return (NULL);
450*d56f51eaSDavid van Moolenbroek 	} else if (fp == NULL)
451*d56f51eaSDavid van Moolenbroek 		return (NULL);
452*d56f51eaSDavid van Moolenbroek 	else
453*d56f51eaSDavid van Moolenbroek 		rewind(fp);
454*d56f51eaSDavid van Moolenbroek 
455*d56f51eaSDavid van Moolenbroek 	while ((ep = pcap_next_etherent(fp)) != NULL) {
456*d56f51eaSDavid van Moolenbroek 		if (strcmp(ep->name, name) == 0) {
457*d56f51eaSDavid van Moolenbroek 			ap = (u_char *)malloc(6);
458*d56f51eaSDavid van Moolenbroek 			if (ap != NULL) {
459*d56f51eaSDavid van Moolenbroek 				memcpy(ap, ep->addr, 6);
460*d56f51eaSDavid van Moolenbroek 				return (ap);
461*d56f51eaSDavid van Moolenbroek 			}
462*d56f51eaSDavid van Moolenbroek 			break;
463*d56f51eaSDavid van Moolenbroek 		}
464*d56f51eaSDavid van Moolenbroek 	}
465*d56f51eaSDavid van Moolenbroek 	return (NULL);
466*d56f51eaSDavid van Moolenbroek }
467*d56f51eaSDavid van Moolenbroek #else
468*d56f51eaSDavid van Moolenbroek 
469*d56f51eaSDavid van Moolenbroek #if !defined(HAVE_DECL_ETHER_HOSTTON) || !HAVE_DECL_ETHER_HOSTTON
470*d56f51eaSDavid van Moolenbroek #ifndef HAVE_STRUCT_ETHER_ADDR
471*d56f51eaSDavid van Moolenbroek struct ether_addr {
472*d56f51eaSDavid van Moolenbroek 	unsigned char ether_addr_octet[6];
473*d56f51eaSDavid van Moolenbroek };
474*d56f51eaSDavid van Moolenbroek #endif
475*d56f51eaSDavid van Moolenbroek extern int ether_hostton(const char *, struct ether_addr *);
476*d56f51eaSDavid van Moolenbroek #endif
477*d56f51eaSDavid van Moolenbroek 
478*d56f51eaSDavid van Moolenbroek /* Use the os supplied routines */
479*d56f51eaSDavid van Moolenbroek u_char *
pcap_ether_hostton(const char * name)480*d56f51eaSDavid van Moolenbroek pcap_ether_hostton(const char *name)
481*d56f51eaSDavid van Moolenbroek {
482*d56f51eaSDavid van Moolenbroek 	register u_char *ap;
483*d56f51eaSDavid van Moolenbroek 	u_char a[6];
484*d56f51eaSDavid van Moolenbroek 
485*d56f51eaSDavid van Moolenbroek 	ap = NULL;
486*d56f51eaSDavid van Moolenbroek 	if (ether_hostton(name, (struct ether_addr *)a) == 0) {
487*d56f51eaSDavid van Moolenbroek 		ap = (u_char *)malloc(6);
488*d56f51eaSDavid van Moolenbroek 		if (ap != NULL)
489*d56f51eaSDavid van Moolenbroek 			memcpy((char *)ap, (char *)a, 6);
490*d56f51eaSDavid van Moolenbroek 	}
491*d56f51eaSDavid van Moolenbroek 	return (ap);
492*d56f51eaSDavid van Moolenbroek }
493*d56f51eaSDavid van Moolenbroek #endif
494*d56f51eaSDavid van Moolenbroek 
495*d56f51eaSDavid van Moolenbroek u_short
__pcap_nametodnaddr(const char * name)496*d56f51eaSDavid van Moolenbroek __pcap_nametodnaddr(const char *name)
497*d56f51eaSDavid van Moolenbroek {
498*d56f51eaSDavid van Moolenbroek #ifdef	DECNETLIB
499*d56f51eaSDavid van Moolenbroek 	struct nodeent *getnodebyname();
500*d56f51eaSDavid van Moolenbroek 	struct nodeent *nep;
501*d56f51eaSDavid van Moolenbroek 	unsigned short res;
502*d56f51eaSDavid van Moolenbroek 
503*d56f51eaSDavid van Moolenbroek 	nep = getnodebyname(name);
504*d56f51eaSDavid van Moolenbroek 	if (nep == ((struct nodeent *)0))
505*d56f51eaSDavid van Moolenbroek 		bpf_error("unknown decnet host name '%s'\n", name);
506*d56f51eaSDavid van Moolenbroek 
507*d56f51eaSDavid van Moolenbroek 	memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
508*d56f51eaSDavid van Moolenbroek 	return(res);
509*d56f51eaSDavid van Moolenbroek #else
510*d56f51eaSDavid van Moolenbroek 	bpf_error("decnet name support not included, '%s' cannot be translated\n",
511*d56f51eaSDavid van Moolenbroek 		name);
512*d56f51eaSDavid van Moolenbroek 	return(0);
513*d56f51eaSDavid van Moolenbroek #endif
514*d56f51eaSDavid van Moolenbroek }
515