get.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633
  1. /* $Id: get.c 2335 2009-05-11 22:16:37Z aturner $ */
  2. /*
  3. * Copyright (c) 2001-2005 Aaron Turner.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the names of the copyright owners nor the names of its
  16. * contributors may be used to endorse or promote products derived from
  17. * this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  20. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  21. * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  22. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  23. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  25. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  27. * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  28. * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  29. * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. */
  31. #include "config.h"
  32. #include "defines.h"
  33. #include "common.h"
  34. #include "../../lib/sll.h"
  35. #include <sys/types.h>
  36. #include <sys/socket.h>
  37. #include <netinet/in.h>
  38. #include <arpa/inet.h>
  39. #include <ctype.h>
  40. #include <string.h>
  41. #include <stdlib.h>
  42. #ifdef DEBUG
  43. extern int debug;
  44. #endif
  45. #if defined HAVE_PCAP_VERSION && ! defined HAVE_WIN32
  46. extern const char pcap_version[];
  47. #endif
  48. /**
  49. * Depending on what version of libpcap/WinPcap there are different ways to get the
  50. * version of the libpcap/WinPcap library. This presents a unified way to get that
  51. * information.
  52. */
  53. const char *
  54. get_pcap_version(void)
  55. {
  56. #if defined HAVE_WINPCAP
  57. static char ourver[255];
  58. char *last, *version;
  59. /* WinPcap returns a string like:
  60. * WinPcap version 4.0 (packet.dll version 4.0.0.755), based on libpcap version 0.9.5
  61. */
  62. version = safe_strdup(pcap_lib_version());
  63. strtok_r(version, " ", &last);
  64. strtok_r(NULL, " ", &last);
  65. strlcpy(ourver, strtok_r(NULL, " ", &last), 255);
  66. safe_free(version);
  67. return ourver;
  68. #elif defined HAVE_PCAP_VERSION
  69. return pcap_version;
  70. #else
  71. return pcap_lib_version();
  72. #endif
  73. }
  74. /**
  75. * returns the L2 protocol (IP, ARP, etc)
  76. * or 0 for error
  77. */
  78. u_int16_t
  79. get_l2protocol(const u_char *pktdata, const int datalen, const int datalink)
  80. {
  81. eth_hdr_t *eth_hdr;
  82. vlan_hdr_t *vlan_hdr;
  83. hdlc_hdr_t *hdlc_hdr;
  84. sll_hdr_t *sll_hdr;
  85. u_int16_t ether_type;
  86. assert(pktdata);
  87. assert(datalen);
  88. switch (datalink) {
  89. case DLT_RAW:
  90. return ETHERTYPE_IP;
  91. break;
  92. case DLT_EN10MB:
  93. eth_hdr = (eth_hdr_t *)pktdata;
  94. ether_type = ntohs(eth_hdr->ether_type);
  95. switch (ether_type) {
  96. case ETHERTYPE_VLAN: /* 802.1q */
  97. vlan_hdr = (vlan_hdr_t *)pktdata;
  98. return ntohs(vlan_hdr->vlan_len);
  99. default:
  100. return ether_type; /* yes, return it in host byte order */
  101. }
  102. break;
  103. case DLT_C_HDLC:
  104. hdlc_hdr = (hdlc_hdr_t *)pktdata;
  105. return hdlc_hdr->protocol;
  106. break;
  107. case DLT_LINUX_SLL:
  108. sll_hdr = (sll_hdr_t *)pktdata;
  109. return sll_hdr->sll_protocol;
  110. break;
  111. default:
  112. errx(-1, "Unable to process unsupported DLT type: %s (0x%x)",
  113. pcap_datalink_val_to_description(datalink), datalink);
  114. }
  115. return 0;
  116. }
  117. /**
  118. * returns the length in number of bytes of the L2 header, or -1 on error
  119. */
  120. int
  121. get_l2len(const u_char *pktdata, const int datalen, const int datalink)
  122. {
  123. eth_hdr_t *eth_hdr;
  124. assert(pktdata);
  125. assert(datalen);
  126. switch (datalink) {
  127. case DLT_RAW:
  128. /* pktdata IS the ip header! */
  129. return 0;
  130. break;
  131. case DLT_EN10MB:
  132. eth_hdr = (struct tcpr_ethernet_hdr *)pktdata;
  133. switch (ntohs(eth_hdr->ether_type)) {
  134. case ETHERTYPE_VLAN:
  135. return 18;
  136. break;
  137. default:
  138. return 14;
  139. break;
  140. }
  141. break;
  142. case DLT_C_HDLC:
  143. return CISCO_HDLC_LEN;
  144. break;
  145. case DLT_LINUX_SLL:
  146. return SLL_HDR_LEN;
  147. break;
  148. default:
  149. errx(-1, "Unable to process unsupported DLT type: %s (0x%x)",
  150. pcap_datalink_val_to_description(datalink), datalink);
  151. break;
  152. }
  153. return -1; /* we shouldn't get here */
  154. }
  155. /**
  156. * returns a ptr to the ip header + data or NULL if it's not IP
  157. * we may use an extra buffer for the ip header (and above)
  158. * on stricly aligned systems where the layer 2 header doesn't
  159. * fall on a 4 byte boundry (like a standard ethernet header)
  160. *
  161. * Note: you can cast the result as an ip_hdr_t, but you'll be able
  162. * to access data above the header minus any stripped L2 data
  163. */
  164. const u_char *
  165. get_ipv4(const u_char *pktdata, int datalen, int datalink, u_char **newbuff)
  166. {
  167. const u_char *ip_hdr = NULL;
  168. int l2_len = 0;
  169. u_int16_t proto;
  170. assert(pktdata);
  171. assert(datalen);
  172. assert(*newbuff);
  173. l2_len = get_l2len(pktdata, datalen, datalink);
  174. /* sanity... datalen must be > l2_len + IP header len*/
  175. if (l2_len + TCPR_IPV4_H > datalen) {
  176. dbg(1, "get_ipv4(): Layer 2 len > total packet len, hence no IP header");
  177. return NULL;
  178. }
  179. proto = get_l2protocol(pktdata, datalen, datalink);
  180. if (proto != ETHERTYPE_IP)
  181. return NULL;
  182. #ifdef FORCE_ALIGN
  183. /*
  184. * copy layer 3 and up to our temp packet buffer
  185. * for now on, we have to edit the packetbuff because
  186. * just before we send the packet, we copy the packetbuff
  187. * back onto the pkt.data + l2len buffer
  188. * we do all this work to prevent byte alignment issues
  189. */
  190. if (l2_len % 4) {
  191. ip_hdr = *newbuff;
  192. memcpy(ip_hdr, (pktdata + l2_len), (datalen - l2_len));
  193. } else {
  194. /* we don't have to do a memcpy if l2_len lands on a boundry */
  195. ip_hdr = (pktdata + l2_len);
  196. }
  197. #else
  198. /*
  199. * on non-strict byte align systems, don't need to memcpy(),
  200. * just point to l2len bytes into the existing buffer
  201. */
  202. ip_hdr = (pktdata + l2_len);
  203. #endif
  204. return ip_hdr;
  205. }
  206. const u_char *
  207. get_ipv6(const u_char *pktdata, int datalen, int datalink, u_char **newbuff)
  208. {
  209. const u_char *ip6_hdr = NULL;
  210. int l2_len = 0;
  211. u_int16_t proto;
  212. assert(pktdata);
  213. assert(datalen);
  214. assert(*newbuff);
  215. l2_len = get_l2len(pktdata, datalen, datalink);
  216. /* sanity... datalen must be > l2_len + IP header len*/
  217. if (l2_len + TCPR_IPV6_H > datalen) {
  218. dbg(1, "get_ipv6(): Layer 2 len > total packet len, hence no IPv6 header");
  219. return NULL;
  220. }
  221. proto = get_l2protocol(pktdata, datalen, datalink);
  222. if (proto != ETHERTYPE_IP6)
  223. return NULL;
  224. #ifdef FORCE_ALIGN
  225. /*
  226. * copy layer 3 and up to our temp packet buffer
  227. * for now on, we have to edit the packetbuff because
  228. * just before we send the packet, we copy the packetbuff
  229. * back onto the pkt.data + l2len buffer
  230. * we do all this work to prevent byte alignment issues
  231. */
  232. if (l2_len % 4) {
  233. ip6_hdr = *newbuff;
  234. memcpy(ip6_hdr, (pktdata + l2_len), (datalen - l2_len));
  235. } else {
  236. /* we don't have to do a memcpy if l2_len lands on a boundry */
  237. ip6_hdr = (pktdata + l2_len);
  238. }
  239. #else
  240. /*
  241. * on non-strict byte align systems, don't need to memcpy(),
  242. * just point to l2len bytes into the existing buffer
  243. */
  244. ip6_hdr = (pktdata + l2_len);
  245. #endif
  246. return ip6_hdr;
  247. }
  248. /**
  249. * returns a pointer to the layer 4 header which is just beyond the IPv4 header
  250. */
  251. void *
  252. get_layer4_v4(const ipv4_hdr_t *ip_hdr)
  253. {
  254. void *ptr;
  255. assert(ip_hdr);
  256. ptr = (u_int32_t *) ip_hdr + ip_hdr->ip_hl;
  257. return ((void *)ptr);
  258. }
  259. /**
  260. * returns a pointer to the layer 4 header which is just beyond the IPv6 header
  261. * and any exension headers or NULL when there is none as in the case of
  262. * v6 Frag or ESP header. Function is recursive.
  263. */
  264. void *
  265. get_layer4_v6(const ipv6_hdr_t *ip6_hdr)
  266. {
  267. struct tcpr_ipv6_ext_hdr_base *next, *exthdr;
  268. u_int8_t proto;
  269. assert(ip6_hdr);
  270. /* jump to the end of the IPv6 header */
  271. next = (struct tcpr_ipv6_ext_hdr_base *)((u_char *)ip6_hdr + TCPR_IPV6_H);
  272. proto = ip6_hdr->ip_nh;
  273. while (TRUE) {
  274. dbgx(3, "Processing proto: 0x%hx", proto);
  275. switch (proto) {
  276. /* recurse due to v6-in-v6, need to recast next as an IPv6 Header */
  277. case TCPR_IPV6_NH_IPV6:
  278. dbg(3, "recursing due to v6-in-v6");
  279. return get_layer4_v6((ipv6_hdr_t *)next);
  280. break;
  281. /* loop again */
  282. case TCPR_IPV6_NH_AH:
  283. case TCPR_IPV6_NH_ROUTING:
  284. case TCPR_IPV6_NH_DESTOPTS:
  285. case TCPR_IPV6_NH_HBH:
  286. dbgx(3, "Going deeper due to extension header 0x%02X", proto);
  287. exthdr = get_ipv6_next(next);
  288. proto = exthdr->ip_nh;
  289. next = exthdr;
  290. break;
  291. /*
  292. * Can't handle. Unparsable IPv6 fragment/encrypted data
  293. */
  294. case TCPR_IPV6_NH_FRAGMENT:
  295. case TCPR_IPV6_NH_ESP:
  296. return NULL;
  297. break;
  298. /*
  299. * no further processing, either TCP, UDP, ICMP, etc...
  300. */
  301. default:
  302. if (proto != ip6_hdr->ip_nh) {
  303. dbgx(3, "Returning byte offset of this ext header: %u", IPV6_EXTLEN_TO_BYTES(next->ip_len));
  304. return (void *)((u_char *)next + IPV6_EXTLEN_TO_BYTES(next->ip_len));
  305. } else {
  306. dbgx(3, "%s", "Returning end of IPv6 Header");
  307. return next;
  308. }
  309. break;
  310. } /* switch */
  311. } /* while */
  312. }
  313. /**
  314. * returns the next payload or header of the current extention header
  315. * returns NULL for none/ESP.
  316. */
  317. void *
  318. get_ipv6_next(struct tcpr_ipv6_ext_hdr_base *exthdr)
  319. {
  320. int len = 0;
  321. assert(exthdr);
  322. dbgx(3, "Jumping to next IPv6 header. Processing 0x%02x", exthdr->ip_nh);
  323. switch (exthdr->ip_nh) {
  324. /* no further processing */
  325. case TCPR_IPV6_NH_NO_NEXT:
  326. case TCPR_IPV6_NH_ESP:
  327. dbg(3, "No-Next or ESP... can't go any further...");
  328. return NULL;
  329. break;
  330. /*
  331. * fragment header is fixed size
  332. * FIXME: Frag header has further ext headers (has a ip_nh field)
  333. * but I don't support it because there's never a full L4 + payload beyond.
  334. */
  335. case TCPR_IPV6_NH_FRAGMENT:
  336. dbg(3, "Looks like were a fragment header. Returning some frag'd data.");
  337. return (void *)((u_char *)exthdr + sizeof(struct tcpr_ipv6_frag_hdr));
  338. break;
  339. /* all the rest require us to go deeper using the ip_len field */
  340. case TCPR_IPV6_NH_IPV6:
  341. case TCPR_IPV6_NH_ROUTING:
  342. case TCPR_IPV6_NH_DESTOPTS:
  343. case TCPR_IPV6_NH_HBH:
  344. case TCPR_IPV6_NH_AH:
  345. len = IPV6_EXTLEN_TO_BYTES(exthdr->ip_len);
  346. dbgx(3, "Looks like we're an ext header (0x%hhx). Jumping %u bytes to the next", exthdr->ip_nh, len);
  347. return (void *)((u_char *)exthdr + len);
  348. break;
  349. default:
  350. dbg(3, "Must not be a v6 extension header... returning self");
  351. return (void *)exthdr;
  352. break;
  353. }
  354. }
  355. /**
  356. * returns the protocol of the actual layer4 header by processing through
  357. * the extension headers
  358. */
  359. u_int8_t
  360. get_ipv6_l4proto(const ipv6_hdr_t *ip6_hdr)
  361. {
  362. u_char *ptr = (u_char *)ip6_hdr + TCPR_IPV6_H; /* jump to the end of the IPv6 header */
  363. u_int8_t proto;
  364. struct tcpr_ipv6_ext_hdr_base *exthdr = NULL;
  365. proto = ip6_hdr->ip_nh;
  366. assert(ip6_hdr);
  367. while (TRUE) {
  368. dbgx(3, "Processing next proto 0x%02X", proto);
  369. switch (proto) {
  370. /* no further processing for IPV6 types with nothing beyond them */
  371. case TCPR_IPV6_NH_FRAGMENT:
  372. case TCPR_IPV6_NH_ESP:
  373. dbg(3, "No-Next or ESP... can't go any further...");
  374. return proto;
  375. break;
  376. /* recurse */
  377. case TCPR_IPV6_NH_IPV6:
  378. dbg(3, "Recursing due to v6 in v6");
  379. return get_ipv6_l4proto((ipv6_hdr_t *)ptr);
  380. break;
  381. /* loop again */
  382. case TCPR_IPV6_NH_AH:
  383. case TCPR_IPV6_NH_ROUTING:
  384. case TCPR_IPV6_NH_DESTOPTS:
  385. case TCPR_IPV6_NH_HBH:
  386. dbgx(3, "Jumping to next extension header (0x%hhx)", proto);
  387. exthdr = get_ipv6_next((struct tcpr_ipv6_ext_hdr_base *)ptr);
  388. proto = exthdr->ip_nh;
  389. ptr = (u_char *)exthdr;
  390. break;
  391. /* should be TCP, UDP or the like */
  392. default:
  393. dbgx(3, "Selecting next L4 Proto as: 0x%02x", proto);
  394. return proto;
  395. }
  396. }
  397. }
  398. /**
  399. * get_name2addr4()
  400. * stolen from LIBNET since I didn't want to have to deal with
  401. * passing a libnet_t around. Returns 0xFFFFFFFF (255.255.255.255)
  402. * on error
  403. */
  404. u_int32_t
  405. get_name2addr4(const char *hostname, u_int8_t dnslookup)
  406. {
  407. struct in_addr addr;
  408. #if ! defined HAVE_INET_ATON && defined HAVE_INET_ADDR
  409. struct hostent *host_ent;
  410. #endif
  411. u_int32_t m;
  412. u_int val;
  413. int i;
  414. if (dnslookup == DNS_RESOLVE) {
  415. #ifdef HAVE_INET_ATON
  416. if (inet_aton(hostname, &addr) != 1) {
  417. return(0xffffffff);
  418. }
  419. #elif defined HAVE_INET_ADDR
  420. if ((addr.s_addr = inet_addr(hostname)) == INADDR_NONE) {
  421. if (!(host_ent = gethostbyname(hostname))) {
  422. warnx("unable to resolve %s: %s", hostname, strerror(errno));
  423. /* XXX - this is actually 255.255.255.255 */
  424. return (0xffffffff);
  425. }
  426. /* was: host_ent->h_length); */
  427. memcpy(&addr.s_addr, host_ent->h_addr, sizeof(addr.s_addr));
  428. }
  429. #else
  430. warn("Unable to support get_name2addr4 w/ resolve");
  431. /* call ourselves recursively once w/o resolving the hostname */
  432. return get_name2addr4(hostname, DNS_DONT_RESOLVE);
  433. #endif
  434. /* return in network byte order */
  435. return (addr.s_addr);
  436. } else {
  437. /*
  438. * We only want dots 'n decimals.
  439. */
  440. if (!isdigit(hostname[0])) {
  441. warnx("Expected dotted-quad notation (%s) when DNS lookups are disabled", hostname);
  442. /* XXX - this is actually 255.255.255.255 */
  443. return (-1);
  444. }
  445. m = 0;
  446. for (i = 0; i < 4; i++) {
  447. m <<= 8;
  448. if (*hostname) {
  449. val = 0;
  450. while (*hostname && *hostname != '.') {
  451. val *= 10;
  452. val += *hostname - '0';
  453. if (val > 255) {
  454. dbgx(4, "value %d > 255 for dotted quad", val);
  455. /* XXX - this is actually 255.255.255.255 */
  456. return (-1);
  457. }
  458. hostname++;
  459. }
  460. m |= val;
  461. if (*hostname) {
  462. hostname++;
  463. }
  464. }
  465. }
  466. /* host byte order */
  467. return (ntohl(m));
  468. }
  469. }
  470. int
  471. get_name2addr6(const char *hostname, u_int8_t dnslookup, struct tcpr_in6_addr *addr)
  472. {
  473. (void)dnslookup;
  474. #ifdef HAVE_INET_PTON
  475. return inet_pton(AF_INET6, hostname, addr);
  476. #else
  477. #error "Unable to support get_name2addr6."
  478. #endif
  479. return -1;
  480. }
  481. /**
  482. * Generic wrapper around inet_ntop() and inet_ntoa() depending on whichever
  483. * is available on your system
  484. */
  485. const char *
  486. get_addr2name4(const u_int32_t ip, u_int8_t dnslookup)
  487. {
  488. struct in_addr addr;
  489. static char *new_string = NULL;
  490. if (new_string == NULL)
  491. new_string = (char *)safe_malloc(255);
  492. new_string[0] = '\0';
  493. addr.s_addr = ip;
  494. #ifdef HAVE_INET_NTOP
  495. if (inet_ntop(AF_INET, &addr, new_string, 255) == NULL) {
  496. warnx("Unable to convert 0x%x to a string", ip);
  497. strlcpy(new_string, "", sizeof(new_string));
  498. }
  499. return new_string;
  500. #elif defined HAVE_INET_NTOA
  501. return inet_ntoa(&addr);
  502. #else
  503. #error "Unable to support get_addr2name4."
  504. #endif
  505. if (dnslookup != DNS_DONT_RESOLVE) {
  506. warn("Sorry, we don't support name resolution.");
  507. }
  508. return new_string;
  509. }
  510. const char *
  511. get_addr2name6(const struct tcpr_in6_addr *addr, u_int8_t dnslookup)
  512. {
  513. static char *new_string = NULL;
  514. if (new_string == NULL)
  515. new_string = (char *)safe_malloc(255);
  516. new_string[0] = '\0';
  517. #ifdef HAVE_INET_NTOP
  518. if (inet_ntop(AF_INET6, addr, new_string, 255) == NULL) {
  519. warn("Unable to convert addr to a string");
  520. strlcpy(new_string, "", sizeof(new_string));
  521. }
  522. return new_string;
  523. #else
  524. #error "Unable to support get_addr2name6."
  525. #endif
  526. if (dnslookup != DNS_DONT_RESOLVE) {
  527. warn("Sorry, we don't support name resolution.");
  528. }
  529. return new_string;
  530. }
  531. const char *
  532. get_cidr2name(const tcpr_cidr_t *cidr_ptr, u_int8_t dnslookup)
  533. {
  534. if (cidr_ptr->family == AF_INET) {
  535. return get_addr2name4(cidr_ptr->u.network, dnslookup);
  536. } else if (cidr_ptr->family == AF_INET6) {
  537. return get_addr2name6(&cidr_ptr->u.network6, dnslookup);
  538. } else {
  539. return NULL;
  540. }
  541. }