1 /* 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 25 #include <config.h> 26 27 #ifdef DECNETLIB 28 #include <sys/types.h> 29 #include <netdnet/dnetdb.h> 30 #endif 31 32 #ifdef _WIN32 33 #include <winsock2.h> 34 #include <ws2tcpip.h> 35 #else /* _WIN32 */ 36 #include <sys/param.h> 37 #include <sys/types.h> 38 #include <sys/socket.h> 39 #include <sys/time.h> 40 41 #include <netinet/in.h> 42 43 #ifdef HAVE_ETHER_HOSTTON 44 #if defined(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON) 45 /* 46 * OK, just include <net/ethernet.h>. 47 */ 48 #include <net/ethernet.h> 49 #elif defined(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON) 50 /* 51 * OK, just include <netinet/ether.h> 52 */ 53 #include <netinet/ether.h> 54 #elif defined(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON) 55 /* 56 * OK, just include <sys/ethernet.h> 57 */ 58 #include <sys/ethernet.h> 59 #elif defined(ARPA_INET_H_DECLARES_ETHER_HOSTTON) 60 /* 61 * OK, just include <arpa/inet.h> 62 */ 63 #include <arpa/inet.h> 64 #elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON) 65 /* 66 * OK, include <netinet/if_ether.h>, after all the other stuff we 67 * need to include or define for its benefit. 68 */ 69 #define NEED_NETINET_IF_ETHER_H 70 #else 71 /* 72 * We'll have to declare it ourselves. 73 * If <netinet/if_ether.h> defines struct ether_addr, include 74 * it. Otherwise, define it ourselves. 75 */ 76 #ifdef HAVE_STRUCT_ETHER_ADDR 77 #define NEED_NETINET_IF_ETHER_H 78 #else /* HAVE_STRUCT_ETHER_ADDR */ 79 struct ether_addr { 80 unsigned char ether_addr_octet[6]; 81 }; 82 #endif /* HAVE_STRUCT_ETHER_ADDR */ 83 #endif /* what declares ether_hostton() */ 84 85 #ifdef NEED_NETINET_IF_ETHER_H 86 #include <net/if.h> /* Needed on some platforms */ 87 #include <netinet/in.h> /* Needed on some platforms */ 88 #include <netinet/if_ether.h> 89 #endif /* NEED_NETINET_IF_ETHER_H */ 90 91 #ifndef HAVE_DECL_ETHER_HOSTTON 92 /* 93 * No header declares it, so declare it ourselves. 94 */ 95 extern int ether_hostton(const char *, struct ether_addr *); 96 #endif /* !defined(HAVE_DECL_ETHER_HOSTTON) */ 97 #endif /* HAVE_ETHER_HOSTTON */ 98 99 #include <arpa/inet.h> 100 #include <netdb.h> 101 #endif /* _WIN32 */ 102 103 #include <errno.h> 104 #include <stdlib.h> 105 #include <string.h> 106 #include <stdio.h> 107 108 #include "pcap-int.h" 109 110 #include "diag-control.h" 111 112 #include "gencode.h" 113 #include <pcap/namedb.h> 114 #include "nametoaddr.h" 115 116 #include "thread-local.h" 117 118 #ifdef HAVE_OS_PROTO_H 119 #include "os-proto.h" 120 #endif 121 122 #ifndef NTOHL 123 #define NTOHL(x) (x) = ntohl(x) 124 #define NTOHS(x) (x) = ntohs(x) 125 #endif 126 127 /* 128 * Convert host name to internet address. 129 * Return 0 upon failure. 130 * XXX - not thread-safe; don't use it inside libpcap. 131 */ 132 bpf_u_int32 ** 133 pcap_nametoaddr(const char *name) 134 { 135 #ifndef h_addr 136 static bpf_u_int32 *hlist[2]; 137 #endif 138 bpf_u_int32 **p; 139 struct hostent *hp; 140 141 /* 142 * gethostbyname() is deprecated on Windows, perhaps because 143 * it's not thread-safe, or because it doesn't support IPv6, 144 * or both. 145 * 146 * We deprecate pcap_nametoaddr() on all platforms because 147 * it's not thread-safe; we supply it for backwards compatibility, 148 * so suppress the deprecation warning. We could, I guess, 149 * use getaddrinfo() and construct the array ourselves, but 150 * that's probably not worth the effort, as that wouldn't make 151 * this thread-safe - we can't change the API to require that 152 * our caller free the address array, so we still have to reuse 153 * a local array. 154 */ 155 DIAG_OFF_DEPRECATION 156 if ((hp = gethostbyname(name)) != NULL) { 157 DIAG_ON_DEPRECATION 158 #ifndef h_addr 159 hlist[0] = (bpf_u_int32 *)hp->h_addr; 160 NTOHL(hp->h_addr); 161 return hlist; 162 #else 163 for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p) 164 NTOHL(**p); 165 return (bpf_u_int32 **)hp->h_addr_list; 166 #endif 167 } 168 else 169 return 0; 170 } 171 172 struct addrinfo * 173 pcap_nametoaddrinfo(const char *name) 174 { 175 struct addrinfo hints, *res; 176 int error; 177 178 memset(&hints, 0, sizeof(hints)); 179 hints.ai_family = PF_UNSPEC; 180 hints.ai_socktype = SOCK_STREAM; /*not really*/ 181 hints.ai_protocol = IPPROTO_TCP; /*not really*/ 182 error = getaddrinfo(name, NULL, &hints, &res); 183 if (error) 184 return NULL; 185 else 186 return res; 187 } 188 189 /* 190 * Convert net name to internet address. 191 * Return 0 upon failure. 192 * XXX - not guaranteed to be thread-safe! See below for platforms 193 * on which it is thread-safe and on which it isn't. 194 */ 195 #if defined(_WIN32) || defined(__CYGWIN__) 196 bpf_u_int32 197 pcap_nametonetaddr(const char *name _U_) 198 { 199 /* 200 * There's no "getnetbyname()" on Windows. 201 * 202 * XXX - I guess we could use the BSD code to read 203 * C:\Windows\System32\drivers\etc/networks, assuming 204 * that's its home on all the versions of Windows 205 * we use, but that file probably just has the loopback 206 * network on 127/24 on 99 44/100% of Windows machines. 207 * 208 * (Heck, these days it probably just has that on 99 44/100% 209 * of *UN*X* machines.) 210 */ 211 return 0; 212 } 213 #else /* _WIN32 */ 214 bpf_u_int32 215 pcap_nametonetaddr(const char *name) 216 { 217 /* 218 * UN*X. 219 */ 220 struct netent *np; 221 #if defined(HAVE_LINUX_GETNETBYNAME_R) 222 /* 223 * We have Linux's reentrant getnetbyname_r(). 224 */ 225 struct netent result_buf; 226 char buf[1024]; /* arbitrary size */ 227 int h_errnoval; 228 int err; 229 230 /* 231 * Apparently, the man page at 232 * 233 * http://man7.org/linux/man-pages/man3/getnetbyname_r.3.html 234 * 235 * lies when it says 236 * 237 * If the function call successfully obtains a network record, 238 * then *result is set pointing to result_buf; otherwise, *result 239 * is set to NULL. 240 * 241 * and, in fact, at least in some versions of GNU libc, it does 242 * *not* always get set if getnetbyname_r() succeeds. 243 */ 244 np = NULL; 245 err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np, 246 &h_errnoval); 247 if (err != 0) { 248 /* 249 * XXX - dynamically allocate the buffer, and make it 250 * bigger if we get ERANGE back? 251 */ 252 return 0; 253 } 254 #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R) 255 /* 256 * We have Solaris's and IRIX's reentrant getnetbyname_r(). 257 */ 258 struct netent result_buf; 259 char buf[1024]; /* arbitrary size */ 260 261 np = getnetbyname_r(name, &result_buf, buf, (int)sizeof buf); 262 #elif defined(HAVE_AIX_GETNETBYNAME_R) 263 /* 264 * We have AIX's reentrant getnetbyname_r(). 265 */ 266 struct netent result_buf; 267 struct netent_data net_data; 268 269 if (getnetbyname_r(name, &result_buf, &net_data) == -1) 270 np = NULL; 271 else 272 np = &result_buf; 273 #else 274 /* 275 * We don't have any getnetbyname_r(); either we have a 276 * getnetbyname() that uses thread-specific data, in which 277 * case we're thread-safe (sufficiently recent FreeBSD, 278 * sufficiently recent Darwin-based OS, sufficiently recent 279 * HP-UX, sufficiently recent Tru64 UNIX), or we have the 280 * traditional getnetbyname() (everything else, including 281 * current NetBSD and OpenBSD), in which case we're not 282 * thread-safe. 283 */ 284 np = getnetbyname(name); 285 #endif 286 if (np != NULL) 287 return np->n_net; 288 else 289 return 0; 290 } 291 #endif /* _WIN32 */ 292 293 /* 294 * Convert a port name to its port and protocol numbers. 295 * We assume only TCP or UDP. 296 * Return 0 upon failure. 297 */ 298 int 299 pcap_nametoport(const char *name, int *port, int *proto) 300 { 301 struct addrinfo hints, *res, *ai; 302 int error; 303 struct sockaddr_in *in4; 304 #ifdef INET6 305 struct sockaddr_in6 *in6; 306 #endif 307 int tcp_port = -1; 308 int udp_port = -1; 309 310 /* 311 * We check for both TCP and UDP in case there are 312 * ambiguous entries. 313 */ 314 memset(&hints, 0, sizeof(hints)); 315 hints.ai_family = PF_UNSPEC; 316 hints.ai_socktype = SOCK_STREAM; 317 hints.ai_protocol = IPPROTO_TCP; 318 error = getaddrinfo(NULL, name, &hints, &res); 319 if (error != 0) { 320 if (error != EAI_NONAME && 321 error != EAI_SERVICE) { 322 /* 323 * This is a real error, not just "there's 324 * no such service name". 325 * XXX - this doesn't return an error string. 326 */ 327 return 0; 328 } 329 } else { 330 /* 331 * OK, we found it. Did it find anything? 332 */ 333 for (ai = res; ai != NULL; ai = ai->ai_next) { 334 /* 335 * Does it have an address? 336 */ 337 if (ai->ai_addr != NULL) { 338 /* 339 * Yes. Get a port number; we're done. 340 */ 341 if (ai->ai_addr->sa_family == AF_INET) { 342 in4 = (struct sockaddr_in *)ai->ai_addr; 343 tcp_port = ntohs(in4->sin_port); 344 break; 345 } 346 #ifdef INET6 347 if (ai->ai_addr->sa_family == AF_INET6) { 348 in6 = (struct sockaddr_in6 *)ai->ai_addr; 349 tcp_port = ntohs(in6->sin6_port); 350 break; 351 } 352 #endif 353 } 354 } 355 freeaddrinfo(res); 356 } 357 358 memset(&hints, 0, sizeof(hints)); 359 hints.ai_family = PF_UNSPEC; 360 hints.ai_socktype = SOCK_DGRAM; 361 hints.ai_protocol = IPPROTO_UDP; 362 error = getaddrinfo(NULL, name, &hints, &res); 363 if (error != 0) { 364 if (error != EAI_NONAME && 365 error != EAI_SERVICE) { 366 /* 367 * This is a real error, not just "there's 368 * no such service name". 369 * XXX - this doesn't return an error string. 370 */ 371 return 0; 372 } 373 } else { 374 /* 375 * OK, we found it. Did it find anything? 376 */ 377 for (ai = res; ai != NULL; ai = ai->ai_next) { 378 /* 379 * Does it have an address? 380 */ 381 if (ai->ai_addr != NULL) { 382 /* 383 * Yes. Get a port number; we're done. 384 */ 385 if (ai->ai_addr->sa_family == AF_INET) { 386 in4 = (struct sockaddr_in *)ai->ai_addr; 387 udp_port = ntohs(in4->sin_port); 388 break; 389 } 390 #ifdef INET6 391 if (ai->ai_addr->sa_family == AF_INET6) { 392 in6 = (struct sockaddr_in6 *)ai->ai_addr; 393 udp_port = ntohs(in6->sin6_port); 394 break; 395 } 396 #endif 397 } 398 } 399 freeaddrinfo(res); 400 } 401 402 /* 403 * We need to check /etc/services for ambiguous entries. 404 * If we find an ambiguous entry, and it has the 405 * same port number, change the proto to PROTO_UNDEF 406 * so both TCP and UDP will be checked. 407 */ 408 if (tcp_port >= 0) { 409 *port = tcp_port; 410 *proto = IPPROTO_TCP; 411 if (udp_port >= 0) { 412 if (udp_port == tcp_port) 413 *proto = PROTO_UNDEF; 414 #ifdef notdef 415 else 416 /* Can't handle ambiguous names that refer 417 to different port numbers. */ 418 warning("ambiguous port %s in /etc/services", 419 name); 420 #endif 421 } 422 return 1; 423 } 424 if (udp_port >= 0) { 425 *port = udp_port; 426 *proto = IPPROTO_UDP; 427 return 1; 428 } 429 #if defined(ultrix) || defined(__osf__) 430 /* Special hack in case NFS isn't in /etc/services */ 431 if (strcmp(name, "nfs") == 0) { 432 *port = 2049; 433 *proto = PROTO_UNDEF; 434 return 1; 435 } 436 #endif 437 return 0; 438 } 439 440 /* 441 * Convert a string in the form PPP-PPP, where correspond to ports, to 442 * a starting and ending port in a port range. 443 * Return 0 on failure. 444 */ 445 int 446 pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto) 447 { 448 char *off, *cpy; 449 int save_proto; 450 451 if ((cpy = strdup(name)) == NULL) 452 return 0; 453 454 if ((off = strchr(cpy, '-')) == NULL) { 455 free(cpy); 456 return 0; 457 } 458 459 *off = '\0'; 460 461 if (pcap_nametoport(cpy, port1, proto) == 0) { 462 free(cpy); 463 return 0; 464 } 465 save_proto = *proto; 466 467 if (pcap_nametoport(off + 1, port2, proto) == 0) { 468 free(cpy); 469 return 0; 470 } 471 free(cpy); 472 473 if (*proto != save_proto) 474 *proto = PROTO_UNDEF; 475 476 return 1; 477 } 478 479 /* 480 * XXX - not guaranteed to be thread-safe! See below for platforms 481 * on which it is thread-safe and on which it isn't. 482 */ 483 int 484 pcap_nametoproto(const char *str) 485 { 486 struct protoent *p; 487 #if defined(HAVE_LINUX_GETNETBYNAME_R) 488 /* 489 * We have Linux's reentrant getprotobyname_r(). 490 */ 491 struct protoent result_buf; 492 char buf[1024]; /* arbitrary size */ 493 int err; 494 495 err = getprotobyname_r(str, &result_buf, buf, sizeof buf, &p); 496 if (err != 0) { 497 /* 498 * XXX - dynamically allocate the buffer, and make it 499 * bigger if we get ERANGE back? 500 */ 501 return 0; 502 } 503 #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R) 504 /* 505 * We have Solaris's and IRIX's reentrant getprotobyname_r(). 506 */ 507 struct protoent result_buf; 508 char buf[1024]; /* arbitrary size */ 509 510 p = getprotobyname_r(str, &result_buf, buf, (int)sizeof buf); 511 #elif defined(HAVE_AIX_GETNETBYNAME_R) 512 /* 513 * We have AIX's reentrant getprotobyname_r(). 514 */ 515 struct protoent result_buf; 516 struct protoent_data proto_data; 517 518 if (getprotobyname_r(str, &result_buf, &proto_data) == -1) 519 p = NULL; 520 else 521 p = &result_buf; 522 #else 523 /* 524 * We don't have any getprotobyname_r(); either we have a 525 * getprotobyname() that uses thread-specific data, in which 526 * case we're thread-safe (sufficiently recent FreeBSD, 527 * sufficiently recent Darwin-based OS, sufficiently recent 528 * HP-UX, sufficiently recent Tru64 UNIX, Windows), or we have 529 * the traditional getprotobyname() (everything else, including 530 * current NetBSD and OpenBSD), in which case we're not 531 * thread-safe. 532 */ 533 p = getprotobyname(str); 534 #endif 535 if (p != 0) 536 return p->p_proto; 537 else 538 return PROTO_UNDEF; 539 } 540 541 #include "ethertype.h" 542 543 struct eproto { 544 const char *s; 545 u_short p; 546 }; 547 548 /* 549 * Static data base of ether protocol types. 550 * tcpdump used to import this, and it's declared as an export on 551 * Debian, at least, so make it a public symbol, even though we 552 * don't officially export it by declaring it in a header file. 553 * (Programs *should* do this themselves, as tcpdump now does.) 554 * 555 * We declare it here, right before defining it, to squelch any 556 * warnings we might get from compilers about the lack of a 557 * declaration. 558 */ 559 PCAP_API struct eproto eproto_db[]; 560 PCAP_API_DEF struct eproto eproto_db[] = { 561 { "aarp", ETHERTYPE_AARP }, 562 { "arp", ETHERTYPE_ARP }, 563 { "atalk", ETHERTYPE_ATALK }, 564 { "decnet", ETHERTYPE_DN }, 565 { "ip", ETHERTYPE_IP }, 566 #ifdef INET6 567 { "ip6", ETHERTYPE_IPV6 }, 568 #endif 569 { "lat", ETHERTYPE_LAT }, 570 { "loopback", ETHERTYPE_LOOPBACK }, 571 { "mopdl", ETHERTYPE_MOPDL }, 572 { "moprc", ETHERTYPE_MOPRC }, 573 { "rarp", ETHERTYPE_REVARP }, 574 { "sca", ETHERTYPE_SCA }, 575 { (char *)0, 0 } 576 }; 577 578 int 579 pcap_nametoeproto(const char *s) 580 { 581 struct eproto *p = eproto_db; 582 583 while (p->s != 0) { 584 if (strcmp(p->s, s) == 0) 585 return p->p; 586 p += 1; 587 } 588 return PROTO_UNDEF; 589 } 590 591 #include "llc.h" 592 593 /* Static data base of LLC values. */ 594 static struct eproto llc_db[] = { 595 { "iso", LLCSAP_ISONS }, 596 { "stp", LLCSAP_8021D }, 597 { "ipx", LLCSAP_IPX }, 598 { "netbeui", LLCSAP_NETBEUI }, 599 { (char *)0, 0 } 600 }; 601 602 int 603 pcap_nametollc(const char *s) 604 { 605 struct eproto *p = llc_db; 606 607 while (p->s != 0) { 608 if (strcmp(p->s, s) == 0) 609 return p->p; 610 p += 1; 611 } 612 return PROTO_UNDEF; 613 } 614 615 /* Hex digit to 8-bit unsigned integer. */ 616 static inline u_char 617 pcapint_xdtoi(u_char c) 618 { 619 if (c >= '0' && c <= '9') 620 return (u_char)(c - '0'); 621 else if (c >= 'a' && c <= 'f') 622 return (u_char)(c - 'a' + 10); 623 else 624 return (u_char)(c - 'A' + 10); 625 } 626 627 int 628 __pcap_atoin(const char *s, bpf_u_int32 *addr) 629 { 630 u_int n; 631 int len; 632 633 *addr = 0; 634 len = 0; 635 for (;;) { 636 n = 0; 637 while (*s && *s != '.') { 638 if (n > 25) { 639 /* The result will be > 255 */ 640 return -1; 641 } 642 n = n * 10 + *s++ - '0'; 643 } 644 if (n > 255) 645 return -1; 646 *addr <<= 8; 647 *addr |= n & 0xff; 648 len += 8; 649 if (*s == '\0') 650 return len; 651 ++s; 652 } 653 /* NOTREACHED */ 654 } 655 656 int 657 __pcap_atodn(const char *s, bpf_u_int32 *addr) 658 { 659 #define AREASHIFT 10 660 #define AREAMASK 0176000 661 #define NODEMASK 01777 662 663 u_int node, area; 664 665 if (sscanf(s, "%d.%d", &area, &node) != 2) 666 return(0); 667 668 *addr = (area << AREASHIFT) & AREAMASK; 669 *addr |= (node & NODEMASK); 670 671 return(32); 672 } 673 674 /* 675 * libpcap ARCnet address format is "^\$[0-9a-fA-F]{1,2}$" in regexp syntax. 676 * Iff the given string is a well-formed ARCnet address, parse the string, 677 * store the 8-bit unsigned value into the provided integer and return 1. 678 * Otherwise return 0. 679 * 680 * --> START -- $ --> DOLLAR -- [0-9a-fA-F] --> HEX1 -- \0 -->-+ 681 * | | | | 682 * [.] [.] [0-9a-fA-F] | 683 * | | | | 684 * v v v v 685 * (invalid) <--------+-<---------------[.]-- HEX2 -- \0 -->-+--> (valid) 686 */ 687 int 688 pcapint_atoan(const char *s, uint8_t *addr) 689 { 690 enum { 691 START, 692 DOLLAR, 693 HEX1, 694 HEX2, 695 } fsm_state = START; 696 uint8_t tmp = 0; 697 698 while (*s) { 699 switch (fsm_state) { 700 case START: 701 if (*s != '$') 702 goto invalid; 703 fsm_state = DOLLAR; 704 break; 705 case DOLLAR: 706 if (! PCAP_ISXDIGIT(*s)) 707 goto invalid; 708 tmp = pcapint_xdtoi(*s); 709 fsm_state = HEX1; 710 break; 711 case HEX1: 712 if (! PCAP_ISXDIGIT(*s)) 713 goto invalid; 714 tmp <<= 4; 715 tmp |= pcapint_xdtoi(*s); 716 fsm_state = HEX2; 717 break; 718 case HEX2: 719 goto invalid; 720 } // switch 721 s++; 722 } // while 723 if (fsm_state == HEX1 || fsm_state == HEX2) { 724 *addr = tmp; 725 return 1; 726 } 727 728 invalid: 729 return 0; 730 } 731 732 // Man page: "xxxxxxxxxxxx", regexp: "^[0-9a-fA-F]{12}$". 733 static u_char 734 pcapint_atomac48_xxxxxxxxxxxx(const char *s, uint8_t *addr) 735 { 736 if (strlen(s) == 12 && 737 PCAP_ISXDIGIT(s[0]) && 738 PCAP_ISXDIGIT(s[1]) && 739 PCAP_ISXDIGIT(s[2]) && 740 PCAP_ISXDIGIT(s[3]) && 741 PCAP_ISXDIGIT(s[4]) && 742 PCAP_ISXDIGIT(s[5]) && 743 PCAP_ISXDIGIT(s[6]) && 744 PCAP_ISXDIGIT(s[7]) && 745 PCAP_ISXDIGIT(s[8]) && 746 PCAP_ISXDIGIT(s[9]) && 747 PCAP_ISXDIGIT(s[10]) && 748 PCAP_ISXDIGIT(s[11])) { 749 addr[0] = pcapint_xdtoi(s[0]) << 4 | pcapint_xdtoi(s[1]); 750 addr[1] = pcapint_xdtoi(s[2]) << 4 | pcapint_xdtoi(s[3]); 751 addr[2] = pcapint_xdtoi(s[4]) << 4 | pcapint_xdtoi(s[5]); 752 addr[3] = pcapint_xdtoi(s[6]) << 4 | pcapint_xdtoi(s[7]); 753 addr[4] = pcapint_xdtoi(s[8]) << 4 | pcapint_xdtoi(s[9]); 754 addr[5] = pcapint_xdtoi(s[10]) << 4 | pcapint_xdtoi(s[11]); 755 return 1; 756 } 757 return 0; 758 } 759 760 // Man page: "xxxx.xxxx.xxxx", regexp: "^[0-9a-fA-F]{4}(\.[0-9a-fA-F]{4}){2}$". 761 static u_char 762 pcapint_atomac48_xxxx_3_times(const char *s, uint8_t *addr) 763 { 764 const char sep = '.'; 765 if (strlen(s) == 14 && 766 PCAP_ISXDIGIT(s[0]) && 767 PCAP_ISXDIGIT(s[1]) && 768 PCAP_ISXDIGIT(s[2]) && 769 PCAP_ISXDIGIT(s[3]) && 770 s[4] == sep && 771 PCAP_ISXDIGIT(s[5]) && 772 PCAP_ISXDIGIT(s[6]) && 773 PCAP_ISXDIGIT(s[7]) && 774 PCAP_ISXDIGIT(s[8]) && 775 s[9] == sep && 776 PCAP_ISXDIGIT(s[10]) && 777 PCAP_ISXDIGIT(s[11]) && 778 PCAP_ISXDIGIT(s[12]) && 779 PCAP_ISXDIGIT(s[13])) { 780 addr[0] = pcapint_xdtoi(s[0]) << 4 | pcapint_xdtoi(s[1]); 781 addr[1] = pcapint_xdtoi(s[2]) << 4 | pcapint_xdtoi(s[3]); 782 addr[2] = pcapint_xdtoi(s[5]) << 4 | pcapint_xdtoi(s[6]); 783 addr[3] = pcapint_xdtoi(s[7]) << 4 | pcapint_xdtoi(s[8]); 784 addr[4] = pcapint_xdtoi(s[10]) << 4 | pcapint_xdtoi(s[11]); 785 addr[5] = pcapint_xdtoi(s[12]) << 4 | pcapint_xdtoi(s[13]); 786 return 1; 787 } 788 return 0; 789 } 790 791 /* 792 * Man page: "xx:xx:xx:xx:xx:xx", regexp: "^[0-9a-fA-F]{1,2}(:[0-9a-fA-F]{1,2}){5}$". 793 * Man page: "xx-xx-xx-xx-xx-xx", regexp: "^[0-9a-fA-F]{1,2}(-[0-9a-fA-F]{1,2}){5}$". 794 * Man page: "xx.xx.xx.xx.xx.xx", regexp: "^[0-9a-fA-F]{1,2}(\.[0-9a-fA-F]{1,2}){5}$". 795 * (Any "xx" above can be "x", which is equivalent to "0x".) 796 * 797 * An equivalent (and parametrisable for EUI-64) FSM could be implemented using 798 * a smaller graph, but that graph would be neither acyclic nor planar nor 799 * trivial to verify. 800 * 801 * | 802 * [.] v 803 * +<---------- START 804 * | | 805 * | | [0-9a-fA-F] 806 * | [.] v 807 * +<--------- BYTE0_X ----------+ 808 * | | | 809 * | | [0-9a-fA-F] | 810 * | [.] v | 811 * +<--------- BYTE0_XX | [:\.-] 812 * | | | 813 * | | [:\.-] | 814 * | [.] v | 815 * +<----- BYTE0_SEP_BYTE1 <-----+ 816 * | | 817 * | | [0-9a-fA-F] 818 * | [.] v 819 * +<--------- BYTE1_X ----------+ 820 * | | | 821 * | | [0-9a-fA-F] | 822 * | [.] v | 823 * +<--------- BYTE1_XX | <sep> 824 * | | | 825 * | | <sep> | 826 * | [.] v | 827 * +<----- BYTE1_SEP_BYTE2 <-----+ 828 * | | 829 * | | [0-9a-fA-F] 830 * | [.] v 831 * +<--------- BYTE2_X ----------+ 832 * | | | 833 * | | [0-9a-fA-F] | 834 * | [.] v | 835 * +<--------- BYTE2_XX | <sep> 836 * | | | 837 * | | <sep> | 838 * | [.] v | 839 * +<----- BYTE2_SEP_BYTE3 <-----+ 840 * | | 841 * | | [0-9a-fA-F] 842 * | [.] v 843 * +<--------- BYTE3_X ----------+ 844 * | | | 845 * | | [0-9a-fA-F] | 846 * | [.] v | 847 * +<--------- BYTE3_XX | <sep> 848 * | | | 849 * | | <sep> | 850 * | [.] v | 851 * +<----- BYTE3_SEP_BYTE4 <-----+ 852 * | | 853 * | | [0-9a-fA-F] 854 * | [.] v 855 * +<--------- BYTE4_X ----------+ 856 * | | | 857 * | | [0-9a-fA-F] | 858 * | [.] v | 859 * +<--------- BYTE4_XX | <sep> 860 * | | | 861 * | | <sep> | 862 * | [.] v | 863 * +<----- BYTE4_SEP_BYTE5 <-----+ 864 * | | 865 * | | [0-9a-fA-F] 866 * | [.] v 867 * +<--------- BYTE5_X ----------+ 868 * | | | 869 * | | [0-9a-fA-F] | 870 * | [.] v | 871 * +<--------- BYTE5_XX | \0 872 * | | | 873 * | | \0 | 874 * | | v 875 * +--> (reject) +---------> (accept) 876 * 877 */ 878 static u_char 879 pcapint_atomac48_x_xx_6_times(const char *s, uint8_t *addr) 880 { 881 enum { 882 START, 883 BYTE0_X, 884 BYTE0_XX, 885 BYTE0_SEP_BYTE1, 886 BYTE1_X, 887 BYTE1_XX, 888 BYTE1_SEP_BYTE2, 889 BYTE2_X, 890 BYTE2_XX, 891 BYTE2_SEP_BYTE3, 892 BYTE3_X, 893 BYTE3_XX, 894 BYTE3_SEP_BYTE4, 895 BYTE4_X, 896 BYTE4_XX, 897 BYTE4_SEP_BYTE5, 898 BYTE5_X, 899 BYTE5_XX, 900 } fsm_state = START; 901 uint8_t buf[6]; 902 const char *seplist = ":.-"; 903 char sep; 904 905 while (*s) { 906 switch (fsm_state) { 907 case START: 908 if (PCAP_ISXDIGIT(*s)) { 909 buf[0] = pcapint_xdtoi(*s); 910 fsm_state = BYTE0_X; 911 break; 912 } 913 goto reject; 914 case BYTE0_X: 915 if (strchr(seplist, *s)) { 916 sep = *s; 917 fsm_state = BYTE0_SEP_BYTE1; 918 break; 919 } 920 if (PCAP_ISXDIGIT(*s)) { 921 buf[0] = buf[0] << 4 | pcapint_xdtoi(*s); 922 fsm_state = BYTE0_XX; 923 break; 924 } 925 goto reject; 926 case BYTE0_XX: 927 if (strchr(seplist, *s)) { 928 sep = *s; 929 fsm_state = BYTE0_SEP_BYTE1; 930 break; 931 } 932 goto reject; 933 case BYTE0_SEP_BYTE1: 934 if (PCAP_ISXDIGIT(*s)) { 935 buf[1] = pcapint_xdtoi(*s); 936 fsm_state = BYTE1_X; 937 break; 938 } 939 goto reject; 940 case BYTE1_X: 941 if (*s == sep) { 942 fsm_state = BYTE1_SEP_BYTE2; 943 break; 944 } 945 if (PCAP_ISXDIGIT(*s)) { 946 buf[1] = buf[1] << 4 | pcapint_xdtoi(*s); 947 fsm_state = BYTE1_XX; 948 break; 949 } 950 goto reject; 951 case BYTE1_XX: 952 if (*s == sep) { 953 fsm_state = BYTE1_SEP_BYTE2; 954 break; 955 } 956 goto reject; 957 case BYTE1_SEP_BYTE2: 958 if (PCAP_ISXDIGIT(*s)) { 959 buf[2] = pcapint_xdtoi(*s); 960 fsm_state = BYTE2_X; 961 break; 962 } 963 goto reject; 964 case BYTE2_X: 965 if (*s == sep) { 966 fsm_state = BYTE2_SEP_BYTE3; 967 break; 968 } 969 if (PCAP_ISXDIGIT(*s)) { 970 buf[2] = buf[2] << 4 | pcapint_xdtoi(*s); 971 fsm_state = BYTE2_XX; 972 break; 973 } 974 goto reject; 975 case BYTE2_XX: 976 if (*s == sep) { 977 fsm_state = BYTE2_SEP_BYTE3; 978 break; 979 } 980 goto reject; 981 case BYTE2_SEP_BYTE3: 982 if (PCAP_ISXDIGIT(*s)) { 983 buf[3] = pcapint_xdtoi(*s); 984 fsm_state = BYTE3_X; 985 break; 986 } 987 goto reject; 988 case BYTE3_X: 989 if (*s == sep) { 990 fsm_state = BYTE3_SEP_BYTE4; 991 break; 992 } 993 if (PCAP_ISXDIGIT(*s)) { 994 buf[3] = buf[3] << 4 | pcapint_xdtoi(*s); 995 fsm_state = BYTE3_XX; 996 break; 997 } 998 goto reject; 999 case BYTE3_XX: 1000 if (*s == sep) { 1001 fsm_state = BYTE3_SEP_BYTE4; 1002 break; 1003 } 1004 goto reject; 1005 case BYTE3_SEP_BYTE4: 1006 if (PCAP_ISXDIGIT(*s)) { 1007 buf[4] = pcapint_xdtoi(*s); 1008 fsm_state = BYTE4_X; 1009 break; 1010 } 1011 goto reject; 1012 case BYTE4_X: 1013 if (*s == sep) { 1014 fsm_state = BYTE4_SEP_BYTE5; 1015 break; 1016 } 1017 if (PCAP_ISXDIGIT(*s)) { 1018 buf[4] = buf[4] << 4 | pcapint_xdtoi(*s); 1019 fsm_state = BYTE4_XX; 1020 break; 1021 } 1022 goto reject; 1023 case BYTE4_XX: 1024 if (*s == sep) { 1025 fsm_state = BYTE4_SEP_BYTE5; 1026 break; 1027 } 1028 goto reject; 1029 case BYTE4_SEP_BYTE5: 1030 if (PCAP_ISXDIGIT(*s)) { 1031 buf[5] = pcapint_xdtoi(*s); 1032 fsm_state = BYTE5_X; 1033 break; 1034 } 1035 goto reject; 1036 case BYTE5_X: 1037 if (PCAP_ISXDIGIT(*s)) { 1038 buf[5] = buf[5] << 4 | pcapint_xdtoi(*s); 1039 fsm_state = BYTE5_XX; 1040 break; 1041 } 1042 goto reject; 1043 case BYTE5_XX: 1044 goto reject; 1045 } // switch 1046 s++; 1047 } // while 1048 1049 if (fsm_state == BYTE5_X || fsm_state == BYTE5_XX) { 1050 // accept 1051 memcpy(addr, buf, sizeof(buf)); 1052 return 1; 1053 } 1054 1055 reject: 1056 return 0; 1057 } 1058 1059 // The 'addr' argument must point to an array of at least 6 elements. 1060 static int 1061 pcapint_atomac48(const char *s, uint8_t *addr) 1062 { 1063 return s && ( 1064 pcapint_atomac48_xxxxxxxxxxxx(s, addr) || 1065 pcapint_atomac48_xxxx_3_times(s, addr) || 1066 pcapint_atomac48_x_xx_6_times(s, addr) 1067 ); 1068 } 1069 1070 /* 1071 * If 's' is a MAC-48 address in one of the forms documented in pcap-filter(7) 1072 * for "ether host", return a pointer to an allocated buffer with the binary 1073 * value of the address. Return NULL on any error. 1074 */ 1075 u_char * 1076 pcap_ether_aton(const char *s) 1077 { 1078 uint8_t tmp[6]; 1079 if (! pcapint_atomac48(s, tmp)) 1080 return (NULL); 1081 1082 u_char *e = malloc(6); 1083 if (e == NULL) 1084 return (NULL); 1085 memcpy(e, tmp, sizeof(tmp)); 1086 return (e); 1087 } 1088 1089 #ifndef HAVE_ETHER_HOSTTON 1090 /* 1091 * Roll our own. 1092 * 1093 * This should be thread-safe, as we define the static variables 1094 * we use to be thread-local, and as pcap_next_etherent() does so 1095 * as well. 1096 */ 1097 u_char * 1098 pcap_ether_hostton(const char *name) 1099 { 1100 register struct pcap_etherent *ep; 1101 register u_char *ap; 1102 static thread_local FILE *fp = NULL; 1103 static thread_local int init = 0; 1104 1105 if (!init) { 1106 fp = fopen(PCAP_ETHERS_FILE, "r"); 1107 ++init; 1108 if (fp == NULL) 1109 return (NULL); 1110 } else if (fp == NULL) 1111 return (NULL); 1112 else 1113 rewind(fp); 1114 1115 while ((ep = pcap_next_etherent(fp)) != NULL) { 1116 if (strcmp(ep->name, name) == 0) { 1117 ap = (u_char *)malloc(6); 1118 if (ap != NULL) { 1119 memcpy(ap, ep->addr, 6); 1120 return (ap); 1121 } 1122 break; 1123 } 1124 } 1125 return (NULL); 1126 } 1127 #else 1128 /* 1129 * Use the OS-supplied routine. 1130 * This *should* be thread-safe; the API doesn't have a static buffer. 1131 */ 1132 u_char * 1133 pcap_ether_hostton(const char *name) 1134 { 1135 register u_char *ap; 1136 u_char a[6]; 1137 char namebuf[1024]; 1138 1139 /* 1140 * In AIX 7.1 and 7.2: int ether_hostton(char *, struct ether_addr *); 1141 */ 1142 pcapint_strlcpy(namebuf, name, sizeof(namebuf)); 1143 ap = NULL; 1144 if (ether_hostton(namebuf, (struct ether_addr *)a) == 0) { 1145 ap = (u_char *)malloc(6); 1146 if (ap != NULL) 1147 memcpy((char *)ap, (char *)a, 6); 1148 } 1149 return (ap); 1150 } 1151 #endif 1152 1153 /* 1154 * XXX - not guaranteed to be thread-safe! 1155 */ 1156 int 1157 #ifdef DECNETLIB 1158 __pcap_nametodnaddr(const char *name, u_short *res) 1159 { 1160 struct nodeent *getnodebyname(); 1161 struct nodeent *nep; 1162 1163 nep = getnodebyname(name); 1164 if (nep == ((struct nodeent *)0)) 1165 return(0); 1166 1167 memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short)); 1168 return(1); 1169 #else 1170 __pcap_nametodnaddr(const char *name _U_, u_short *res _U_) 1171 { 1172 return(0); 1173 #endif 1174 } 1175