nametoaddr.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  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. #ifdef HAVE_CONFIG_H
  25. #include <config.h>
  26. #endif
  27. #ifdef DECNETLIB
  28. #include <sys/types.h>
  29. #include <netdnet/dnetdb.h>
  30. #endif
  31. #ifdef _WIN32
  32. #include <winsock2.h>
  33. #include <ws2tcpip.h>
  34. #ifdef INET6
  35. /*
  36. * To quote the MSDN page for getaddrinfo() at
  37. *
  38. * https://msdn.microsoft.com/en-us/library/windows/desktop/ms738520(v=vs.85).aspx
  39. *
  40. * "Support for getaddrinfo on Windows 2000 and older versions
  41. * The getaddrinfo function was added to the Ws2_32.dll on Windows XP and
  42. * later. To execute an application that uses this function on earlier
  43. * versions of Windows, then you need to include the Ws2tcpip.h and
  44. * Wspiapi.h files. When the Wspiapi.h include file is added, the
  45. * getaddrinfo function is defined to the WspiapiGetAddrInfo inline
  46. * function in the Wspiapi.h file. At runtime, the WspiapiGetAddrInfo
  47. * function is implemented in such a way that if the Ws2_32.dll or the
  48. * Wship6.dll (the file containing getaddrinfo in the IPv6 Technology
  49. * Preview for Windows 2000) does not include getaddrinfo, then a
  50. * version of getaddrinfo is implemented inline based on code in the
  51. * Wspiapi.h header file. This inline code will be used on older Windows
  52. * platforms that do not natively support the getaddrinfo function."
  53. *
  54. * We use getaddrinfo(), so we include Wspiapi.h here.
  55. */
  56. #include <wspiapi.h>
  57. #endif /* INET6 */
  58. #else /* _WIN32 */
  59. #include <sys/param.h>
  60. #include <sys/types.h>
  61. #include <sys/socket.h>
  62. #include <sys/time.h>
  63. #include <netinet/in.h>
  64. #ifdef HAVE_ETHER_HOSTTON
  65. #if defined(NET_ETHERNET_H_DECLARES_ETHER_HOSTTON)
  66. /*
  67. * OK, just include <net/ethernet.h>.
  68. */
  69. #include <net/ethernet.h>
  70. #elif defined(NETINET_ETHER_H_DECLARES_ETHER_HOSTTON)
  71. /*
  72. * OK, just include <netinet/ether.h>
  73. */
  74. #include <netinet/ether.h>
  75. #elif defined(SYS_ETHERNET_H_DECLARES_ETHER_HOSTTON)
  76. /*
  77. * OK, just include <sys/ethernet.h>
  78. */
  79. #include <sys/ethernet.h>
  80. #elif defined(ARPA_INET_H_DECLARES_ETHER_HOSTTON)
  81. /*
  82. * OK, just include <arpa/inet.h>
  83. */
  84. #include <arpa/inet.h>
  85. #elif defined(NETINET_IF_ETHER_H_DECLARES_ETHER_HOSTTON)
  86. /*
  87. * OK, include <netinet/if_ether.h>, after all the other stuff we
  88. * need to include or define for its benefit.
  89. */
  90. #define NEED_NETINET_IF_ETHER_H
  91. #else
  92. /*
  93. * We'll have to declare it ourselves.
  94. * If <netinet/if_ether.h> defines struct ether_addr, include
  95. * it. Otherwise, define it ourselves.
  96. */
  97. #ifdef HAVE_STRUCT_ETHER_ADDR
  98. #define NEED_NETINET_IF_ETHER_H
  99. #else /* HAVE_STRUCT_ETHER_ADDR */
  100. struct ether_addr {
  101. unsigned char ether_addr_octet[6];
  102. };
  103. #endif /* HAVE_STRUCT_ETHER_ADDR */
  104. #endif /* what declares ether_hostton() */
  105. #ifdef NEED_NETINET_IF_ETHER_H
  106. #include <net/if.h> /* Needed on some platforms */
  107. #include <netinet/in.h> /* Needed on some platforms */
  108. #include <netinet/if_ether.h>
  109. #endif /* NEED_NETINET_IF_ETHER_H */
  110. #ifndef HAVE_DECL_ETHER_HOSTTON
  111. /*
  112. * No header declares it, so declare it ourselves.
  113. */
  114. extern int ether_hostton(const char *, struct ether_addr *);
  115. #endif /* !defined(HAVE_DECL_ETHER_HOSTTON) */
  116. #endif /* HAVE_ETHER_HOSTTON */
  117. #include <arpa/inet.h>
  118. #include <netdb.h>
  119. #endif /* _WIN32 */
  120. #include <ctype.h>
  121. #include <errno.h>
  122. #include <stdlib.h>
  123. #include <string.h>
  124. #include <stdio.h>
  125. #include "pcap-int.h"
  126. #include "gencode.h"
  127. #include <pcap/namedb.h>
  128. #include "nametoaddr.h"
  129. #ifdef HAVE_OS_PROTO_H
  130. #include "os-proto.h"
  131. #endif
  132. #ifndef NTOHL
  133. #define NTOHL(x) (x) = ntohl(x)
  134. #define NTOHS(x) (x) = ntohs(x)
  135. #endif
  136. /*
  137. * Convert host name to internet address.
  138. * Return 0 upon failure.
  139. * XXX - not thread-safe; don't use it inside libpcap.
  140. */
  141. bpf_u_int32 **
  142. pcap_nametoaddr(const char *name)
  143. {
  144. #ifndef h_addr
  145. static bpf_u_int32 *hlist[2];
  146. #endif
  147. bpf_u_int32 **p;
  148. struct hostent *hp;
  149. if ((hp = gethostbyname(name)) != NULL) {
  150. #ifndef h_addr
  151. hlist[0] = (bpf_u_int32 *)hp->h_addr;
  152. NTOHL(hp->h_addr);
  153. return hlist;
  154. #else
  155. for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
  156. NTOHL(**p);
  157. return (bpf_u_int32 **)hp->h_addr_list;
  158. #endif
  159. }
  160. else
  161. return 0;
  162. }
  163. struct addrinfo *
  164. pcap_nametoaddrinfo(const char *name)
  165. {
  166. struct addrinfo hints, *res;
  167. int error;
  168. memset(&hints, 0, sizeof(hints));
  169. hints.ai_family = PF_UNSPEC;
  170. hints.ai_socktype = SOCK_STREAM; /*not really*/
  171. hints.ai_protocol = IPPROTO_TCP; /*not really*/
  172. error = getaddrinfo(name, NULL, &hints, &res);
  173. if (error)
  174. return NULL;
  175. else
  176. return res;
  177. }
  178. /*
  179. * Convert net name to internet address.
  180. * Return 0 upon failure.
  181. * XXX - not guaranteed to be thread-safe! See below for platforms
  182. * on which it is thread-safe and on which it isn't.
  183. */
  184. bpf_u_int32
  185. pcap_nametonetaddr(const char *name)
  186. {
  187. #ifdef _WIN32
  188. /*
  189. * There's no "getnetbyname()" on Windows.
  190. *
  191. * XXX - I guess we could use the BSD code to read
  192. * C:\Windows\System32\drivers\etc/networks, assuming
  193. * that's its home on all the versions of Windows
  194. * we use, but that file probably just has the loopback
  195. * network on 127/24 on 99 44/100% of Windows machines.
  196. *
  197. * (Heck, these days it probably just has that on 99 44/100%
  198. * of *UN*X* machines.)
  199. */
  200. return 0;
  201. #else
  202. /*
  203. * UN*X.
  204. */
  205. struct netent *np;
  206. #if defined(HAVE_LINUX_GETNETBYNAME_R)
  207. /*
  208. * We have Linux's reentrant getnetbyname_r().
  209. */
  210. struct netent result_buf;
  211. char buf[1024]; /* arbitrary size */
  212. int h_errnoval;
  213. int err;
  214. err = getnetbyname_r(name, &result_buf, buf, sizeof buf, &np,
  215. &h_errnoval);
  216. if (err != 0) {
  217. /*
  218. * XXX - dynamically allocate the buffer, and make it
  219. * bigger if we get ERANGE back?
  220. */
  221. return 0;
  222. }
  223. #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
  224. /*
  225. * We have Solaris's and IRIX's reentrant getnetbyname_r().
  226. */
  227. struct netent result_buf;
  228. char buf[1024]; /* arbitrary size */
  229. np = getnetbyname_r(name, &result_buf, buf, (int)sizeof buf);
  230. #elif defined(HAVE_AIX_GETNETBYNAME_R)
  231. /*
  232. * We have AIX's reentrant getnetbyname_r().
  233. */
  234. struct netent result_buf;
  235. struct netent_data net_data;
  236. if (getnetbyname_r(name, &result_buf, &net_data) == -1)
  237. np = NULL;
  238. else
  239. np = &result_buf;
  240. #else
  241. /*
  242. * We don't have any getnetbyname_r(); either we have a
  243. * getnetbyname() that uses thread-specific data, in which
  244. * case we're thread-safe (sufficiently recent FreeBSD,
  245. * sufficiently recent Darwin-based OS, sufficiently recent
  246. * HP-UX, sufficiently recent Tru64 UNIX), or we have the
  247. * traditional getnetbyname() (everything else, including
  248. * current NetBSD and OpenBSD), in which case we're not
  249. * thread-safe.
  250. */
  251. np = getnetbyname(name);
  252. #endif
  253. if (np != NULL)
  254. return np->n_net;
  255. else
  256. return 0;
  257. #endif /* _WIN32 */
  258. }
  259. /*
  260. * Convert a port name to its port and protocol numbers.
  261. * We assume only TCP or UDP.
  262. * Return 0 upon failure.
  263. */
  264. int
  265. pcap_nametoport(const char *name, int *port, int *proto)
  266. {
  267. struct addrinfo hints, *res, *ai;
  268. int error;
  269. struct sockaddr_in *in4;
  270. #ifdef INET6
  271. struct sockaddr_in6 *in6;
  272. #endif
  273. int tcp_port = -1;
  274. int udp_port = -1;
  275. /*
  276. * We check for both TCP and UDP in case there are
  277. * ambiguous entries.
  278. */
  279. memset(&hints, 0, sizeof(hints));
  280. hints.ai_family = PF_UNSPEC;
  281. hints.ai_socktype = SOCK_STREAM;
  282. hints.ai_protocol = IPPROTO_TCP;
  283. error = getaddrinfo(NULL, name, &hints, &res);
  284. if (error != 0) {
  285. if (error != EAI_NONAME &&
  286. error != EAI_SERVICE) {
  287. /*
  288. * This is a real error, not just "there's
  289. * no such service name".
  290. * XXX - this doesn't return an error string.
  291. */
  292. return 0;
  293. }
  294. } else {
  295. /*
  296. * OK, we found it. Did it find anything?
  297. */
  298. for (ai = res; ai != NULL; ai = ai->ai_next) {
  299. /*
  300. * Does it have an address?
  301. */
  302. if (ai->ai_addr != NULL) {
  303. /*
  304. * Yes. Get a port number; we're done.
  305. */
  306. if (ai->ai_addr->sa_family == AF_INET) {
  307. in4 = (struct sockaddr_in *)ai->ai_addr;
  308. tcp_port = ntohs(in4->sin_port);
  309. break;
  310. }
  311. #ifdef INET6
  312. if (ai->ai_addr->sa_family == AF_INET6) {
  313. in6 = (struct sockaddr_in6 *)ai->ai_addr;
  314. tcp_port = ntohs(in6->sin6_port);
  315. break;
  316. }
  317. #endif
  318. }
  319. }
  320. freeaddrinfo(res);
  321. }
  322. memset(&hints, 0, sizeof(hints));
  323. hints.ai_family = PF_UNSPEC;
  324. hints.ai_socktype = SOCK_DGRAM;
  325. hints.ai_protocol = IPPROTO_UDP;
  326. error = getaddrinfo(NULL, name, &hints, &res);
  327. if (error != 0) {
  328. if (error != EAI_NONAME &&
  329. error != EAI_SERVICE) {
  330. /*
  331. * This is a real error, not just "there's
  332. * no such service name".
  333. * XXX - this doesn't return an error string.
  334. */
  335. return 0;
  336. }
  337. } else {
  338. /*
  339. * OK, we found it. Did it find anything?
  340. */
  341. for (ai = res; ai != NULL; ai = ai->ai_next) {
  342. /*
  343. * Does it have an address?
  344. */
  345. if (ai->ai_addr != NULL) {
  346. /*
  347. * Yes. Get a port number; we're done.
  348. */
  349. if (ai->ai_addr->sa_family == AF_INET) {
  350. in4 = (struct sockaddr_in *)ai->ai_addr;
  351. udp_port = ntohs(in4->sin_port);
  352. break;
  353. }
  354. #ifdef INET6
  355. if (ai->ai_addr->sa_family == AF_INET6) {
  356. in6 = (struct sockaddr_in6 *)ai->ai_addr;
  357. udp_port = ntohs(in6->sin6_port);
  358. break;
  359. }
  360. #endif
  361. }
  362. }
  363. freeaddrinfo(res);
  364. }
  365. /*
  366. * We need to check /etc/services for ambiguous entries.
  367. * If we find an ambiguous entry, and it has the
  368. * same port number, change the proto to PROTO_UNDEF
  369. * so both TCP and UDP will be checked.
  370. */
  371. if (tcp_port >= 0) {
  372. *port = tcp_port;
  373. *proto = IPPROTO_TCP;
  374. if (udp_port >= 0) {
  375. if (udp_port == tcp_port)
  376. *proto = PROTO_UNDEF;
  377. #ifdef notdef
  378. else
  379. /* Can't handle ambiguous names that refer
  380. to different port numbers. */
  381. warning("ambiguous port %s in /etc/services",
  382. name);
  383. #endif
  384. }
  385. return 1;
  386. }
  387. if (udp_port >= 0) {
  388. *port = udp_port;
  389. *proto = IPPROTO_UDP;
  390. return 1;
  391. }
  392. #if defined(ultrix) || defined(__osf__)
  393. /* Special hack in case NFS isn't in /etc/services */
  394. if (strcmp(name, "nfs") == 0) {
  395. *port = 2049;
  396. *proto = PROTO_UNDEF;
  397. return 1;
  398. }
  399. #endif
  400. return 0;
  401. }
  402. /*
  403. * Convert a string in the form PPP-PPP, where correspond to ports, to
  404. * a starting and ending port in a port range.
  405. * Return 0 on failure.
  406. */
  407. int
  408. pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
  409. {
  410. u_int p1, p2;
  411. char *off, *cpy;
  412. int save_proto;
  413. if (sscanf(name, "%d-%d", &p1, &p2) != 2) {
  414. if ((cpy = strdup(name)) == NULL)
  415. return 0;
  416. if ((off = strchr(cpy, '-')) == NULL) {
  417. free(cpy);
  418. return 0;
  419. }
  420. *off = '\0';
  421. if (pcap_nametoport(cpy, port1, proto) == 0) {
  422. free(cpy);
  423. return 0;
  424. }
  425. save_proto = *proto;
  426. if (pcap_nametoport(off + 1, port2, proto) == 0) {
  427. free(cpy);
  428. return 0;
  429. }
  430. free(cpy);
  431. if (*proto != save_proto)
  432. *proto = PROTO_UNDEF;
  433. } else {
  434. *port1 = p1;
  435. *port2 = p2;
  436. *proto = PROTO_UNDEF;
  437. }
  438. return 1;
  439. }
  440. /*
  441. * XXX - not guaranteed to be thread-safe! See below for platforms
  442. * on which it is thread-safe and on which it isn't.
  443. */
  444. int
  445. pcap_nametoproto(const char *str)
  446. {
  447. struct protoent *p;
  448. #if defined(HAVE_LINUX_GETNETBYNAME_R)
  449. /*
  450. * We have Linux's reentrant getprotobyname_r().
  451. */
  452. struct protoent result_buf;
  453. char buf[1024]; /* arbitrary size */
  454. int err;
  455. err = getprotobyname_r(str, &result_buf, buf, sizeof buf, &p);
  456. if (err != 0) {
  457. /*
  458. * XXX - dynamically allocate the buffer, and make it
  459. * bigger if we get ERANGE back?
  460. */
  461. return 0;
  462. }
  463. #elif defined(HAVE_SOLARIS_IRIX_GETNETBYNAME_R)
  464. /*
  465. * We have Solaris's and IRIX's reentrant getprotobyname_r().
  466. */
  467. struct protoent result_buf;
  468. char buf[1024]; /* arbitrary size */
  469. p = getprotobyname_r(str, &result_buf, buf, (int)sizeof buf);
  470. #elif defined(HAVE_AIX_GETNETBYNAME_R)
  471. /*
  472. * We have AIX's reentrant getprotobyname_r().
  473. */
  474. struct protoent result_buf;
  475. struct protoent_data proto_data;
  476. if (getprotobyname_r(str, &result_buf, &proto_data) == -1)
  477. p = NULL;
  478. else
  479. p = &result_buf;
  480. #else
  481. /*
  482. * We don't have any getprotobyname_r(); either we have a
  483. * getprotobyname() that uses thread-specific data, in which
  484. * case we're thread-safe (sufficiently recent FreeBSD,
  485. * sufficiently recent Darwin-based OS, sufficiently recent
  486. * HP-UX, sufficiently recent Tru64 UNIX, Windows), or we have
  487. * the traditional getprotobyname() (everything else, including
  488. * current NetBSD and OpenBSD), in which case we're not
  489. * thread-safe.
  490. */
  491. p = getprotobyname(str);
  492. #endif
  493. if (p != 0)
  494. return p->p_proto;
  495. else
  496. return PROTO_UNDEF;
  497. }
  498. #include "ethertype.h"
  499. struct eproto {
  500. const char *s;
  501. u_short p;
  502. };
  503. /*
  504. * Static data base of ether protocol types.
  505. * tcpdump used to import this, and it's declared as an export on
  506. * Debian, at least, so make it a public symbol, even though we
  507. * don't officially export it by declaring it in a header file.
  508. * (Programs *should* do this themselves, as tcpdump now does.)
  509. *
  510. * We declare it here, right before defining it, to squelch any
  511. * warnings we might get from compilers about the lack of a
  512. * declaration.
  513. */
  514. PCAP_API struct eproto eproto_db[];
  515. PCAP_API_DEF struct eproto eproto_db[] = {
  516. { "pup", ETHERTYPE_PUP },
  517. { "xns", ETHERTYPE_NS },
  518. { "ip", ETHERTYPE_IP },
  519. #ifdef INET6
  520. { "ip6", ETHERTYPE_IPV6 },
  521. #endif
  522. { "arp", ETHERTYPE_ARP },
  523. { "rarp", ETHERTYPE_REVARP },
  524. { "sprite", ETHERTYPE_SPRITE },
  525. { "mopdl", ETHERTYPE_MOPDL },
  526. { "moprc", ETHERTYPE_MOPRC },
  527. { "decnet", ETHERTYPE_DN },
  528. { "lat", ETHERTYPE_LAT },
  529. { "sca", ETHERTYPE_SCA },
  530. { "lanbridge", ETHERTYPE_LANBRIDGE },
  531. { "vexp", ETHERTYPE_VEXP },
  532. { "vprod", ETHERTYPE_VPROD },
  533. { "atalk", ETHERTYPE_ATALK },
  534. { "atalkarp", ETHERTYPE_AARP },
  535. { "loopback", ETHERTYPE_LOOPBACK },
  536. { "decdts", ETHERTYPE_DECDTS },
  537. { "decdns", ETHERTYPE_DECDNS },
  538. { (char *)0, 0 }
  539. };
  540. int
  541. pcap_nametoeproto(const char *s)
  542. {
  543. struct eproto *p = eproto_db;
  544. while (p->s != 0) {
  545. if (strcmp(p->s, s) == 0)
  546. return p->p;
  547. p += 1;
  548. }
  549. return PROTO_UNDEF;
  550. }
  551. #include "llc.h"
  552. /* Static data base of LLC values. */
  553. static struct eproto llc_db[] = {
  554. { "iso", LLCSAP_ISONS },
  555. { "stp", LLCSAP_8021D },
  556. { "ipx", LLCSAP_IPX },
  557. { "netbeui", LLCSAP_NETBEUI },
  558. { (char *)0, 0 }
  559. };
  560. int
  561. pcap_nametollc(const char *s)
  562. {
  563. struct eproto *p = llc_db;
  564. while (p->s != 0) {
  565. if (strcmp(p->s, s) == 0)
  566. return p->p;
  567. p += 1;
  568. }
  569. return PROTO_UNDEF;
  570. }
  571. /* Hex digit to 8-bit unsigned integer. */
  572. static inline u_char
  573. xdtoi(u_char c)
  574. {
  575. if (isdigit(c))
  576. return (u_char)(c - '0');
  577. else if (islower(c))
  578. return (u_char)(c - 'a' + 10);
  579. else
  580. return (u_char)(c - 'A' + 10);
  581. }
  582. int
  583. __pcap_atoin(const char *s, bpf_u_int32 *addr)
  584. {
  585. u_int n;
  586. int len;
  587. *addr = 0;
  588. len = 0;
  589. for (;;) {
  590. n = 0;
  591. while (*s && *s != '.')
  592. n = n * 10 + *s++ - '0';
  593. *addr <<= 8;
  594. *addr |= n & 0xff;
  595. len += 8;
  596. if (*s == '\0')
  597. return len;
  598. ++s;
  599. }
  600. /* NOTREACHED */
  601. }
  602. int
  603. __pcap_atodn(const char *s, bpf_u_int32 *addr)
  604. {
  605. #define AREASHIFT 10
  606. #define AREAMASK 0176000
  607. #define NODEMASK 01777
  608. u_int node, area;
  609. if (sscanf(s, "%d.%d", &area, &node) != 2)
  610. return(0);
  611. *addr = (area << AREASHIFT) & AREAMASK;
  612. *addr |= (node & NODEMASK);
  613. return(32);
  614. }
  615. /*
  616. * Convert 's', which can have the one of the forms:
  617. *
  618. * "xx:xx:xx:xx:xx:xx"
  619. * "xx.xx.xx.xx.xx.xx"
  620. * "xx-xx-xx-xx-xx-xx"
  621. * "xxxx.xxxx.xxxx"
  622. * "xxxxxxxxxxxx"
  623. *
  624. * (or various mixes of ':', '.', and '-') into a new
  625. * ethernet address. Assumes 's' is well formed.
  626. */
  627. u_char *
  628. pcap_ether_aton(const char *s)
  629. {
  630. register u_char *ep, *e;
  631. register u_char d;
  632. e = ep = (u_char *)malloc(6);
  633. if (e == NULL)
  634. return (NULL);
  635. while (*s) {
  636. if (*s == ':' || *s == '.' || *s == '-')
  637. s += 1;
  638. d = xdtoi(*s++);
  639. if (isxdigit((unsigned char)*s)) {
  640. d <<= 4;
  641. d |= xdtoi(*s++);
  642. }
  643. *ep++ = d;
  644. }
  645. return (e);
  646. }
  647. #ifndef HAVE_ETHER_HOSTTON
  648. /*
  649. * Roll our own.
  650. * XXX - not thread-safe, because pcap_next_etherent() isn't thread-
  651. * safe! Needs a mutex or a thread-safe pcap_next_etherent().
  652. */
  653. u_char *
  654. pcap_ether_hostton(const char *name)
  655. {
  656. register struct pcap_etherent *ep;
  657. register u_char *ap;
  658. static FILE *fp = NULL;
  659. static int init = 0;
  660. if (!init) {
  661. fp = fopen(PCAP_ETHERS_FILE, "r");
  662. ++init;
  663. if (fp == NULL)
  664. return (NULL);
  665. } else if (fp == NULL)
  666. return (NULL);
  667. else
  668. rewind(fp);
  669. while ((ep = pcap_next_etherent(fp)) != NULL) {
  670. if (strcmp(ep->name, name) == 0) {
  671. ap = (u_char *)malloc(6);
  672. if (ap != NULL) {
  673. memcpy(ap, ep->addr, 6);
  674. return (ap);
  675. }
  676. break;
  677. }
  678. }
  679. return (NULL);
  680. }
  681. #else
  682. /*
  683. * Use the OS-supplied routine.
  684. * This *should* be thread-safe; the API doesn't have a static buffer.
  685. */
  686. u_char *
  687. pcap_ether_hostton(const char *name)
  688. {
  689. register u_char *ap;
  690. u_char a[6];
  691. ap = NULL;
  692. if (ether_hostton(name, (struct ether_addr *)a) == 0) {
  693. ap = (u_char *)malloc(6);
  694. if (ap != NULL)
  695. memcpy((char *)ap, (char *)a, 6);
  696. }
  697. return (ap);
  698. }
  699. #endif
  700. /*
  701. * XXX - not guaranteed to be thread-safe!
  702. */
  703. int
  704. #ifdef DECNETLIB
  705. __pcap_nametodnaddr(const char *name, u_short *res)
  706. {
  707. struct nodeent *getnodebyname();
  708. struct nodeent *nep;
  709. nep = getnodebyname(name);
  710. if (nep == ((struct nodeent *)0))
  711. return(0);
  712. memcpy((char *)res, (char *)nep->n_addr, sizeof(unsigned short));
  713. return(1);
  714. #else
  715. __pcap_nametodnaddr(const char *name _U_, u_short *res _U_)
  716. {
  717. return(0);
  718. #endif
  719. }