get.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /* $Id: $ */
  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 "../dlt.h"
  36. #ifdef DEBUG
  37. extern int debug;
  38. #endif
  39. /*
  40. * returns the L2 protocol (IP, ARP, etc)
  41. * or 0 for error
  42. */
  43. u_int16_t
  44. get_l2protocol(const u_char *pktdata, const int datalen, const int datalink)
  45. {
  46. eth_hdr_t *eth_hdr;
  47. vlan_hdr_t *vlan_hdr;
  48. hdlc_hdr_t *hdlc_hdr;
  49. sll_hdr_t *sll_hdr;
  50. u_int16_t ether_type;
  51. switch (datalink) {
  52. case DLT_RAW:
  53. return ETHERTYPE_IP;
  54. break;
  55. case DLT_EN10MB:
  56. eth_hdr = (eth_hdr_t *)pktdata;
  57. ether_type = ntohs(eth_hdr->ether_type);
  58. switch (ether_type) {
  59. case ETHERTYPE_VLAN: /* 802.1q */
  60. vlan_hdr = (vlan_hdr_t *)pktdata;
  61. return vlan_hdr->vlan_len;
  62. default:
  63. return ether_type; /* yes, return it in nbo */
  64. }
  65. break;
  66. case DLT_C_HDLC:
  67. hdlc_hdr = (hdlc_hdr_t *)pktdata;
  68. return hdlc_hdr->protocol;
  69. break;
  70. case DLT_LINUX_SLL:
  71. sll_hdr = (sll_hdr_t *)pktdata;
  72. return sll_hdr->sll_protocol;
  73. break;
  74. default:
  75. errx(1, "Unable to process unsupported DLT type: %s (0x%x)",
  76. pcap_datalink_val_to_description(datalink), datalink);
  77. }
  78. return 0;
  79. }
  80. /*
  81. * returns the length in number of bytes of the L2 header, or -1 on error
  82. */
  83. int
  84. get_l2len(const u_char *pktdata, const int datalen, const int datalink)
  85. {
  86. eth_hdr_t *eth_hdr;
  87. u_int16_t ether_type;
  88. switch (datalink) {
  89. case DLT_RAW:
  90. /* pktdata IS the ip header! */
  91. return 0;
  92. break;
  93. case DLT_EN10MB:
  94. eth_hdr = (eth_hdr_t *)pktdata;
  95. ether_type = ntohs(eth_hdr->ether_type);
  96. switch (ether_type) {
  97. case ETHERTYPE_VLAN: /* 802.1q */
  98. return LIBNET_802_1Q_H;
  99. break;
  100. default: /* ethernet */
  101. return LIBNET_ETH_H;
  102. break;
  103. }
  104. break;
  105. case DLT_C_HDLC:
  106. return CISCO_HDLC_LEN;
  107. break;
  108. case DLT_LINUX_SLL:
  109. return SLL_HDR_LEN;
  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. break;
  115. }
  116. return -1; /* we shouldn't get here */
  117. }
  118. /*
  119. * returns a ptr to the ip header + data or NULL if it's not IP
  120. * we may use an extra buffer for the ip header (and above)
  121. * on stricly aligned systems where the layer 2 header doesn't
  122. * fall on a 4 byte boundry (like a standard ethernet header)
  123. *
  124. * Note: you can cast the result as an ip_hdr_t, but you'll be able
  125. * to access data above the header minus any stripped L2 data
  126. */
  127. const u_char *
  128. get_ipv4(const u_char *pktdata, int datalen, int datalink, u_char **newbuff)
  129. {
  130. const u_char *ip_hdr = NULL;
  131. int l2_len = 0;
  132. u_int16_t proto;
  133. l2_len = get_l2len(pktdata, datalen, datalink);
  134. /* sanity... datalen must be > l2_len + IP header len*/
  135. if (l2_len + LIBNET_IPV4_H > datalen) {
  136. dbg(1, "get_ipv4(): Layer 2 len > total packet len, hence no IP header");
  137. return NULL;
  138. }
  139. proto = get_l2protocol(pktdata, datalen, datalink);
  140. if (proto != ETHERTYPE_IP)
  141. return NULL;
  142. #ifdef FORCE_ALIGN
  143. /*
  144. * copy layer 3 and up to our temp packet buffer
  145. * for now on, we have to edit the packetbuff because
  146. * just before we send the packet, we copy the packetbuff
  147. * back onto the pkt.data + l2len buffer
  148. * we do all this work to prevent byte alignment issues
  149. */
  150. if (l2_len % 4) {
  151. ip_hdr = *newbuff;
  152. memcpy(ip_hdr, (pktdata + l2_len), (datalen - l2_len));
  153. } else {
  154. /* we don't have to do a memcpy if l2_len lands on a boundry */
  155. ip_hdr = (pktdata + l2_len);
  156. }
  157. #else
  158. /*
  159. * on non-strict byte align systems, don't need to memcpy(),
  160. * just point to l2len bytes into the existing buffer
  161. */
  162. ip_hdr = (pktdata + l2_len);
  163. #endif
  164. return ip_hdr;
  165. }
  166. /*
  167. * returns a pointer to the layer 4 header which is just beyond the IP header
  168. */
  169. void *
  170. get_layer4(const ip_hdr_t * ip_hdr)
  171. {
  172. void *ptr;
  173. ptr = (u_int32_t *) ip_hdr + ip_hdr->ip_hl;
  174. return ((void *)ptr);
  175. }
  176. /*
  177. * get_name2addr4()
  178. * stolen from LIBNET since I didn't want to have to deal with passing a libnet_t
  179. */
  180. u_int32_t
  181. get_name2addr4(const char *hostname, u_int8_t dnslookup)
  182. {
  183. struct in_addr addr;
  184. struct hostent *host_ent;
  185. u_int32_t m;
  186. u_int val;
  187. int i;
  188. if (dnslookup == LIBNET_RESOLVE)
  189. {
  190. if ((addr.s_addr = inet_addr(hostname)) == -1)
  191. {
  192. if (!(host_ent = gethostbyname(hostname)))
  193. {
  194. warnx("unable to resolve %s: %s", hostname, strerror(errno));
  195. /* XXX - this is actually 255.255.255.255 */
  196. return (-1);
  197. }
  198. memcpy(&addr.s_addr, host_ent->h_addr, sizeof(addr.s_addr)); /* was:
  199. * host_ent->h_length);
  200. */
  201. }
  202. /* network byte order */
  203. return (addr.s_addr);
  204. }
  205. else
  206. {
  207. /*
  208. * We only want dots 'n decimals.
  209. */
  210. if (!isdigit(hostname[0]))
  211. {
  212. warnx("Expected dotted-quad notation (%s) when DNS lookups are disabled", hostname);
  213. /* XXX - this is actually 255.255.255.255 */
  214. return (-1);
  215. }
  216. m = 0;
  217. for (i = 0; i < 4; i++)
  218. {
  219. m <<= 8;
  220. if (*hostname)
  221. {
  222. val = 0;
  223. while (*hostname && *hostname != '.')
  224. {
  225. val *= 10;
  226. val += *hostname - '0';
  227. if (val > 255)
  228. {
  229. dbg(4, "value %d > 255 for dotted quad", val);
  230. /* XXX - this is actually 255.255.255.255 */
  231. return (-1);
  232. }
  233. hostname++;
  234. }
  235. m |= val;
  236. if (*hostname)
  237. {
  238. hostname++;
  239. }
  240. }
  241. }
  242. /* host byte order */
  243. return (ntohl(m));
  244. }
  245. }
  246. /*
  247. Local Variables:
  248. mode:c
  249. indent-tabs-mode:nil
  250. c-basic-offset:4
  251. End:
  252. */