PageRenderTime 54ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/libnet-1.1.6/src/libnet_raw.c

#
C | 263 lines | 180 code | 27 blank | 56 comment | 32 complexity | 08e0b9543753b70e0ddf5058ce7e4cfa MD5 | raw file
  1. /*
  2. * $Id: libnet_raw.c,v 1.9 2004/02/18 18:19:00 mike Exp $
  3. *
  4. * libnet
  5. * libnet_raw.c - raw sockets routines
  6. *
  7. * Copyright (c) 1998 - 2004 Mike D. Schiffman <mike@infonexus.com>
  8. * All rights reserved.
  9. *
  10. * Redistribution and use in source and binary forms, with or without
  11. * modification, are permitted provided that the following conditions
  12. * are met:
  13. * 1. Redistributions of source code must retain the above copyright
  14. * notice, this list of conditions and the following disclaimer.
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in the
  17. * documentation and/or other materials provided with the distribution.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  23. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. *
  31. */
  32. #if (HAVE_CONFIG_H)
  33. #include "../include/config.h"
  34. #endif
  35. #if (!(_WIN32) || (__CYGWIN__))
  36. #include "../include/libnet.h"
  37. #else
  38. #include "../include/win32/libnet.h"
  39. #endif
  40. #if defined (__WIN32__)
  41. int
  42. libnet_open_raw4(libnet_t *l)
  43. {
  44. return (libnet_open_link(l));
  45. }
  46. int
  47. libnet_open_raw6(libnet_t *l)
  48. {
  49. return (libnet_open_link(l));
  50. }
  51. int
  52. libnet_close_raw4(libnet_t *l)
  53. {
  54. return (libnet_close_link_interface(l));
  55. }
  56. int
  57. libnet_close_raw6(libnet_t *l)
  58. {
  59. return (libnet_close_link_interface(l));
  60. }
  61. #else
  62. int
  63. libnet_open_raw4(libnet_t *l)
  64. {
  65. int len; /* now supposed to be socklen_t, but maybe old systems used int? */
  66. #if !(__WIN32__)
  67. int n = 1;
  68. #if (__svr4__)
  69. void *nptr = &n;
  70. #else
  71. int *nptr = &n;
  72. #endif /* __svr4__ */
  73. #else
  74. BOOL n;
  75. #endif
  76. if (l == NULL)
  77. {
  78. return (-1);
  79. }
  80. l->fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
  81. if (l->fd == -1)
  82. {
  83. snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  84. "%s(): SOCK_RAW allocation failed: %s\n",
  85. __func__, strerror(errno));
  86. goto bad;
  87. }
  88. #ifdef IP_HDRINCL
  89. /*
  90. * man raw
  91. *
  92. * The IPv4 layer generates an IP header when sending a packet unless
  93. * the IP_HDRINCL socket option is enabled on the socket. When it
  94. * is enabled, the packet must contain an IP header. For
  95. * receiving the IP header is always included in the packet.
  96. */
  97. #if !(__WIN32__)
  98. if (setsockopt(l->fd, IPPROTO_IP, IP_HDRINCL, nptr, sizeof(n)) == -1)
  99. #else
  100. n = TRUE;
  101. if (setsockopt(l->fd, IPPROTO_IP, IP_HDRINCL, &n, sizeof(n)) == -1)
  102. #endif
  103. {
  104. snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  105. "%s(): set IP_HDRINCL failed: %s\n",
  106. __func__, strerror(errno));
  107. goto bad;
  108. }
  109. #endif /* IP_HDRINCL */
  110. #ifdef SO_SNDBUF
  111. /*
  112. * man 7 socket
  113. *
  114. * Sets and gets the maximum socket send buffer in bytes.
  115. *
  116. * Taken from libdnet by Dug Song
  117. */
  118. len = sizeof(n);
  119. if (getsockopt(l->fd, SOL_SOCKET, SO_SNDBUF, &n, &len) < 0)
  120. {
  121. snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  122. "%s(): get SO_SNDBUF failed: %s\n",
  123. __func__, strerror(errno));
  124. goto bad;
  125. }
  126. for (n += 128; n < 1048576; n += 128)
  127. {
  128. if (setsockopt(l->fd, SOL_SOCKET, SO_SNDBUF, &n, len) < 0)
  129. {
  130. if (errno == ENOBUFS)
  131. {
  132. break;
  133. }
  134. snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  135. "%s(): set SO_SNDBUF failed: %s\n",
  136. __func__, strerror(errno));
  137. goto bad;
  138. }
  139. }
  140. #endif
  141. #ifdef SO_BROADCAST
  142. /*
  143. * man 7 socket
  144. *
  145. * Set or get the broadcast flag. When enabled, datagram sockets
  146. * receive packets sent to a broadcast address and they are allowed
  147. * to send packets to a broadcast address. This option has no
  148. * effect on stream-oriented sockets.
  149. */
  150. if (setsockopt(l->fd, SOL_SOCKET, SO_BROADCAST, nptr, sizeof(n)) == -1)
  151. {
  152. snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  153. "%s(): set SO_BROADCAST failed: %s\n",
  154. __func__, strerror(errno));
  155. goto bad;
  156. }
  157. #endif /* SO_BROADCAST */
  158. return (l->fd);
  159. bad:
  160. return (-1);
  161. }
  162. int
  163. libnet_close_raw4(libnet_t *l)
  164. {
  165. if (l == NULL)
  166. {
  167. return (-1);
  168. }
  169. return (close(l->fd));
  170. }
  171. #if ((defined HAVE_SOLARIS && !defined HAVE_SOLARIS_IPV6) || defined (__WIN32__))
  172. int libnet_open_raw6(libnet_t *l)
  173. {
  174. return (-1);
  175. }
  176. #else
  177. int
  178. libnet_open_raw6(libnet_t *l)
  179. {
  180. #if !(__WIN32__)
  181. #if (__svr4__)
  182. int one = 1;
  183. void *oneptr = &one;
  184. #else
  185. #if (__linux__)
  186. int one = 1;
  187. int *oneptr = &one;
  188. #endif
  189. #endif /* __svr4__ */
  190. #else
  191. BOOL one;
  192. #endif
  193. /* Solaris IPv6 stuff */
  194. if (l == NULL)
  195. {
  196. return (-1);
  197. }
  198. l->fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
  199. if (l->fd == -1)
  200. {
  201. snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  202. "%s(): SOCK_RAW allocation failed: %s\n", __func__,
  203. strerror(errno));
  204. goto bad;
  205. }
  206. #if (__linux__)
  207. if (setsockopt(l->fd, SOL_SOCKET, SO_BROADCAST, oneptr, sizeof(one)) == -1)
  208. {
  209. snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  210. "%s(): set SO_BROADCAST failed: %s\n", __func__,
  211. strerror(errno));
  212. goto bad;
  213. }
  214. if(l->device != NULL)
  215. if(setsockopt(l->fd, SOL_SOCKET, SO_BINDTODEVICE, l->device, strlen(l->device)) == -1) {
  216. snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
  217. "%s(): set SO_BINDTODEVICE failed: %s\n", __func__, strerror(errno));
  218. goto bad;
  219. }
  220. #endif /* __linux__ */
  221. return (l->fd);
  222. bad:
  223. return (-1);
  224. }
  225. #endif
  226. int
  227. libnet_close_raw6(libnet_t *l)
  228. {
  229. if (l == NULL)
  230. {
  231. return (-1);
  232. }
  233. return (close(l->fd));
  234. }
  235. #endif
  236. /* EOF */