1 /* $OpenBSD: nametoaddr.c,v 1.25 2024/04/05 18:01:56 deraadt Exp $ */
2
3 /*
4 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
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 * Name to id translation routines used by the scanner.
24 * These functions are not time critical.
25 */
26
27 #include <sys/types.h> /* concession to AIX */
28 #include <sys/socket.h>
29 #include <sys/time.h>
30
31 #include <net/if.h>
32 #include <netinet/in.h>
33 #include <netinet/if_ether.h>
34 #include <arpa/inet.h>
35
36 #include <ctype.h>
37 #include <errno.h>
38 #include <stdlib.h>
39 #include <netdb.h>
40 #include <stdio.h>
41 #include <string.h>
42
43 #include "pcap-int.h"
44
45 #include "gencode.h"
46 #include <pcap-namedb.h>
47
48 #ifdef HAVE_OS_PROTO_H
49 #include "os-proto.h"
50 #endif
51
52 #ifndef NTOHL
53 #define NTOHL(x) (x) = ntohl(x)
54 #define NTOHS(x) (x) = ntohs(x)
55 #endif
56
57 static __inline int xdtoi(int);
58
59 /*
60 * Convert host name to internet address.
61 * Return 0 upon failure.
62 */
63 bpf_u_int32 **
pcap_nametoaddr(const char * name)64 pcap_nametoaddr(const char *name)
65 {
66 #ifndef h_addr
67 static bpf_u_int32 *hlist[2];
68 #endif
69 bpf_u_int32 **p;
70 struct hostent *hp;
71
72 if ((hp = gethostbyname(name)) != NULL) {
73 #ifndef h_addr
74 hlist[0] = (bpf_u_int32 *)hp->h_addr;
75 NTOHL(hp->h_addr);
76 return hlist;
77 #else
78 for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
79 NTOHL(**p);
80 return (bpf_u_int32 **)hp->h_addr_list;
81 #endif
82 }
83 else
84 return 0;
85 }
86
87 #ifdef INET6
88 struct addrinfo *
pcap_nametoaddrinfo(const char * name)89 pcap_nametoaddrinfo(const char *name)
90 {
91 struct addrinfo hints, *res;
92 int error;
93
94 memset(&hints, 0, sizeof(hints));
95 hints.ai_family = PF_UNSPEC;
96 hints.ai_socktype = SOCK_STREAM; /*not really*/
97 error = getaddrinfo(name, NULL, &hints, &res);
98 if (error)
99 return NULL;
100 else
101 return res;
102 }
103 #endif /*INET6*/
104
105 /*
106 * Convert net name to internet address.
107 * Return 0 upon failure.
108 */
109 bpf_u_int32
pcap_nametonetaddr(const char * name)110 pcap_nametonetaddr(const char *name)
111 {
112 struct netent *np;
113
114 if ((np = getnetbyname(name)) != NULL)
115 return np->n_net;
116 else
117 return 0;
118 }
119
120 /*
121 * Convert a port name to its port and protocol numbers.
122 * We assume only TCP or UDP.
123 * Return 0 upon failure.
124 */
125 int
pcap_nametoport(const char * name,int * port,int * proto)126 pcap_nametoport(const char *name, int *port, int *proto)
127 {
128 struct servent *sp;
129 char *other;
130
131 sp = getservbyname(name, (char *)0);
132 if (sp != NULL) {
133 NTOHS(sp->s_port);
134 *port = sp->s_port;
135 *proto = pcap_nametoproto(sp->s_proto);
136 /*
137 * We need to check /etc/services for ambiguous entries.
138 * If we find the ambiguous entry, and it has the
139 * same port number, change the proto to PROTO_UNDEF
140 * so both TCP and UDP will be checked.
141 */
142 if (*proto == IPPROTO_TCP)
143 other = "udp";
144 else
145 other = "tcp";
146
147 sp = getservbyname(name, other);
148 if (sp != 0) {
149 NTOHS(sp->s_port);
150 #ifdef notdef
151 if (*port != sp->s_port)
152 /* Can't handle ambiguous names that refer
153 to different port numbers. */
154 warning("ambiguous port %s in /etc/services",
155 name);
156 #endif
157 *proto = PROTO_UNDEF;
158 }
159 return 1;
160 }
161 #if defined(ultrix) || defined(__osf__)
162 /* Special hack in case NFS isn't in /etc/services */
163 if (strcmp(name, "nfs") == 0) {
164 *port = 2049;
165 *proto = PROTO_UNDEF;
166 return 1;
167 }
168 #endif
169 return 0;
170 }
171
172 int
pcap_nametoproto(const char * str)173 pcap_nametoproto(const char *str)
174 {
175 struct protoent *p;
176
177 p = getprotobyname(str);
178 if (p != 0)
179 return p->p_proto;
180 else
181 return PROTO_UNDEF;
182 }
183
184 #include "ethertype.h"
185
186 struct eproto {
187 char *s;
188 u_short p;
189 };
190
191 /* Static data base of ether protocol types. */
192 static const struct eproto _eproto_db[] = {
193 { "pup", ETHERTYPE_PUP },
194 { "xns", ETHERTYPE_NS },
195 { "ip", ETHERTYPE_IP },
196 #ifdef INET6
197 { "ip6", ETHERTYPE_IPV6 },
198 #endif
199 { "arp", ETHERTYPE_ARP },
200 { "rarp", ETHERTYPE_REVARP },
201 { "lldp", ETHERTYPE_LLDP },
202 { "slow", ETHERTYPE_SLOW },
203 { "sprite", ETHERTYPE_SPRITE },
204 { "mopdl", ETHERTYPE_MOPDL },
205 { "moprc", ETHERTYPE_MOPRC },
206 { "decnet", ETHERTYPE_DN },
207 { "lat", ETHERTYPE_LAT },
208 { "sca", ETHERTYPE_SCA },
209 { "lanbridge", ETHERTYPE_LANBRIDGE },
210 { "vexp", ETHERTYPE_VEXP },
211 { "vprod", ETHERTYPE_VPROD },
212 { "atalk", ETHERTYPE_ATALK },
213 { "atalkarp", ETHERTYPE_AARP },
214 { "loopback", ETHERTYPE_LOOPBACK },
215 { "decdts", ETHERTYPE_DECDTS },
216 { "decdns", ETHERTYPE_DECDNS },
217 { (char *)0, 0 }
218 };
219 /* Accessor for tcpdump */
220 const struct eproto * const eproto_db = _eproto_db;
221
222 int
pcap_nametoeproto(const char * s)223 pcap_nametoeproto(const char *s)
224 {
225 const struct eproto *p = _eproto_db;
226
227 while (p->s != 0) {
228 if (strcmp(p->s, s) == 0)
229 return p->p;
230 p += 1;
231 }
232 return PROTO_UNDEF;
233 }
234
235 #include "llc.h"
236
237 /* Static data base of LLC values. */
238 static const struct eproto llc_db[] = {
239 { "stp", LLCSAP_8021D },
240 { (char *)0, 0 }
241 };
242
243 int
pcap_nametollc(const char * s)244 pcap_nametollc(const char *s)
245 {
246 const struct eproto *p = llc_db;
247
248 while (p->s != 0) {
249 if (strcmp(p->s, s) == 0)
250 return p->p;
251 p += 1;
252 }
253 return PROTO_UNDEF;
254 }
255
256 /* Hex digit to integer. */
257 static __inline int
xdtoi(int c)258 xdtoi(int c)
259 {
260 if (isdigit(c))
261 return c - '0';
262 else if (islower(c))
263 return c - 'a' + 10;
264 else
265 return c - 'A' + 10;
266 }
267
268 int
__pcap_atoin(const char * s,bpf_u_int32 * addr)269 __pcap_atoin(const char *s, bpf_u_int32 *addr)
270 {
271 u_int n;
272 int len;
273
274 *addr = 0;
275 len = 0;
276 while (1) {
277 n = 0;
278 while (*s && *s != '.')
279 n = n * 10 + *s++ - '0';
280 *addr <<= 8;
281 *addr |= n & 0xff;
282 len += 8;
283 if (*s == '\0')
284 return len;
285 ++s;
286 }
287 /* NOTREACHED */
288 }
289
290 int
__pcap_atodn(const char * s,bpf_u_int32 * addr)291 __pcap_atodn(const char *s, bpf_u_int32 *addr)
292 {
293 #define AREASHIFT 10
294 #define AREAMASK 0176000
295 #define NODEMASK 01777
296
297 u_int node, area;
298
299 if (sscanf((char *)s, "%d.%d", &area, &node) != 2)
300 bpf_error("malformed decnet address '%s'", s);
301
302 *addr = (area << AREASHIFT) & AREAMASK;
303 *addr |= (node & NODEMASK);
304
305 return(32);
306 }
307
308 /*
309 * Convert 's' which has the form "xx:xx:xx:xx:xx:xx" into a new
310 * ethernet address. Assumes 's' is well formed.
311 */
312 u_char *
pcap_ether_aton(const char * s)313 pcap_ether_aton(const char *s)
314 {
315 u_char *ep, *e;
316 u_int d;
317
318 e = ep = malloc(6);
319 if (e == NULL)
320 bpf_error("malloc");
321
322 while (*s) {
323 if (*s == ':')
324 s += 1;
325 d = xdtoi(*s++);
326 if (isxdigit((unsigned char)*s)) {
327 d <<= 4;
328 d |= xdtoi(*s++);
329 }
330 *ep++ = d;
331 }
332
333 return (e);
334 }
335
336 #ifndef HAVE_ETHER_HOSTTON
337 /* Roll our own */
338 u_char *
pcap_ether_hostton(const char * name)339 pcap_ether_hostton(const char *name)
340 {
341 struct pcap_etherent *ep;
342 u_char *ap;
343 static FILE *fp = NULL;
344 static init = 0;
345
346 if (!init) {
347 fp = fopen(PCAP_ETHERS_FILE, "r");
348 ++init;
349 if (fp == NULL)
350 return (NULL);
351 } else if (fp == NULL)
352 return (NULL);
353 else
354 rewind(fp);
355
356 while ((ep = pcap_next_etherent(fp)) != NULL) {
357 if (strcmp(ep->name, name) == 0) {
358 ap = malloc(6);
359 if (ap != NULL) {
360 memcpy(ap, ep->addr, 6);
361 return (ap);
362 }
363 break;
364 }
365 }
366 return (NULL);
367 }
368 #else
369
370 /* Use the os supplied routines */
371 u_char *
pcap_ether_hostton(const char * name)372 pcap_ether_hostton(const char *name)
373 {
374 u_char *ap;
375 u_char a[6];
376
377 ap = NULL;
378 if (ether_hostton(name, (struct ether_addr *)a) == 0) {
379 ap = malloc(6);
380 if (ap != NULL)
381 memcpy((char *)ap, (char *)a, 6);
382 }
383 return (ap);
384 }
385 #endif
386
387 u_short
__pcap_nametodnaddr(const char * name)388 __pcap_nametodnaddr(const char *name)
389 {
390 #ifdef DECNETLIB
391 struct nodeent *getnodebyname();
392 struct nodeent *nep;
393 unsigned short res;
394
395 nep = getnodebyname(name);
396 if (nep == ((struct nodeent *)0))
397 bpf_error("unknown decnet host name '%s'\n", name);
398
399 memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
400 return(res);
401 #else
402 bpf_error("decnet name support not included, '%s' cannot be translated\n",
403 name);
404 /* NOTREACHED */
405 #endif
406 }
407