source: lib/format_pcap.c @ 9e2a109

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 9e2a109 was 9e2a109, checked in by Daniel Lawson <dlawson@…>, 15 years ago

moved format.h to libtrace_int.h

pulled out all the format-specific libtrace_t stuff into an opaque pointer which is defined inside each format_*.o file, for both input and output

This seems to work, it compiles at least, and wag and erf both work

rtclient input is currently broken, I suspect it's not stepping over the status properly

  • Property mode set to 100644
File size: 9.1 KB
Line 
1/*
2 * This file is part of libtrace
3 *
4 * Copyright (c) 2004 The University of Waikato, Hamilton, New Zealand.
5 * Authors: Daniel Lawson
6 *          Perry Lorier
7 *         
8 * All rights reserved.
9 *
10 * This code has been developed by the University of Waikato WAND
11 * research group. For further information please see http://www.wand.net.nz/
12 *
13 * libtrace is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2 of the License, or
16 * (at your option) any later version.
17 *
18 * libtrace is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with libtrace; if not, write to the Free Software
25 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 *
27 * $Id$
28 *
29 */
30
31#include "common.h"
32#include "config.h"
33#include "libtrace.h"
34#include "libtrace_int.h"
35#include <inttypes.h>
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <unistd.h>
39#include <assert.h>
40
41
42#if HAVE_PCAP_BPF_H
43#  include <pcap-bpf.h>
44#else
45#  ifdef HAVE_NET_BPF_H
46#    include <net/bpf.h>
47#  endif
48#endif
49
50#if HAVE_PCAP_H
51#  include <pcap.h>
52#  ifdef HAVE_PCAP_INT_H
53#    include <pcap-int.h>
54#  endif
55#endif
56
57#if HAVE_PCAP
58
59struct libtrace_format_data_t {
60        union {
61                char *path;             /**< information for local sockets */
62                char *interface;        /**< intormation for reading of network
63                                             interfaces */
64        } conn_info;
65        /** Information about the current state of the input device */
66        union {
67                int fd;
68                FILE *file;
69                pcap_t *pcap;
70        } input;
71};
72
73static int pcap_init_input(struct libtrace_t *libtrace) {
74        char errbuf[PCAP_ERRBUF_SIZE];
75        struct stat buf;
76        libtrace->format_data = (struct libtrace_format_data_t *) 
77                malloc(sizeof(struct libtrace_format_data_t));
78        libtrace->format_data->conn_info.path = libtrace->uridata;
79        if (!strncmp(libtrace->format_data->conn_info.path,"-",1)) {
80                if ((libtrace->format_data->input.pcap = 
81                        pcap_open_offline(libtrace->format_data->conn_info.path,
82                                                errbuf)) == NULL) {
83                        fprintf(stderr,"%s\n",errbuf);
84                        return 0;
85                }               
86        } else {
87                if (stat(libtrace->format_data->conn_info.path,&buf) == -1) {
88                        perror("stat");
89                        return 0;
90                }
91                if (S_ISCHR(buf.st_mode)) {
92                        if ((libtrace->format_data->input.pcap = 
93                                pcap_open_live(libtrace->format_data->conn_info.path,
94                                        4096,
95                                        1,
96                                        1,
97                                        errbuf)) == NULL) {
98                                fprintf(stderr,"%s\n",errbuf);
99                                return 0;
100                        }
101                } else { 
102                        if ((libtrace->format_data->input.pcap = 
103                                pcap_open_offline(libtrace->format_data->conn_info.path,
104                                        errbuf)) == NULL) {
105                                fprintf(stderr,"%s\n",errbuf);
106                                return 0;
107                        }
108                }       
109        }
110        fprintf(stderr,
111                        "Unsupported scheme (%s) for format pcap\n",
112                        libtrace->format_data->conn_info.path);
113        return 0;
114       
115}
116
117static int pcapint_init_input(struct libtrace_t *libtrace) {
118        char errbuf[PCAP_ERRBUF_SIZE];
119        if ((libtrace->format_data->input.pcap = 
120                        pcap_open_live(libtrace->format_data->conn_info.path,
121                        4096,
122                        1,
123                        1,
124                        errbuf)) == NULL) {
125                fprintf(stderr,"%s\n",errbuf);
126                return 0;
127        }
128
129}
130
131static int pcap_fin_input(struct libtrace_t *libtrace) {
132        return -1;
133}
134
135static void trace_pcap_handler(u_char *user, const struct pcap_pkthdr *pcaphdr, const u_char *pcappkt) {
136        struct libtrace_packet_t *packet = (struct libtrace_packet_t *)user;   
137        void *buffer = packet->buffer;
138        int numbytes = 0;
139       
140        memcpy(buffer,pcaphdr,sizeof(struct pcap_pkthdr));
141        numbytes = pcaphdr->len;
142        memcpy(buffer + sizeof(struct pcap_pkthdr),pcappkt,numbytes);
143
144        packet->size = numbytes + sizeof(struct pcap_pkthdr);
145
146}
147static int pcap_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
148        const u_char *pcappkt;
149        int pcapbytes = 0;
150
151        while ((pcapbytes = pcap_dispatch(libtrace->format_data->input.pcap,
152                                        1, /* number of packets */
153                                        &trace_pcap_handler,
154                                        (u_char *)packet)) == 0);
155
156        if (pcapbytes < 0) {
157                return -1;
158        }
159        return (packet->size - sizeof(struct pcap_pkthdr));
160}
161
162static void *pcap_get_link(const struct libtrace_packet_t *packet) {
163        return (void *) (packet->buffer + sizeof(struct pcap_pkthdr));
164}
165
166static libtrace_linktype_t pcap_get_link_type(const struct libtrace_packet_t *packet) {
167        struct pcap_pkthdr *pcapptr = 0;
168        int linktype = 0;
169        pcapptr = (struct pcap_pkthdr *)packet->buffer;
170        linktype = pcap_datalink(packet->trace->format_data->input.pcap);
171        switch(linktype) {
172                case DLT_NULL:
173                        return TRACE_TYPE_NONE;
174                case DLT_EN10MB:
175                        return TRACE_TYPE_ETH;
176                case DLT_ATM_RFC1483:
177                        return TRACE_TYPE_ATM;
178                case DLT_IEEE802_11:
179                        return TRACE_TYPE_80211;
180#ifdef DLT_LINUX_SLL
181                case DLT_LINUX_SLL:
182                        return TRACE_TYPE_LINUX_SLL;
183#endif
184#ifdef DLT_PFLOG
185                case DLT_PFLOG:
186                        return TRACE_TYPE_PFLOG;
187#endif
188        }
189        return -1;
190}
191
192static int8_t pcap_get_direction(const struct libtrace_packet_t *packet) {
193        int8_t direction  = -1;
194        switch(pcap_get_link_type(packet)) {
195                case TRACE_TYPE_LINUX_SLL:
196                {
197                        struct trace_sll_header_t *sll;
198                        sll = trace_get_link(packet);
199                        if (!sll) {
200                                return -1;
201                        }
202                        /* 0 == LINUX_SLL_HOST */
203                        /* the Waikato Capture point defines "packets
204                         * originating locally" (ie, outbound), with a
205                         * direction of 0, and "packets destined locally"
206                         * (ie, inbound), with a direction of 1.
207                         * This is kind-of-opposite to LINUX_SLL.
208                         * We return consistent values here, however
209                         *
210                         * Note that in recent versions of pcap, you can
211                         * use "inbound" and "outbound" on ppp in linux
212                         */
213                        if (ntohs(sll->pkttype == 0)) {
214                                direction = 1;
215                        } else {
216                                direction = 0;
217                        }
218                        break;
219
220                }
221                case TRACE_TYPE_PFLOG:
222                {
223                        struct trace_pflog_header_t *pflog;
224                        pflog = trace_get_link(packet);
225                        if (!pflog) {
226                                return -1;
227                        }
228                        /* enum    { PF_IN=0, PF_OUT=1 }; */
229                        if (ntohs(pflog->dir==0)) {
230
231                                direction = 1;
232                        }
233                        else {
234                                direction = 0;
235                        }
236                        break;
237                }
238                default:
239                        break;
240        }       
241        return direction;
242}
243
244
245static struct timeval pcap_get_timeval(const struct libtrace_packet_t *packet) { 
246        struct pcap_pkthdr *pcapptr = (struct pcap_pkthdr *)packet->buffer;
247        return pcapptr->ts;
248}
249
250
251static int pcap_get_capture_length(const struct libtrace_packet_t *packet) {
252        struct pcap_pkthdr *pcapptr = 0;
253        pcapptr = (struct pcap_pkthdr *)packet->buffer;
254        return pcapptr->caplen;
255}
256
257static int pcap_get_wire_length(const struct libtrace_packet_t *packet) {
258        struct pcap_pkthdr *pcapptr = 0;
259        pcapptr = (struct pcap_pkthdr *)packet->buffer;
260        return ntohs(pcapptr->len);
261}
262
263static size_t pcap_set_capture_length(struct libtrace_packet_t *packet,size_t size) {
264        struct pcap_pkthdr *pcapptr = 0;
265        assert(packet);
266        if (size > packet->size) {
267                // can't make a packet larger
268                return packet->size;
269        }
270        pcapptr = (struct pcap_pkthdr *)packet->buffer;
271        pcapptr->caplen = size + sizeof(struct pcap_pkthdr);
272        packet->size = pcapptr->caplen;
273        return packet->size;
274}
275
276static void pcap_help() {
277        printf("pcap format module: $Revision$\n");
278        printf("Supported input URIs:\n");
279        printf("\tpcap:/path/to/file\n");
280        printf("\n");
281        printf("\te.g.: pcap:/tmp/trace.pcap\n");
282        printf("\n");
283        printf("Supported output URIs:\n");
284        printf("\tnone\n");
285        printf("\n");
286}
287
288static void pcapint_help() {
289        printf("pcapint format module: $Revision$\n");
290        printf("Supported input URIs:\n");
291        printf("\tpcapint:interface\n");
292        printf("\n");
293        printf("\te.g.: pcapint:eth0\n");
294        printf("\n");
295        printf("Supported output URIs:\n");
296        printf("\tnone\n");
297        printf("\n");
298}
299
300
301static struct libtrace_format_t pcap = {
302        "pcap",
303        "$Id$",
304        pcap_init_input,                /* init_input */
305        NULL,                           /* init_output */
306        NULL,                           /* config_output */
307        pcap_fin_input,                 /* fin_input */
308        NULL,                           /* fin_output */
309        NULL,                           /* read */
310        pcap_read_packet,               /* read_packet */
311        NULL,                           /* write_packet */
312        pcap_get_link,                  /* get_link */
313        pcap_get_link_type,             /* get_link_type */
314        pcap_get_direction,             /* get_direction */
315        NULL,                           /* set_direction */
316        NULL,                           /* get_erf_timestamp */
317        pcap_get_timeval,               /* get_timeval */
318        NULL,                           /* get_seconds */
319        pcap_get_capture_length,        /* get_capture_length */
320        pcap_get_wire_length,           /* get_wire_length */
321        pcap_set_capture_length,        /* set_capture_length */
322        pcap_help                       /* help */
323};
324
325static struct libtrace_format_t pcapint = {
326        "pcapint",
327        "$Id$",
328        pcapint_init_input,             /* init_input */
329        NULL,                           /* init_output */
330        NULL,                           /* config_output */
331        pcap_fin_input,                 /* fin_input */
332        NULL,                           /* fin_output */
333        NULL,                           /* read */
334        pcap_read_packet,               /* read_packet */
335        NULL,                           /* write_packet */
336        pcap_get_link,                  /* get_link */
337        pcap_get_link_type,             /* get_link_type */
338        pcap_get_direction,             /* get_direction */
339        NULL,                           /* set_direction */
340        NULL,                           /* get_erf_timestamp */
341        pcap_get_timeval,               /* get_timeval */
342        NULL,                           /* get_seconds */
343        pcap_get_capture_length,        /* get_capture_length */
344        pcap_get_wire_length,           /* get_wire_length */
345        pcap_set_capture_length,        /* set_capture_length */
346        pcapint_help                    /* help */
347};
348
349void __attribute__((constructor)) pcap_constructor() {
350        register_format(&pcap);
351        register_format(&pcapint);
352}
353
354
355#endif
Note: See TracBrowser for help on using the repository browser.