1 /*
2 * $Id: libnet_init.c,v 1.17 2004/03/16 18:40:59 mike Exp $
3 *
4 * libnet
5 * libnet_init.c - Initilization 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 libnet_t *
libnet_init(int injection_type,const char * device,char * err_buf)43 libnet_init(int injection_type, const char *device, char *err_buf)
44 {
45 libnet_t *l = NULL;
46
47 #if defined(__WIN32__)
48 WSADATA wsaData;
49
50 if ((WSAStartup(0x0202, &wsaData)) != 0)
51 {
52 snprintf(err_buf, LIBNET_ERRBUF_SIZE,
53 "%s(): unable to initialize winsock 2\n", __func__);
54 goto bad;
55 }
56 #endif
57
58 l = (libnet_t *)malloc(sizeof (libnet_t));
59 if (l == NULL)
60 {
61 snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s(): malloc(): %s\n", __func__,
62 strerror(errno));
63 goto bad;
64 }
65
66 memset(l, 0, sizeof (*l));
67
68 l->injection_type = injection_type;
69 l->ptag_state = LIBNET_PTAG_INITIALIZER;
70 l->device = (device ? strdup(device) : NULL);
71 l->fd = -1;
72
73 strncpy(l->label, LIBNET_LABEL_DEFAULT, LIBNET_LABEL_SIZE);
74 l->label[LIBNET_LABEL_SIZE - 1] = '\0';
75
76 switch (l->injection_type)
77 {
78 case LIBNET_NONE:
79 break;
80 case LIBNET_LINK:
81 case LIBNET_LINK_ADV:
82 if (libnet_select_device(l) == -1)
83 {
84 snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s", l->err_buf);
85 goto bad;
86 }
87 if (libnet_open_link(l) == -1)
88 {
89 snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s", l->err_buf);
90 goto bad;
91 }
92 break;
93 case LIBNET_RAW4:
94 case LIBNET_RAW4_ADV:
95 if (libnet_open_raw4(l) == -1)
96 {
97 snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s", l->err_buf);
98 goto bad;
99 }
100 break;
101 case LIBNET_RAW6:
102 case LIBNET_RAW6_ADV:
103 if (libnet_open_raw6(l) == -1)
104 {
105 snprintf(err_buf, LIBNET_ERRBUF_SIZE, "%s", l->err_buf);
106 goto bad;
107 }
108 break;
109 default:
110 snprintf(err_buf, LIBNET_ERRBUF_SIZE,
111 "%s(): unsupported injection type\n", __func__);
112 goto bad;
113 break;
114 }
115
116 return (l);
117
118 bad:
119 if (l)
120 {
121 libnet_destroy(l);
122 }
123 return (NULL);
124 }
125
126 void
libnet_destroy(libnet_t * l)127 libnet_destroy(libnet_t *l)
128 {
129 if (l)
130 {
131 close(l->fd);
132 free(l->device);
133 libnet_clear_packet(l);
134 free(l);
135 }
136 }
137
138 void
libnet_clear_packet(libnet_t * l)139 libnet_clear_packet(libnet_t *l)
140 {
141 libnet_pblock_t *p;
142
143 if (!l)
144 {
145 return;
146 }
147
148 while((p = l->protocol_blocks))
149 {
150 libnet_pblock_delete(l, p);
151 }
152
153 /* All pblocks are deleted, so start the tag count over from 1. */
154 l->ptag_state = 0;
155 }
156
157 void
libnet_stats(libnet_t * l,struct libnet_stats * ls)158 libnet_stats(libnet_t *l, struct libnet_stats *ls)
159 {
160 if (l == NULL)
161 {
162 return;
163 }
164
165 ls->packets_sent = l->stats.packets_sent;
166 ls->packet_errors = l->stats.packet_errors;
167 ls->bytes_written = l->stats.bytes_written;
168 }
169
170 int
libnet_getfd(libnet_t * l)171 libnet_getfd(libnet_t *l)
172 {
173 if (l == NULL)
174 {
175 return (-1);
176 }
177
178 return (l->fd);
179 }
180
181 const char *
libnet_getdevice(libnet_t * l)182 libnet_getdevice(libnet_t *l)
183 {
184 if (l == NULL)
185 {
186 return (NULL);
187 }
188
189 return (l->device);
190 }
191
192 uint8_t *
libnet_getpbuf(libnet_t * l,libnet_ptag_t ptag)193 libnet_getpbuf(libnet_t *l, libnet_ptag_t ptag)
194 {
195 libnet_pblock_t *p;
196
197 if (l == NULL)
198 {
199 return (NULL);
200 }
201
202 p = libnet_pblock_find(l, ptag);
203 if (p == NULL)
204 {
205 /* err msg set in libnet_pblock_find() */
206 return (NULL);
207 }
208 else
209 {
210 return (p->buf);
211 }
212 }
213
214 uint32_t
libnet_getpbuf_size(libnet_t * l,libnet_ptag_t ptag)215 libnet_getpbuf_size(libnet_t *l, libnet_ptag_t ptag)
216 {
217 libnet_pblock_t *p;
218
219 if (l == NULL)
220 {
221 return (0);
222 }
223
224 p = libnet_pblock_find(l, ptag);
225 if (p == NULL)
226 {
227 /* err msg set in libnet_pblock_find() */
228 return (0);
229 }
230 else
231 {
232 return (p->b_len);
233 }
234 }
235
236 uint32_t
libnet_getpacket_size(libnet_t * l)237 libnet_getpacket_size(libnet_t *l)
238 {
239 /* Why doesn't this return l->total_size? */
240 libnet_pblock_t *p;
241 uint32_t n;
242
243 if (l == NULL)
244 {
245 return (0);
246 }
247
248 n = 0;
249 p = l->protocol_blocks;
250 if (p)
251 {
252 for (; p; p = p->next)
253 {
254 n += p->b_len;
255 }
256 }
257 return (n);
258 }
259
260 /* EOF */
261