blob: 194ff45b7588378b16d8eb4352687e1db4fa3768 [file] [log] [blame]
The Android Open Source Project478ab6c2009-03-03 19:30:05 -08001/*
2 * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the University of California,
13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
16 * written permission.
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * Name to id translation routines used by the scanner.
22 * These functions are not time critical.
23 */
24
The Android Open Source Project478ab6c2009-03-03 19:30:05 -080025#ifdef HAVE_CONFIG_H
Haibo Huang165065a2018-07-23 17:26:52 -070026#include <config.h>
The Android Open Source Project478ab6c2009-03-03 19:30:05 -080027#endif
28
JP Abgrall511eca32014-02-12 13:46:45 -080029#ifdef DECNETLIB
30#include <sys/types.h>
31#include <netdnet/dnetdb.h>
32#endif
33
Elliott Hughes965a4b52017-05-15 10:37:39 -070034#ifdef _WIN32
Haibo Huang165065a2018-07-23 17:26:52 -070035 #include <winsock2.h>
36 #include <ws2tcpip.h>
The Android Open Source Project478ab6c2009-03-03 19:30:05 -080037
Haibo Huang165065a2018-07-23 17:26:52 -070038 #ifdef INET6
39 /*
40 * To quote the MSDN page for getaddrinfo() at
41 *
42 * https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
43 *
44 * "Support for getaddrinfo on Windows 2000 and older versions
45 * The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
46 * later. To execute an application that uses this function on earlier
47 * versions of Windows, then you need to include the Ws2tcpip.h and
48 * Wspiapi.h files. When the Wspiapi.h include file is added, the
49 * getaddrinfo function is defined to the WspiapiGetAddrInfo inline
50 * function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
51 * function is implemented in such a way that if the Ws2_32.dll or the
52 * Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
53 * Preview for Windows 2000) does not include getaddrinfo, then a
54 * version of getaddrinfo is implemented inline based on code in the
55 * Wspiapi.h header file. This inline code will be used on older Windows
56 * platforms that do not natively support the getaddrinfo function."
57 *
58 * We use getaddrinfo(), so we include Wspiapi.h here.
59 */
60 #include <wspiapi.h>
61 #endif /* INET6 */
Elliott Hughes965a4b52017-05-15 10:37:39 -070062#else /* _WIN32 */
Haibo Huang165065a2018-07-23 17:26:52 -070063 #include <sys/param.h>
64 #include <sys/types.h>
65 #include <sys/socket.h>
66 #include <sys/time.h>
The Android Open Source Project478ab6c2009-03-03 19:30:05 -080067
Haibo Huang165065a2018-07-23 17:26:52 -070068 #include <netinet/in.h>
The Android Open Source Project478ab6c2009-03-03 19:30:05 -080069
Haibo Huang165065a2018-07-23 17:26:52 -070070 #ifdef HAVE_ETHER_HOSTTON
71 #if defined(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON)
72 /*
73 * OK, just include <net/ethernet.h>.
74 */
75 #include <net/ethernet.h>
76 #elif defined(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON)
77 /*
78 * OK, just include <netinet/ether.h>
79 */
80 #include <netinet/ether.h>
81 #elif defined(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON)
82 /*
83 * OK, just include <sys/ethernet.h>
84 */
85 #include <sys/ethernet.h>
86 #elif defined(ARPA_INET_H_DECLARES_ETHER_HOSTTON)
87 /*
88 * OK, just include <arpa/inet.h>
89 */
90 #include <arpa/inet.h>
91 #elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON)
92 /*
93 * OK, include <netinet/if_ether.h>, after all the other stuff we
94 * need to include or define for its benefit.
95 */
96 #define NEED_NETINET_IF_ETHER_H
97 #else
98 /*
99 * We'll have to declare it ourselves.
100 * If <netinet/if_ether.h> defines struct ether_addr, include
101 * it. Otherwise, define it ourselves.
102 */
103 #ifdef HAVE_STRUCT_ETHER_ADDR
104 #define NEED_NETINET_IF_ETHER_H
105 #else /* HAVE_STRUCT_ETHER_ADDR */
106 struct ether_addr {
107 unsigned char ether_addr_octet[6];
108 };
109 #endif /* HAVE_STRUCT_ETHER_ADDR */
110 #endif /* what declares ether_hostton() */
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800111
Haibo Huang165065a2018-07-23 17:26:52 -0700112 #ifdef NEED_NETINET_IF_ETHER_H
113 #include <net/if.h> /* Needed on some platforms */
114 #include <netinet/in.h> /* Needed on some platforms */
115 #include <netinet/if_ether.h>
116 #endif /* NEED_NETINET_IF_ETHER_H */
117
118 #ifndef HAVE_DECL_ETHER_HOSTTON
119 /*
120 * No header declares it, so declare it ourselves.
121 */
122 extern int ether_hostton(const char *, struct ether_addr *);
123 #endif /* !defined(HAVE_DECL_ETHER_HOSTTON) */
124 #endif /* HAVE_ETHER_HOSTTON */
125
126 #include <arpa/inet.h>
127 #include <netdb.h>
Elliott Hughes965a4b52017-05-15 10:37:39 -0700128#endif /* _WIN32 */
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800129
130#include <ctype.h>
131#include <errno.h>
132#include <stdlib.h>
133#include <string.h>
134#include <stdio.h>
135
136#include "pcap-int.h"
137
138#include "gencode.h"
JP Abgrall511eca32014-02-12 13:46:45 -0800139#include <pcap/namedb.h>
Elliott Hughes965a4b52017-05-15 10:37:39 -0700140#include "nametoaddr.h"
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800141
142#ifdef HAVE_OS_PROTO_H
143#include "os-proto.h"
144#endif
145
146#ifndef NTOHL
147#define NTOHL(x) (x) = ntohl(x)
148#define NTOHS(x) (x) = ntohs(x)
149#endif
150
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800151/*
152 * Convert host name to internet address.
153 * Return 0 upon failure.
Haibo Huang165065a2018-07-23 17:26:52 -0700154 * XXX - not thread-safe; don't use it inside libpcap.
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800155 */
156bpf_u_int32 **
157pcap_nametoaddr(const char *name)
158{
159#ifndef h_addr
160 static bpf_u_int32 *hlist[2];
161#endif
162 bpf_u_int32 **p;
163 struct hostent *hp;
164
165 if ((hp = gethostbyname(name)) != NULL) {
166#ifndef h_addr
167 hlist[0] = (bpf_u_int32 *)hp->h_addr;
168 NTOHL(hp->h_addr);
169 return hlist;
170#else
171 for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
172 NTOHL(**p);
173 return (bpf_u_int32 **)hp->h_addr_list;
174#endif
175 }
176 else
177 return 0;
178}
179
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800180struct addrinfo *
181pcap_nametoaddrinfo(const char *name)
182{
183 struct addrinfo hints, *res;
184 int error;
185
186 memset(&hints, 0, sizeof(hints));
187 hints.ai_family = PF_UNSPEC;
188 hints.ai_socktype = SOCK_STREAM; /*not really*/
189 hints.ai_protocol = IPPROTO_TCP; /*not really*/
190 error = getaddrinfo(name, NULL, &hints, &res);
191 if (error)
192 return NULL;
193 else
194 return res;
195}
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800196
197/*
198 * Convert net name to internet address.
199 * Return 0 upon failure.
Haibo Huang165065a2018-07-23 17:26:52 -0700200 * XXX - not guaranteed to be thread-safe! See below for platforms
201 * on which it is thread-safe and on which it isn't.
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800202 */
203bpf_u_int32
204pcap_nametonetaddr(const char *name)
205{
Haibo Huang165065a2018-07-23 17:26:52 -0700206#ifdef _WIN32
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800207 /*
208 * There's no "getnetbyname()" on Windows.
Elliott Hughes965a4b52017-05-15 10:37:39 -0700209 *
210 * XXX - I guess we could use the BSD code to read
211 * C:\Windows\System32\drivers\etc/networks, assuming
212 * that's its home on all the versions of Windows
213 * we use, but that file probably just has the loopback
214 * network on 127/24 on 99 44/100% of Windows machines.
215 *
216 * (Heck, these days it probably just has that on 99 44/100%
217 * of *UN*X* machines.)
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800218 */
219 return 0;
Haibo Huang165065a2018-07-23 17:26:52 -0700220#else
221 /*
222 * UN*X.
223 */
224 struct netent *np;
225 #if defined(HAVE_LINUX_GETNETBYNAME_R)
226 /*
227 * We have Linux's reentrant getnetbyname_r().
228 */
229 struct netent result_buf;
230 char buf[1024]; /* arbitrary size */
231 int h_errnoval;
232 int err;
233
234 err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
235 &h_errnoval);
236 if (err != 0) {
237 /*
238 * XXX - dynamically allocate the buffer, and make it
239 * bigger if we get ERANGE back?
240 */
241 return 0;
242 }
243 #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
244 /*
245 * We have Solaris's and IRIX's reentrant getnetbyname_r().
246 */
247 struct netent result_buf;
248 char buf[1024]; /* arbitrary size */
249
250 np = getnetbyname_r(name, &result_buf, buf, (int)sizeof buf);
251 #elif defined(HAVE_AIX_GETNETBYNAME_R)
252 /*
253 * We have AIX's reentrant getnetbyname_r().
254 */
255 struct netent result_buf;
256 struct netent_data net_data;
257
258 if (getnetbyname_r(name, &result_buf, &net_data) == -1)
259 np = NULL;
260 else
261 np = &result_buf;
262 #else
263 /*
264 * We don't have any getnetbyname_r(); either we have a
265 * getnetbyname() that uses thread-specific data, in which
266 * case we're thread-safe (sufficiently recent FreeBSD,
267 * sufficiently recent Darwin-based OS, sufficiently recent
268 * HP-UX, sufficiently recent Tru64 UNIX), or we have the
269 * traditional getnetbyname() (everything else, including
270 * current NetBSD and OpenBSD), in which case we're not
271 * thread-safe.
272 */
273 np = getnetbyname(name);
274 #endif
275 if (np != NULL)
276 return np->n_net;
277 else
278 return 0;
279#endif /* _WIN32 */
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800280}
281
282/*
283 * Convert a port name to its port and protocol numbers.
284 * We assume only TCP or UDP.
285 * Return 0 upon failure.
286 */
287int
288pcap_nametoport(const char *name, int *port, int *proto)
289{
Haibo Huang165065a2018-07-23 17:26:52 -0700290 struct addrinfo hints, *res, *ai;
291 int error;
292 struct sockaddr_in *in4;
293#ifdef INET6
294 struct sockaddr_in6 *in6;
295#endif
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800296 int tcp_port = -1;
297 int udp_port = -1;
298
299 /*
Haibo Huang165065a2018-07-23 17:26:52 -0700300 * We check for both TCP and UDP in case there are
301 * ambiguous entries.
302 */
303 memset(&hints, 0, sizeof(hints));
304 hints.ai_family = PF_UNSPEC;
305 hints.ai_socktype = SOCK_STREAM;
306 hints.ai_protocol = IPPROTO_TCP;
307 error = getaddrinfo(NULL, name, &hints, &res);
308 if (error != 0) {
309 if (error != EAI_NONAME &&
310 error != EAI_SERVICE) {
311 /*
312 * This is a real error, not just "there's
313 * no such service name".
314 * XXX - this doesn't return an error string.
315 */
316 return 0;
317 }
318 } else {
319 /*
320 * OK, we found it. Did it find anything?
321 */
322 for (ai = res; ai != NULL; ai = ai->ai_next) {
323 /*
324 * Does it have an address?
325 */
326 if (ai->ai_addr != NULL) {
327 /*
328 * Yes. Get a port number; we're done.
329 */
330 if (ai->ai_addr->sa_family == AF_INET) {
331 in4 = (struct sockaddr_in *)ai->ai_addr;
332 tcp_port = ntohs(in4->sin_port);
333 break;
334 }
335#ifdef INET6
336 if (ai->ai_addr->sa_family == AF_INET6) {
337 in6 = (struct sockaddr_in6 *)ai->ai_addr;
338 tcp_port = ntohs(in6->sin6_port);
339 break;
340 }
341#endif
342 }
343 }
344 freeaddrinfo(res);
345 }
346
347 memset(&hints, 0, sizeof(hints));
348 hints.ai_family = PF_UNSPEC;
349 hints.ai_socktype = SOCK_DGRAM;
350 hints.ai_protocol = IPPROTO_UDP;
351 error = getaddrinfo(NULL, name, &hints, &res);
352 if (error != 0) {
353 if (error != EAI_NONAME &&
354 error != EAI_SERVICE) {
355 /*
356 * This is a real error, not just "there's
357 * no such service name".
358 * XXX - this doesn't return an error string.
359 */
360 return 0;
361 }
362 } else {
363 /*
364 * OK, we found it. Did it find anything?
365 */
366 for (ai = res; ai != NULL; ai = ai->ai_next) {
367 /*
368 * Does it have an address?
369 */
370 if (ai->ai_addr != NULL) {
371 /*
372 * Yes. Get a port number; we're done.
373 */
374 if (ai->ai_addr->sa_family == AF_INET) {
375 in4 = (struct sockaddr_in *)ai->ai_addr;
376 udp_port = ntohs(in4->sin_port);
377 break;
378 }
379#ifdef INET6
380 if (ai->ai_addr->sa_family == AF_INET6) {
381 in6 = (struct sockaddr_in6 *)ai->ai_addr;
382 udp_port = ntohs(in6->sin6_port);
383 break;
384 }
385#endif
386 }
387 }
388 freeaddrinfo(res);
389 }
390
391 /*
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800392 * We need to check /etc/services for ambiguous entries.
Haibo Huang165065a2018-07-23 17:26:52 -0700393 * If we find an ambiguous entry, and it has the
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800394 * same port number, change the proto to PROTO_UNDEF
395 * so both TCP and UDP will be checked.
396 */
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800397 if (tcp_port >= 0) {
398 *port = tcp_port;
399 *proto = IPPROTO_TCP;
400 if (udp_port >= 0) {
401 if (udp_port == tcp_port)
402 *proto = PROTO_UNDEF;
403#ifdef notdef
404 else
405 /* Can't handle ambiguous names that refer
406 to different port numbers. */
407 warning("ambiguous port %s in /etc/services",
408 name);
409#endif
410 }
411 return 1;
412 }
413 if (udp_port >= 0) {
414 *port = udp_port;
415 *proto = IPPROTO_UDP;
416 return 1;
417 }
418#if defined(ultrix) || defined(__osf__)
419 /* Special hack in case NFS isn't in /etc/services */
420 if (strcmp(name, "nfs") == 0) {
421 *port = 2049;
422 *proto = PROTO_UNDEF;
423 return 1;
424 }
425#endif
426 return 0;
427}
428
429/*
430 * Convert a string in the form PPP-PPP, where correspond to ports, to
431 * a starting and ending port in a port range.
432 * Return 0 on failure.
433 */
434int
435pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
436{
437 u_int p1, p2;
438 char *off, *cpy;
439 int save_proto;
440
441 if (sscanf(name, "%d-%d", &p1, &p2) != 2) {
442 if ((cpy = strdup(name)) == NULL)
443 return 0;
444
445 if ((off = strchr(cpy, '-')) == NULL) {
446 free(cpy);
447 return 0;
448 }
449
450 *off = '\0';
451
452 if (pcap_nametoport(cpy, port1, proto) == 0) {
453 free(cpy);
454 return 0;
455 }
456 save_proto = *proto;
457
458 if (pcap_nametoport(off + 1, port2, proto) == 0) {
459 free(cpy);
460 return 0;
461 }
JP Abgrall511eca32014-02-12 13:46:45 -0800462 free(cpy);
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800463
464 if (*proto != save_proto)
465 *proto = PROTO_UNDEF;
466 } else {
467 *port1 = p1;
468 *port2 = p2;
469 *proto = PROTO_UNDEF;
470 }
471
472 return 1;
473}
474
Haibo Huang165065a2018-07-23 17:26:52 -0700475/*
476 * XXX - not guaranteed to be thread-safe! See below for platforms
477 * on which it is thread-safe and on which it isn't.
478 */
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800479int
480pcap_nametoproto(const char *str)
481{
482 struct protoent *p;
Haibo Huang165065a2018-07-23 17:26:52 -0700483 #if defined(HAVE_LINUX_GETNETBYNAME_R)
484 /*
485 * We have Linux's reentrant getprotobyname_r().
486 */
487 struct protoent result_buf;
488 char buf[1024]; /* arbitrary size */
489 int err;
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800490
Haibo Huang165065a2018-07-23 17:26:52 -0700491 err = getprotobyname_r(str, &result_buf, buf, sizeof buf, &p);
492 if (err != 0) {
493 /*
494 * XXX - dynamically allocate the buffer, and make it
495 * bigger if we get ERANGE back?
496 */
497 return 0;
498 }
499 #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
500 /*
501 * We have Solaris's and IRIX's reentrant getprotobyname_r().
502 */
503 struct protoent result_buf;
504 char buf[1024]; /* arbitrary size */
505
506 p = getprotobyname_r(str, &result_buf, buf, (int)sizeof buf);
507 #elif defined(HAVE_AIX_GETNETBYNAME_R)
508 /*
509 * We have AIX's reentrant getprotobyname_r().
510 */
511 struct protoent result_buf;
512 struct protoent_data proto_data;
513
514 if (getprotobyname_r(str, &result_buf, &proto_data) == -1)
515 p = NULL;
516 else
517 p = &result_buf;
518 #else
519 /*
520 * We don't have any getprotobyname_r(); either we have a
521 * getprotobyname() that uses thread-specific data, in which
522 * case we're thread-safe (sufficiently recent FreeBSD,
523 * sufficiently recent Darwin-based OS, sufficiently recent
524 * HP-UX, sufficiently recent Tru64 UNIX, Windows), or we have
525 * the traditional getprotobyname() (everything else, including
526 * current NetBSD and OpenBSD), in which case we're not
527 * thread-safe.
528 */
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800529 p = getprotobyname(str);
Haibo Huang165065a2018-07-23 17:26:52 -0700530 #endif
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800531 if (p != 0)
532 return p->p_proto;
533 else
534 return PROTO_UNDEF;
535}
536
537#include "ethertype.h"
538
539struct eproto {
540 const char *s;
541 u_short p;
542};
543
Elliott Hughes965a4b52017-05-15 10:37:39 -0700544/*
545 * Static data base of ether protocol types.
546 * tcpdump used to import this, and it's declared as an export on
547 * Debian, at least, so make it a public symbol, even though we
548 * don't officially export it by declaring it in a header file.
549 * (Programs *should* do this themselves, as tcpdump now does.)
Haibo Huang165065a2018-07-23 17:26:52 -0700550 *
551 * We declare it here, right before defining it, to squelch any
552 * warnings we might get from compilers about the lack of a
553 * declaration.
Elliott Hughes965a4b52017-05-15 10:37:39 -0700554 */
Haibo Huang165065a2018-07-23 17:26:52 -0700555PCAP_API struct eproto eproto_db[];
Elliott Hughes965a4b52017-05-15 10:37:39 -0700556PCAP_API_DEF struct eproto eproto_db[] = {
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800557 { "pup", ETHERTYPE_PUP },
558 { "xns", ETHERTYPE_NS },
559 { "ip", ETHERTYPE_IP },
560#ifdef INET6
561 { "ip6", ETHERTYPE_IPV6 },
562#endif
563 { "arp", ETHERTYPE_ARP },
564 { "rarp", ETHERTYPE_REVARP },
565 { "sprite", ETHERTYPE_SPRITE },
566 { "mopdl", ETHERTYPE_MOPDL },
567 { "moprc", ETHERTYPE_MOPRC },
568 { "decnet", ETHERTYPE_DN },
569 { "lat", ETHERTYPE_LAT },
570 { "sca", ETHERTYPE_SCA },
571 { "lanbridge", ETHERTYPE_LANBRIDGE },
572 { "vexp", ETHERTYPE_VEXP },
573 { "vprod", ETHERTYPE_VPROD },
574 { "atalk", ETHERTYPE_ATALK },
575 { "atalkarp", ETHERTYPE_AARP },
576 { "loopback", ETHERTYPE_LOOPBACK },
577 { "decdts", ETHERTYPE_DECDTS },
578 { "decdns", ETHERTYPE_DECDNS },
579 { (char *)0, 0 }
580};
581
582int
583pcap_nametoeproto(const char *s)
584{
585 struct eproto *p = eproto_db;
586
587 while (p->s != 0) {
588 if (strcmp(p->s, s) == 0)
589 return p->p;
590 p += 1;
591 }
592 return PROTO_UNDEF;
593}
594
595#include "llc.h"
596
597/* Static data base of LLC values. */
598static struct eproto llc_db[] = {
599 { "iso", LLCSAP_ISONS },
600 { "stp", LLCSAP_8021D },
601 { "ipx", LLCSAP_IPX },
602 { "netbeui", LLCSAP_NETBEUI },
603 { (char *)0, 0 }
604};
605
606int
607pcap_nametollc(const char *s)
608{
609 struct eproto *p = llc_db;
610
611 while (p->s != 0) {
612 if (strcmp(p->s, s) == 0)
613 return p->p;
614 p += 1;
615 }
616 return PROTO_UNDEF;
617}
618
Haibo Huang165065a2018-07-23 17:26:52 -0700619/* Hex digit to 8-bit unsigned integer. */
620static inline u_char
621xdtoi(u_char c)
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800622{
623 if (isdigit(c))
Haibo Huang165065a2018-07-23 17:26:52 -0700624 return (u_char)(c - '0');
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800625 else if (islower(c))
Haibo Huang165065a2018-07-23 17:26:52 -0700626 return (u_char)(c - 'a' + 10);
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800627 else
Haibo Huang165065a2018-07-23 17:26:52 -0700628 return (u_char)(c - 'A' + 10);
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800629}
630
631int
632__pcap_atoin(const char *s, bpf_u_int32 *addr)
633{
634 u_int n;
635 int len;
636
637 *addr = 0;
638 len = 0;
Haibo Huang165065a2018-07-23 17:26:52 -0700639 for (;;) {
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800640 n = 0;
641 while (*s && *s != '.')
642 n = n * 10 + *s++ - '0';
643 *addr <<= 8;
644 *addr |= n & 0xff;
645 len += 8;
646 if (*s == '\0')
647 return len;
648 ++s;
649 }
650 /* NOTREACHED */
651}
652
653int
654__pcap_atodn(const char *s, bpf_u_int32 *addr)
655{
656#define AREASHIFT 10
657#define AREAMASK 0176000
658#define NODEMASK 01777
659
660 u_int node, area;
661
662 if (sscanf(s, "%d.%d", &area, &node) != 2)
Elliott Hughes965a4b52017-05-15 10:37:39 -0700663 return(0);
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800664
665 *addr = (area << AREASHIFT) & AREAMASK;
666 *addr |= (node & NODEMASK);
667
668 return(32);
669}
670
671/*
JP Abgrall511eca32014-02-12 13:46:45 -0800672 * Convert 's', which can have the one of the forms:
673 *
674 * "xx:xx:xx:xx:xx:xx"
675 * "xx.xx.xx.xx.xx.xx"
676 * "xx-xx-xx-xx-xx-xx"
677 * "xxxx.xxxx.xxxx"
678 * "xxxxxxxxxxxx"
679 *
680 * (or various mixes of ':', '.', and '-') into a new
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800681 * ethernet address. Assumes 's' is well formed.
682 */
683u_char *
684pcap_ether_aton(const char *s)
685{
686 register u_char *ep, *e;
Haibo Huang165065a2018-07-23 17:26:52 -0700687 register u_char d;
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800688
689 e = ep = (u_char *)malloc(6);
JP Abgrall511eca32014-02-12 13:46:45 -0800690 if (e == NULL)
691 return (NULL);
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800692
693 while (*s) {
JP Abgrall511eca32014-02-12 13:46:45 -0800694 if (*s == ':' || *s == '.' || *s == '-')
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800695 s += 1;
696 d = xdtoi(*s++);
697 if (isxdigit((unsigned char)*s)) {
698 d <<= 4;
699 d |= xdtoi(*s++);
700 }
701 *ep++ = d;
702 }
703
704 return (e);
705}
706
707#ifndef HAVE_ETHER_HOSTTON
Haibo Huang165065a2018-07-23 17:26:52 -0700708/*
709 * Roll our own.
710 * XXX - not thread-safe, because pcap_next_etherent() isn't thread-
711 * safe! Needs a mutex or a thread-safe pcap_next_etherent().
712 */
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800713u_char *
714pcap_ether_hostton(const char *name)
715{
716 register struct pcap_etherent *ep;
717 register u_char *ap;
718 static FILE *fp = NULL;
719 static int init = 0;
720
721 if (!init) {
722 fp = fopen(PCAP_ETHERS_FILE, "r");
723 ++init;
724 if (fp == NULL)
725 return (NULL);
726 } else if (fp == NULL)
727 return (NULL);
728 else
729 rewind(fp);
730
731 while ((ep = pcap_next_etherent(fp)) != NULL) {
732 if (strcmp(ep->name, name) == 0) {
733 ap = (u_char *)malloc(6);
734 if (ap != NULL) {
735 memcpy(ap, ep->addr, 6);
736 return (ap);
737 }
738 break;
739 }
740 }
741 return (NULL);
742}
743#else
Haibo Huang165065a2018-07-23 17:26:52 -0700744/*
745 * Use the OS-supplied routine.
746 * This *should* be thread-safe; the API doesn't have a static buffer.
747 */
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800748u_char *
749pcap_ether_hostton(const char *name)
750{
751 register u_char *ap;
752 u_char a[6];
753
754 ap = NULL;
755 if (ether_hostton(name, (struct ether_addr *)a) == 0) {
756 ap = (u_char *)malloc(6);
757 if (ap != NULL)
758 memcpy((char *)ap, (char *)a, 6);
759 }
760 return (ap);
761}
762#endif
763
Haibo Huang165065a2018-07-23 17:26:52 -0700764/*
765 * XXX - not guaranteed to be thread-safe!
766 */
Elliott Hughes965a4b52017-05-15 10:37:39 -0700767int
Haibo Huang165065a2018-07-23 17:26:52 -0700768#ifdef DECNETLIB
Elliott Hughes965a4b52017-05-15 10:37:39 -0700769__pcap_nametodnaddr(const char *name, u_short *res)
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800770{
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800771 struct nodeent *getnodebyname();
772 struct nodeent *nep;
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800773
774 nep = getnodebyname(name);
775 if (nep == ((struct nodeent *)0))
Elliott Hughes965a4b52017-05-15 10:37:39 -0700776 return(0);
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800777
Elliott Hughes965a4b52017-05-15 10:37:39 -0700778 memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
779 return(1);
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800780#else
Haibo Huang165065a2018-07-23 17:26:52 -0700781__pcap_nametodnaddr(const char *name _U_, u_short *res _U_)
782{
The Android Open Source Project478ab6c2009-03-03 19:30:05 -0800783 return(0);
784#endif
785}