/[dynamips]/upstream/dynamips-0.2.7-RC2/net_io_filter.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /upstream/dynamips-0.2.7-RC2/net_io_filter.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (hide annotations)
Sat Oct 6 16:23:47 2007 UTC (16 years, 6 months ago) by dpavlin
Original Path: upstream/dynamips-0.2.7-RC1/net_io_filter.c
File MIME type: text/plain
File size: 7370 byte(s)
dynamips-0.2.7-RC1

1 dpavlin 1 /*
2 dpavlin 7 * Cisco router simulation platform.
3 dpavlin 1 * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4     *
5     * NetIO Filtering.
6     */
7    
8     #include <stdio.h>
9     #include <stdlib.h>
10     #include <string.h>
11     #include <stdarg.h>
12     #include <unistd.h>
13     #include <errno.h>
14     #include <signal.h>
15     #include <fcntl.h>
16     #include <ctype.h>
17     #include <time.h>
18     #include <sys/time.h>
19     #include <sys/stat.h>
20     #include <sys/types.h>
21     #include <sys/ioctl.h>
22     #include <sys/socket.h>
23     #include <sys/un.h>
24     #include <sys/wait.h>
25     #include <netinet/in.h>
26     #include <arpa/inet.h>
27     #include <netdb.h>
28     #include <pthread.h>
29 dpavlin 7 #include <pcap.h>
30 dpavlin 1
31     #include "registry.h"
32     #include "net.h"
33     #include "net_io.h"
34     #include "net_io_filter.h"
35    
36     /* Filter list */
37     static netio_pktfilter_t *pf_list = NULL;
38    
39     /* Find a filter */
40     netio_pktfilter_t *netio_filter_find(char *name)
41     {
42     netio_pktfilter_t *pf;
43    
44     for(pf=pf_list;pf;pf=pf->next)
45     if (!strcmp(pf->name,name))
46     return pf;
47    
48     return NULL;
49     }
50    
51     /* Add a new filter */
52     int netio_filter_add(netio_pktfilter_t *pf)
53     {
54     if (netio_filter_find(pf->name) != NULL)
55     return(-1);
56    
57     pf->next = pf_list;
58     pf_list = pf;
59     return(0);
60     }
61    
62     /* Bind a filter to a NIO */
63     int netio_filter_bind(netio_desc_t *nio,int direction,char *pf_name)
64     {
65     netio_pktfilter_t *pf;
66    
67     if (!(pf = netio_filter_find(pf_name)))
68     return(-1);
69    
70     if (direction == NETIO_FILTER_DIR_RX) {
71     nio->rx_filter_data = NULL;
72     nio->rx_filter = pf;
73 dpavlin 7 } else if (direction == NETIO_FILTER_DIR_TX) {
74 dpavlin 1 nio->tx_filter_data = NULL;
75     nio->tx_filter = pf;
76 dpavlin 7 } else {
77     nio->both_filter_data = NULL;
78     nio->both_filter = pf;
79 dpavlin 1 }
80     return(0);
81     }
82    
83     /* Unbind a filter from a NIO */
84     int netio_filter_unbind(netio_desc_t *nio,int direction)
85     {
86     netio_pktfilter_t *pf;
87     void **opt;
88    
89     if (direction == NETIO_FILTER_DIR_RX) {
90     opt = &nio->rx_filter_data;
91     pf = nio->rx_filter;
92 dpavlin 7 } else if (direction == NETIO_FILTER_DIR_TX) {
93 dpavlin 1 opt = &nio->tx_filter_data;
94     pf = nio->tx_filter;
95 dpavlin 7 } else {
96     opt = &nio->both_filter_data;
97     pf = nio->both_filter;
98 dpavlin 1 }
99    
100     if (!pf)
101     return(-1);
102    
103     pf->free(nio,opt);
104     return(0);
105     }
106    
107     /* Setup a filter */
108     int netio_filter_setup(netio_desc_t *nio,int direction,int argc,char *argv[])
109     {
110     netio_pktfilter_t *pf;
111     void **opt;
112    
113     if (direction == NETIO_FILTER_DIR_RX) {
114     opt = &nio->rx_filter_data;
115     pf = nio->rx_filter;
116 dpavlin 7 } else if (direction == NETIO_FILTER_DIR_TX) {
117 dpavlin 1 opt = &nio->tx_filter_data;
118     pf = nio->tx_filter;
119 dpavlin 7 } else {
120     opt = &nio->both_filter_data;
121     pf = nio->both_filter;
122 dpavlin 1 }
123    
124     if (!pf)
125     return(-1);
126    
127     return(pf->setup(nio,opt,argc,argv));
128     }
129    
130     /* ======================================================================== */
131 dpavlin 7 /* Packet Capture ("capture") */
132     /* GFA */
133     /* ======================================================================== */
134    
135     /* Free resources used by filter */
136     static void pf_capture_free(netio_desc_t *nio,void **opt)
137     {
138     struct netio_filter_capture *c = *opt;
139    
140     if (c != NULL) {
141     printf("NIO %s: ending packet capture.\n",nio->name);
142    
143     /* Close dumper */
144     if (c->dumper)
145     pcap_dump_close(c->dumper);
146    
147     /* Close PCAP descriptor */
148     if (c->desc)
149     pcap_close(c->desc);
150    
151     free(c);
152     *opt = NULL;
153     }
154     }
155    
156     /* Setup filter resources */
157     static int pf_capture_setup(netio_desc_t *nio,void **opt,
158     int argc,char *argv[])
159     {
160     struct netio_filter_capture *c;
161     int link_type;
162    
163     /* We must have a link type and a filename */
164     if (argc != 2)
165     return(-1);
166    
167     /* Free resources if something has already been done */
168     pf_capture_free(nio,opt);
169    
170     /* Allocate structure to hold PCAP info */
171     if (!(c = malloc(sizeof(*c))))
172     return(-1);
173    
174     if ((link_type = pcap_datalink_name_to_val(argv[0])) == -1) {
175     fprintf(stderr,"NIO %s: unknown link type %s, assuming Ethernet.\n",
176     nio->name,argv[0]);
177     link_type = DLT_EN10MB;
178     }
179    
180     /* Open a dead pcap descriptor */
181     if (!(c->desc = pcap_open_dead(link_type,8192))) {
182     fprintf(stderr,"NIO %s: pcap_open_dead failure\n",nio->name);
183     goto pcap_open_err;
184     }
185    
186     /* Open the output file */
187     if (!(c->dumper = pcap_dump_open(c->desc,argv[1]))) {
188     fprintf(stderr,"NIO %s: pcap_dump_open failure (file %s)\n",
189     nio->name,argv[0]);
190     goto pcap_dump_err;
191     }
192    
193     printf("NIO %s: capturing to file '%s'\n",nio->name,argv[1]);
194     *opt = c;
195     return(0);
196    
197     pcap_dump_err:
198     pcap_close(c->desc);
199     pcap_open_err:
200     free(c);
201     return(-1);
202     }
203    
204     /* Packet handler: write packets to a file in CAP format */
205     static int pf_capture_pkt_handler(netio_desc_t *nio,void *pkt,size_t len,
206     void *opt)
207     {
208     struct netio_filter_capture *c = opt;
209     struct pcap_pkthdr pkt_hdr;
210    
211     if (c != NULL) {
212     gettimeofday(&pkt_hdr.ts,0);
213     pkt_hdr.caplen = len;
214     pkt_hdr.len = len;
215    
216     pcap_dump((u_char *)c->dumper,&pkt_hdr,pkt);
217     pcap_dump_flush(c->dumper);
218     }
219    
220     return(NETIO_FILTER_ACTION_PASS);
221     }
222    
223     /* Packet capture */
224     static netio_pktfilter_t pf_capture_def = {
225     "capture",
226     pf_capture_setup,
227     pf_capture_free,
228     pf_capture_pkt_handler,
229     NULL,
230     };
231    
232     /* ======================================================================== */
233 dpavlin 1 /* Frequency Dropping ("freq_drop"). */
234     /* ======================================================================== */
235    
236     struct pf_freqdrop_data {
237     int frequency;
238     int current;
239     };
240    
241     /* Setup filter ressources */
242     static int pf_freqdrop_setup(netio_desc_t *nio,void **opt,
243     int argc,char *argv[])
244     {
245     struct pf_freqdrop_data *data = *opt;
246    
247     if (argc != 1)
248     return(-1);
249    
250     if (!data) {
251     if (!(data = malloc(sizeof(*data))))
252     return(-1);
253    
254     *opt = data;
255     }
256    
257     data->current = 0;
258     data->frequency = atoi(argv[0]);
259     return(0);
260     }
261    
262     /* Free ressources used by filter */
263     static void pf_freqdrop_free(netio_desc_t *nio,void **opt)
264     {
265     if (*opt)
266     free(*opt);
267    
268     *opt = NULL;
269     }
270    
271     /* Packet handler: drop 1 out of n packets */
272     static int pf_freqdrop_pkt_handler(netio_desc_t *nio,void *pkt,size_t len,
273     void *opt)
274     {
275     struct pf_freqdrop_data *data = opt;
276    
277     if (data != NULL) {
278     switch(data->frequency) {
279     case -1:
280     return(NETIO_FILTER_ACTION_DROP);
281     case 0:
282     return(NETIO_FILTER_ACTION_PASS);
283     default:
284     data->current++;
285    
286     if (data->current == data->frequency) {
287     data->current = 0;
288     return(NETIO_FILTER_ACTION_DROP);
289     }
290     }
291     }
292    
293     return(NETIO_FILTER_ACTION_PASS);
294     }
295    
296     /* Packet dropping at 1/n frequency */
297     static netio_pktfilter_t pf_freqdrop_def = {
298     "freq_drop",
299     pf_freqdrop_setup,
300     pf_freqdrop_free,
301     pf_freqdrop_pkt_handler,
302     NULL,
303     };
304    
305     /* ======================================================================== */
306     /* Initialization of packet filters. */
307     /* ======================================================================== */
308    
309     void netio_filter_load_all(void)
310     {
311     netio_filter_add(&pf_freqdrop_def);
312 dpavlin 7 netio_filter_add(&pf_capture_def);
313 dpavlin 1 }

  ViewVC Help
Powered by ViewVC 1.1.26