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