xref: /openbsd/lib/libpcap/nametoaddr.c (revision 9b113833)
1*9b113833Smickey /*	$OpenBSD: nametoaddr.c,v 1.4 1996/07/12 13:19:09 mickey Exp $	*/
2df930be7Sderaadt 
3df930be7Sderaadt /*
4*9b113833Smickey  * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
5df930be7Sderaadt  *	The Regents of the University of California.  All rights reserved.
6df930be7Sderaadt  *
7df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
8df930be7Sderaadt  * modification, are permitted provided that: (1) source code distributions
9df930be7Sderaadt  * retain the above copyright notice and this paragraph in its entirety, (2)
10df930be7Sderaadt  * distributions including binary code include the above copyright notice and
11df930be7Sderaadt  * this paragraph in its entirety in the documentation or other materials
12df930be7Sderaadt  * provided with the distribution, and (3) all advertising materials mentioning
13df930be7Sderaadt  * features or use of this software display the following acknowledgement:
14df930be7Sderaadt  * ``This product includes software developed by the University of California,
15df930be7Sderaadt  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16df930be7Sderaadt  * the University nor the names of its contributors may be used to endorse
17df930be7Sderaadt  * or promote products derived from this software without specific prior
18df930be7Sderaadt  * written permission.
19df930be7Sderaadt  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20df930be7Sderaadt  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21df930be7Sderaadt  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22df930be7Sderaadt  *
23df930be7Sderaadt  * Name to id translation routines used by the scanner.
24df930be7Sderaadt  * These functions are not time critical.
25df930be7Sderaadt  */
26df930be7Sderaadt 
27df930be7Sderaadt #ifndef lint
28df930be7Sderaadt static char rcsid[] =
29*9b113833Smickey     "@(#) Header: nametoaddr.c,v 1.38 96/06/17 02:42:50 leres Exp (LBL)";
30df930be7Sderaadt #endif
31df930be7Sderaadt 
32df930be7Sderaadt #include <sys/param.h>
33df930be7Sderaadt #include <sys/socket.h>
34*9b113833Smickey 
35*9b113833Smickey #if __STDC__
36*9b113833Smickey struct mbuf;
37*9b113833Smickey struct rtentry;
38*9b113833Smickey #endif
39*9b113833Smickey 
40df930be7Sderaadt #include <net/if.h>
41df930be7Sderaadt #include <netinet/in.h>
42df930be7Sderaadt #include <netinet/if_ether.h>
43df930be7Sderaadt #include <arpa/inet.h>
44df930be7Sderaadt 
45df930be7Sderaadt #include <ctype.h>
46df930be7Sderaadt #include <errno.h>
47*9b113833Smickey #include <stdlib.h>
48*9b113833Smickey #include <memory.h>
49df930be7Sderaadt #include <netdb.h>
50df930be7Sderaadt #include <pcap.h>
51df930be7Sderaadt #include <pcap-namedb.h>
52df930be7Sderaadt #include <stdio.h>
53*9b113833Smickey 
54*9b113833Smickey #ifdef HAVE_OS_PROTO_H
55*9b113833Smickey #include "os-proto.h"
56df930be7Sderaadt #endif
57df930be7Sderaadt 
58*9b113833Smickey #include "pcap-int.h"
59df930be7Sderaadt #include "gencode.h"
60df930be7Sderaadt 
61df930be7Sderaadt #ifndef NTOHL
62df930be7Sderaadt #define NTOHL(x) (x) = ntohl(x)
63df930be7Sderaadt #define NTOHS(x) (x) = ntohs(x)
64df930be7Sderaadt #endif
65df930be7Sderaadt 
66df930be7Sderaadt static inline int xdtoi(int);
67df930be7Sderaadt 
68df930be7Sderaadt /*
69df930be7Sderaadt  *  Convert host name to internet address.
70df930be7Sderaadt  *  Return 0 upon failure.
71df930be7Sderaadt  */
72*9b113833Smickey bpf_u_int32 **
73df930be7Sderaadt pcap_nametoaddr(const char *name)
74df930be7Sderaadt {
75df930be7Sderaadt #ifndef h_addr
76*9b113833Smickey 	static bpf_u_int32 *hlist[2];
77df930be7Sderaadt #endif
78*9b113833Smickey 	bpf_u_int32 **p;
79df930be7Sderaadt 	struct hostent *hp;
80df930be7Sderaadt 
81df930be7Sderaadt 	if ((hp = gethostbyname(name)) != NULL) {
82df930be7Sderaadt #ifndef h_addr
83*9b113833Smickey 		hlist[0] = (bpf_u_int32 *)hp->h_addr;
84df930be7Sderaadt 		NTOHL(hp->h_addr);
85df930be7Sderaadt 		return hlist;
86df930be7Sderaadt #else
87*9b113833Smickey 		for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
88df930be7Sderaadt 			NTOHL(**p);
89*9b113833Smickey 		return (bpf_u_int32 **)hp->h_addr_list;
90df930be7Sderaadt #endif
91df930be7Sderaadt 	}
92df930be7Sderaadt 	else
93df930be7Sderaadt 		return 0;
94df930be7Sderaadt }
95df930be7Sderaadt 
96df930be7Sderaadt /*
97df930be7Sderaadt  *  Convert net name to internet address.
98df930be7Sderaadt  *  Return 0 upon failure.
99df930be7Sderaadt  */
100*9b113833Smickey bpf_u_int32
101df930be7Sderaadt pcap_nametonetaddr(const char *name)
102df930be7Sderaadt {
103df930be7Sderaadt 	struct netent *np;
104df930be7Sderaadt 
105df930be7Sderaadt 	if ((np = getnetbyname(name)) != NULL)
106df930be7Sderaadt 		return np->n_net;
107df930be7Sderaadt 	else
108df930be7Sderaadt 		return 0;
109df930be7Sderaadt }
110df930be7Sderaadt 
111df930be7Sderaadt /*
112df930be7Sderaadt  * Convert a port name to its port and protocol numbers.
113df930be7Sderaadt  * We assume only TCP or UDP.
114df930be7Sderaadt  * Return 0 upon failure.
115df930be7Sderaadt  */
116df930be7Sderaadt int
117df930be7Sderaadt pcap_nametoport(const char *name, int *port, int *proto)
118df930be7Sderaadt {
119df930be7Sderaadt 	struct servent *sp;
120df930be7Sderaadt 	char *other;
121df930be7Sderaadt 
122df930be7Sderaadt 	sp = getservbyname(name, (char *)0);
123df930be7Sderaadt 	if (sp != NULL) {
124df930be7Sderaadt 		NTOHS(sp->s_port);
125df930be7Sderaadt 		*port = sp->s_port;
126df930be7Sderaadt 		*proto = pcap_nametoproto(sp->s_proto);
127df930be7Sderaadt 		/*
128df930be7Sderaadt 		 * We need to check /etc/services for ambiguous entries.
129df930be7Sderaadt 		 * If we find the ambiguous entry, and it has the
130df930be7Sderaadt 		 * same port number, change the proto to PROTO_UNDEF
131df930be7Sderaadt 		 * so both TCP and UDP will be checked.
132df930be7Sderaadt 		 */
133df930be7Sderaadt 		if (*proto == IPPROTO_TCP)
134df930be7Sderaadt 			other = "udp";
135df930be7Sderaadt 		else
136df930be7Sderaadt 			other = "tcp";
137df930be7Sderaadt 
138df930be7Sderaadt 		sp = getservbyname(name, other);
139df930be7Sderaadt 		if (sp != 0) {
140df930be7Sderaadt 			NTOHS(sp->s_port);
141*9b113833Smickey #ifdef notdef
142df930be7Sderaadt 			if (*port != sp->s_port)
143df930be7Sderaadt 				/* Can't handle ambiguous names that refer
144df930be7Sderaadt 				   to different port numbers. */
145df930be7Sderaadt 				warning("ambiguous port %s in /etc/services",
146df930be7Sderaadt 					name);
147df930be7Sderaadt #endif
148df930be7Sderaadt 			*proto = PROTO_UNDEF;
149df930be7Sderaadt 		}
150df930be7Sderaadt 		return 1;
151df930be7Sderaadt 	}
152df930be7Sderaadt #if defined(ultrix) || defined(__osf__)
153df930be7Sderaadt 	/* Special hack in case NFS isn't in /etc/services */
154df930be7Sderaadt 	if (strcmp(name, "nfs") == 0) {
155df930be7Sderaadt 		*port = 2049;
156df930be7Sderaadt 		*proto = PROTO_UNDEF;
157df930be7Sderaadt 		return 1;
158df930be7Sderaadt 	}
159df930be7Sderaadt #endif
160df930be7Sderaadt 	return 0;
161df930be7Sderaadt }
162df930be7Sderaadt 
163df930be7Sderaadt int
164df930be7Sderaadt pcap_nametoproto(const char *str)
165df930be7Sderaadt {
166df930be7Sderaadt 	struct protoent *p;
167df930be7Sderaadt 
168df930be7Sderaadt 	p = getprotobyname(str);
169df930be7Sderaadt 	if (p != 0)
170df930be7Sderaadt 		return p->p_proto;
171df930be7Sderaadt 	else
172df930be7Sderaadt 		return PROTO_UNDEF;
173df930be7Sderaadt }
174df930be7Sderaadt 
175df930be7Sderaadt #include "ethertype.h"
176df930be7Sderaadt 
177df930be7Sderaadt struct eproto {
178df930be7Sderaadt 	char *s;
179df930be7Sderaadt 	u_short p;
180df930be7Sderaadt };
181df930be7Sderaadt 
182df930be7Sderaadt /* Static data base of ether protocol types. */
183df930be7Sderaadt struct eproto eproto_db[] = {
184df930be7Sderaadt 	{ "pup", ETHERTYPE_PUP },
185df930be7Sderaadt 	{ "xns", ETHERTYPE_NS },
186df930be7Sderaadt 	{ "ip", ETHERTYPE_IP },
187df930be7Sderaadt 	{ "arp", ETHERTYPE_ARP },
188df930be7Sderaadt 	{ "rarp", ETHERTYPE_REVARP },
189df930be7Sderaadt 	{ "sprite", ETHERTYPE_SPRITE },
190df930be7Sderaadt 	{ "mopdl", ETHERTYPE_MOPDL },
191df930be7Sderaadt 	{ "moprc", ETHERTYPE_MOPRC },
192df930be7Sderaadt 	{ "decnet", ETHERTYPE_DN },
193df930be7Sderaadt 	{ "lat", ETHERTYPE_LAT },
194df930be7Sderaadt 	{ "lanbridge", ETHERTYPE_LANBRIDGE },
195df930be7Sderaadt 	{ "vexp", ETHERTYPE_VEXP },
196df930be7Sderaadt 	{ "vprod", ETHERTYPE_VPROD },
197df930be7Sderaadt 	{ "atalk", ETHERTYPE_ATALK },
198df930be7Sderaadt 	{ "atalkarp", ETHERTYPE_AARP },
199df930be7Sderaadt 	{ "loopback", ETHERTYPE_LOOPBACK },
200df930be7Sderaadt 	{ "decdts", ETHERTYPE_DECDTS },
201df930be7Sderaadt 	{ "decdns", ETHERTYPE_DECDNS },
202df930be7Sderaadt 	{ (char *)0, 0 }
203df930be7Sderaadt };
204df930be7Sderaadt 
205df930be7Sderaadt int
206df930be7Sderaadt pcap_nametoeproto(const char *s)
207df930be7Sderaadt {
208df930be7Sderaadt 	struct eproto *p = eproto_db;
209df930be7Sderaadt 
210df930be7Sderaadt 	while (p->s != 0) {
211df930be7Sderaadt 		if (strcmp(p->s, s) == 0)
212df930be7Sderaadt 			return p->p;
213df930be7Sderaadt 		p += 1;
214df930be7Sderaadt 	}
215df930be7Sderaadt 	return PROTO_UNDEF;
216df930be7Sderaadt }
217df930be7Sderaadt 
218df930be7Sderaadt /* Hex digit to integer. */
219df930be7Sderaadt static inline int
220df930be7Sderaadt xdtoi(c)
221df930be7Sderaadt 	register int c;
222df930be7Sderaadt {
223df930be7Sderaadt 	if (isdigit(c))
224df930be7Sderaadt 		return c - '0';
225df930be7Sderaadt 	else if (islower(c))
226df930be7Sderaadt 		return c - 'a' + 10;
227df930be7Sderaadt 	else
228df930be7Sderaadt 		return c - 'A' + 10;
229df930be7Sderaadt }
230df930be7Sderaadt 
231*9b113833Smickey bpf_u_int32
232df930be7Sderaadt __pcap_atoin(const char *s)
233df930be7Sderaadt {
234*9b113833Smickey 	bpf_u_int32 addr = 0;
235df930be7Sderaadt 	u_int n;
236df930be7Sderaadt 
237df930be7Sderaadt 	while (1) {
238df930be7Sderaadt 		n = 0;
239df930be7Sderaadt 		while (*s && *s != '.')
240df930be7Sderaadt 			n = n * 10 + *s++ - '0';
241df930be7Sderaadt 		addr <<= 8;
242df930be7Sderaadt 		addr |= n & 0xff;
243df930be7Sderaadt 		if (*s == '\0')
244df930be7Sderaadt 			return addr;
245df930be7Sderaadt 		++s;
246df930be7Sderaadt 	}
247df930be7Sderaadt 	/* NOTREACHED */
248df930be7Sderaadt }
249df930be7Sderaadt 
250*9b113833Smickey bpf_u_int32
251df930be7Sderaadt __pcap_atodn(const char *s)
252df930be7Sderaadt {
253df930be7Sderaadt #define AREASHIFT 10
254df930be7Sderaadt #define AREAMASK 0176000
255df930be7Sderaadt #define NODEMASK 01777
256df930be7Sderaadt 
257*9b113833Smickey 	bpf_u_int32 addr = 0;
258df930be7Sderaadt 	u_int node, area;
259df930be7Sderaadt 
260df930be7Sderaadt 	if (sscanf((char *)s, "%d.%d", &area, &node) != 2)
261df930be7Sderaadt 		bpf_error("malformed decnet address '%s'", s);
262df930be7Sderaadt 
263df930be7Sderaadt 	addr = (area << AREASHIFT) & AREAMASK;
264df930be7Sderaadt 	addr |= (node & NODEMASK);
265df930be7Sderaadt 
266df930be7Sderaadt 	return(addr);
267df930be7Sderaadt }
268df930be7Sderaadt 
269df930be7Sderaadt /*
270df930be7Sderaadt  * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
271df930be7Sderaadt  * ethernet address.  Assumes 's' is well formed.
272df930be7Sderaadt  */
273df930be7Sderaadt u_char *
274df930be7Sderaadt pcap_ether_aton(const char *s)
275df930be7Sderaadt {
276df930be7Sderaadt 	register u_char *ep, *e;
277df930be7Sderaadt 	register u_int d;
278df930be7Sderaadt 
279df930be7Sderaadt 	e = ep = (u_char *)malloc(6);
280df930be7Sderaadt 
281df930be7Sderaadt 	while (*s) {
282df930be7Sderaadt 		if (*s == ':')
283df930be7Sderaadt 			s += 1;
284df930be7Sderaadt 		d = xdtoi(*s++);
285df930be7Sderaadt 		if (isxdigit(*s)) {
286df930be7Sderaadt 			d <<= 4;
287df930be7Sderaadt 			d |= xdtoi(*s++);
288df930be7Sderaadt 		}
289df930be7Sderaadt 		*ep++ = d;
290df930be7Sderaadt 	}
291df930be7Sderaadt 
292df930be7Sderaadt 	return (e);
293df930be7Sderaadt }
294df930be7Sderaadt 
295*9b113833Smickey #ifndef HAVE_ETHER_HOSTTON
296df930be7Sderaadt /* Roll our own */
297df930be7Sderaadt u_char *
298df930be7Sderaadt pcap_ether_hostton(const char *name)
299df930be7Sderaadt {
300df930be7Sderaadt 	register struct pcap_etherent *ep;
301df930be7Sderaadt 	register u_char *ap;
302df930be7Sderaadt 	static FILE *fp = NULL;
303df930be7Sderaadt 	static init = 0;
304df930be7Sderaadt 
305df930be7Sderaadt 	if (!init) {
306df930be7Sderaadt 		fp = fopen(PCAP_ETHERS_FILE, "r");
307df930be7Sderaadt 		++init;
308df930be7Sderaadt 		if (fp == NULL)
309df930be7Sderaadt 			return (NULL);
310df930be7Sderaadt 	} else if (fp == NULL)
311df930be7Sderaadt 		return (NULL);
312df930be7Sderaadt 	else
313df930be7Sderaadt 		rewind(fp);
314df930be7Sderaadt 
315df930be7Sderaadt 	while ((ep = pcap_next_etherent(fp)) != NULL) {
316df930be7Sderaadt 		if (strcmp(ep->name, name) == 0) {
317df930be7Sderaadt 			ap = (u_char *)malloc(6);
318df930be7Sderaadt 			if (ap != NULL) {
319df930be7Sderaadt 				memcpy(ap, ep->addr, 6);
320df930be7Sderaadt 				return (ap);
321df930be7Sderaadt 			}
322df930be7Sderaadt 			break;
323df930be7Sderaadt 		}
324df930be7Sderaadt 	}
325df930be7Sderaadt 	return (NULL);
326df930be7Sderaadt }
327df930be7Sderaadt #else
328*9b113833Smickey 
329*9b113833Smickey #ifndef sgi
330*9b113833Smickey extern int ether_hostton(char *, struct ether_addr *);
331*9b113833Smickey #endif
332*9b113833Smickey 
333df930be7Sderaadt /* Use the os supplied routines */
334df930be7Sderaadt u_char *
335df930be7Sderaadt pcap_ether_hostton(const char *name)
336df930be7Sderaadt {
337df930be7Sderaadt 	register u_char *ap;
338df930be7Sderaadt 	u_char a[6];
339df930be7Sderaadt 
340df930be7Sderaadt 	ap = NULL;
341df930be7Sderaadt 	if (ether_hostton((char *)name, (struct ether_addr *)a) == 0) {
342df930be7Sderaadt 		ap = (u_char *)malloc(6);
343df930be7Sderaadt 		if (ap != NULL)
344df930be7Sderaadt 			memcpy(ap, a, 6);
345df930be7Sderaadt 	}
346df930be7Sderaadt 	return (ap);
347df930be7Sderaadt }
348df930be7Sderaadt #endif
349df930be7Sderaadt 
350df930be7Sderaadt u_short
351df930be7Sderaadt __pcap_nametodnaddr(const char *name)
352df930be7Sderaadt {
353df930be7Sderaadt #ifdef	DECNETLIB
354df930be7Sderaadt 	struct nodeent *getnodebyname();
355df930be7Sderaadt 	struct nodeent *nep;
356df930be7Sderaadt 	unsigned short res;
357df930be7Sderaadt 
358df930be7Sderaadt 	nep = getnodebyname(name);
359df930be7Sderaadt 	if (nep == ((struct nodeent *)0))
360df930be7Sderaadt 		bpf_error("unknown decnet host name '%s'\n", name);
361df930be7Sderaadt 
362df930be7Sderaadt 	memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
363df930be7Sderaadt 	return(res);
364df930be7Sderaadt #else
365df930be7Sderaadt 	bpf_error("decnet name support not included, '%s' cannot be translated\n",
366df930be7Sderaadt 		name);
367df930be7Sderaadt #endif
368df930be7Sderaadt }
369