Annotation of embedaddon/libnet/src/libnet_raw.c, revision 1.1.1.2
1.1 misho 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:
33: #if (HAVE_CONFIG_H)
34: #include "../include/config.h"
35: #endif
36: #if (!(_WIN32) || (__CYGWIN__))
37: #include "../include/libnet.h"
38: #else
39: #include "../include/win32/libnet.h"
40: #endif
41:
42: #if defined (__WIN32__)
43: int
44: libnet_open_raw4(libnet_t *l)
45: {
46: return (libnet_open_link(l));
47: }
48:
49: int
50: libnet_open_raw6(libnet_t *l)
51: {
52: return (libnet_open_link(l));
53: }
54:
55: int
56: libnet_close_raw4(libnet_t *l)
57: {
58: return (libnet_close_link_interface(l));
59: }
60:
61: int
62: libnet_close_raw6(libnet_t *l)
63: {
64: return (libnet_close_link_interface(l));
65: }
66: #else
67: int
68: libnet_open_raw4(libnet_t *l)
69: {
1.1.1.2 ! misho 70: int len; /* now supposed to be socklen_t, but maybe old systems used int? */
1.1 misho 71:
72: #if !(__WIN32__)
73: int n = 1;
74: #if (__svr4__)
75: void *nptr = &n;
76: #else
77: int *nptr = &n;
78: #endif /* __svr4__ */
79: #else
80: BOOL n;
81: #endif
82:
83: if (l == NULL)
84: {
85: return (-1);
86: }
87:
88: l->fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
89: if (l->fd == -1)
90: {
91: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
92: "%s(): SOCK_RAW allocation failed: %s\n",
93: __func__, strerror(errno));
94: goto bad;
95: }
96:
97: #ifdef IP_HDRINCL
98: /*
99: * man raw
100: *
101: * The IPv4 layer generates an IP header when sending a packet unless
102: * the IP_HDRINCL socket option is enabled on the socket. When it
103: * is enabled, the packet must contain an IP header. For
104: * receiving the IP header is always included in the packet.
105: */
106: #if !(__WIN32__)
107: if (setsockopt(l->fd, IPPROTO_IP, IP_HDRINCL, nptr, sizeof(n)) == -1)
108: #else
109: n = TRUE;
1.1.1.2 ! misho 110: if (setsockopt(l->fd, IPPROTO_IP, IP_HDRINCL, &n, sizeof(n)) == -1)
1.1 misho 111: #endif
112:
113: {
114: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
115: "%s(): set IP_HDRINCL failed: %s\n",
116: __func__, strerror(errno));
117: goto bad;
118: }
119: #endif /* IP_HDRINCL */
120:
121: #ifdef SO_SNDBUF
122:
123: /*
124: * man 7 socket
125: *
126: * Sets and gets the maximum socket send buffer in bytes.
127: *
128: * Taken from libdnet by Dug Song
129: */
130: len = sizeof(n);
131: if (getsockopt(l->fd, SOL_SOCKET, SO_SNDBUF, &n, &len) < 0)
132: {
133: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
134: "%s(): get SO_SNDBUF failed: %s\n",
135: __func__, strerror(errno));
136: goto bad;
137: }
138:
139: for (n += 128; n < 1048576; n += 128)
140: {
141: if (setsockopt(l->fd, SOL_SOCKET, SO_SNDBUF, &n, len) < 0)
142: {
143: if (errno == ENOBUFS)
144: {
145: break;
146: }
147: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
148: "%s(): set SO_SNDBUF failed: %s\n",
149: __func__, strerror(errno));
150: goto bad;
151: }
152: }
153: #endif
154:
155: #ifdef SO_BROADCAST
156: /*
157: * man 7 socket
158: *
159: * Set or get the broadcast flag. When enabled, datagram sockets
160: * receive packets sent to a broadcast address and they are allowed
161: * to send packets to a broadcast address. This option has no
162: * effect on stream-oriented sockets.
163: */
164: if (setsockopt(l->fd, SOL_SOCKET, SO_BROADCAST, nptr, sizeof(n)) == -1)
165: {
166: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
167: "%s(): set SO_BROADCAST failed: %s\n",
168: __func__, strerror(errno));
169: goto bad;
170: }
171: #endif /* SO_BROADCAST */
172: return (l->fd);
173:
174: bad:
175: return (-1);
176: }
177:
178:
179: int
180: libnet_close_raw4(libnet_t *l)
181: {
182: if (l == NULL)
183: {
184: return (-1);
185: }
186:
187: return (close(l->fd));
188: }
189:
190: #if ((defined HAVE_SOLARIS && !defined HAVE_SOLARIS_IPV6) || defined (__WIN32__))
191: int libnet_open_raw6(libnet_t *l)
192: {
193: return (-1);
194: }
195:
196: #else
197: int
198: libnet_open_raw6(libnet_t *l)
199: {
200: #if !(__WIN32__)
201: #if (__svr4__)
202: int one = 1;
203: void *oneptr = &one;
204: #else
205: #if (__linux__)
206: int one = 1;
207: int *oneptr = &one;
208: #endif
209: #endif /* __svr4__ */
210: #else
211: BOOL one;
212: #endif
213:
214: /* Solaris IPv6 stuff */
215:
216: if (l == NULL)
217: {
218: return (-1);
219: }
220:
1.1.1.2 ! misho 221: l->fd = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
1.1 misho 222: if (l->fd == -1)
223: {
224: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
225: "%s(): SOCK_RAW allocation failed: %s\n", __func__,
226: strerror(errno));
227: goto bad;
228: }
229:
230: #if (__linux__)
231: if (setsockopt(l->fd, SOL_SOCKET, SO_BROADCAST, oneptr, sizeof(one)) == -1)
232: {
233: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
234: "%s(): set SO_BROADCAST failed: %s\n", __func__,
235: strerror(errno));
236: goto bad;
237: }
1.1.1.2 ! misho 238: if(l->device != NULL)
! 239: if(setsockopt(l->fd, SOL_SOCKET, SO_BINDTODEVICE, l->device, strlen(l->device)) == -1) {
! 240: snprintf(l->err_buf, LIBNET_ERRBUF_SIZE,
! 241: "%s(): set SO_BINDTODEVICE failed: %s\n", __func__, strerror(errno));
! 242: goto bad;
! 243: }
! 244:
1.1 misho 245: #endif /* __linux__ */
246: return (l->fd);
247:
248: bad:
249: return (-1);
250: }
251: #endif
252:
253: int
254: libnet_close_raw6(libnet_t *l)
255: {
256: if (l == NULL)
257: {
258: return (-1);
259: }
260: return (close(l->fd));
261: }
262: #endif
263: /* EOF */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>