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