source: lib/format_pcap.c @ 72bfe20

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

trace_event fixed

  • Property mode set to 100644
File size: 9.3 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 "format_helper.h"
36#include <inttypes.h>
37#include <sys/types.h>
38#include <sys/stat.h>
39#include <unistd.h>
40#include <assert.h>
41
42
43#if HAVE_PCAP_BPF_H
44#  include <pcap-bpf.h>
45#else
46#  ifdef HAVE_NET_BPF_H
47#    include <net/bpf.h>
48#  endif
49#endif
50
51#if HAVE_PCAP_H
52#  include <pcap.h>
53#  ifdef HAVE_PCAP_INT_H
54#    include <pcap-int.h>
55#  endif
56#endif
57
58#if HAVE_PCAP
59
60#define CONNINFO libtrace->format_data->conn_info
61#define INPUT libtrace->format_data->input
62
63struct libtrace_format_data_t {
64        union {
65                char *path;             /**< information for local sockets */
66                char *interface;        /**< intormation for reading of network
67                                             interfaces */
68        } conn_info;
69        /** Information about the current state of the input device */
70        union {
71                int fd;
72                FILE *file;
73                pcap_t *pcap;
74        } input;
75};
76
77static int pcap_init_input(struct libtrace_t *libtrace) {
78        char errbuf[PCAP_ERRBUF_SIZE];
79        struct stat buf;
80        libtrace->format_data = (struct libtrace_format_data_t *) 
81                malloc(sizeof(struct libtrace_format_data_t));
82        CONNINFO.path = libtrace->uridata;
83
84        libtrace->sourcetype = TRACE;
85        if (!strncmp(CONNINFO.path,"-",1)) {
86                if ((INPUT.pcap = 
87                        pcap_open_offline(CONNINFO.path,
88                                                errbuf)) == NULL) {
89                        fprintf(stderr,"%s\n",errbuf);
90                        return 0;
91                }               
92        } else {
93                if (stat(CONNINFO.path,&buf) == -1) {
94                        perror("stat");
95                        return 0;
96                }
97                if (S_ISCHR(buf.st_mode)) {
98                        if ((INPUT.pcap = 
99                                pcap_open_live(CONNINFO.path,
100                                        4096,
101                                        1,
102                                        1,
103                                        errbuf)) == NULL) {
104                                fprintf(stderr,"%s\n",errbuf);
105                                return 0;
106                        }
107                } else { 
108                        if ((INPUT.pcap = 
109                                pcap_open_offline(CONNINFO.path,
110                                        errbuf)) == NULL) {
111                                fprintf(stderr,"%s\n",errbuf);
112                                return 0;
113                        }
114                }       
115        }
116        fprintf(stderr,
117                        "Unsupported scheme (%s) for format pcap\n",
118                        CONNINFO.path);
119        return 0;
120       
121}
122
123static int pcapint_init_input(struct libtrace_t *libtrace) {
124        char errbuf[PCAP_ERRBUF_SIZE];
125        libtrace->format_data = (struct libtrace_format_data_t *) 
126                malloc(sizeof(struct libtrace_format_data_t));
127        CONNINFO.path = libtrace->uridata;
128        libtrace->sourcetype = INTERFACE;
129        if ((INPUT.pcap = 
130                        pcap_open_live(CONNINFO.path,
131                        4096,
132                        1,
133                        1,
134                        errbuf)) == NULL) {
135                fprintf(stderr,"%s\n",errbuf);
136                return 0;
137        }
138
139}
140
141static int pcap_fin_input(struct libtrace_t *libtrace) {
142        return -1;
143}
144
145static void trace_pcap_handler(u_char *user, const struct pcap_pkthdr *pcaphdr, const u_char *pcappkt) {
146        struct libtrace_packet_t *packet = (struct libtrace_packet_t *)user;   
147        void *buffer = packet->buffer;
148        int numbytes = 0;
149       
150        memcpy(buffer,pcaphdr,sizeof(struct pcap_pkthdr));
151        numbytes = pcaphdr->len;
152        memcpy(buffer + sizeof(struct pcap_pkthdr),pcappkt,numbytes);
153
154        packet->size = numbytes + sizeof(struct pcap_pkthdr);
155
156}
157static int pcap_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
158        const u_char *pcappkt;
159        int pcapbytes = 0;
160
161        while ((pcapbytes = pcap_dispatch(INPUT.pcap,
162                                        1, /* number of packets */
163                                        &trace_pcap_handler,
164                                        (u_char *)packet)) == 0);
165
166        if (pcapbytes < 0) {
167                return -1;
168        }
169        return (packet->size - sizeof(struct pcap_pkthdr));
170}
171
172static void *pcap_get_link(const struct libtrace_packet_t *packet) {
173        return (void *) (packet->buffer + sizeof(struct pcap_pkthdr));
174}
175
176static libtrace_linktype_t pcap_get_link_type(const struct libtrace_packet_t *packet) {
177        struct pcap_pkthdr *pcapptr = 0;
178        int linktype = 0;
179        pcapptr = (struct pcap_pkthdr *)packet->buffer;
180        linktype = pcap_datalink(packet->trace->format_data->input.pcap);
181        switch(linktype) {
182                case DLT_NULL:
183                        return TRACE_TYPE_NONE;
184                case DLT_EN10MB:
185                        return TRACE_TYPE_ETH;
186                case DLT_ATM_RFC1483:
187                        return TRACE_TYPE_ATM;
188                case DLT_IEEE802_11:
189                        return TRACE_TYPE_80211;
190#ifdef DLT_LINUX_SLL
191                case DLT_LINUX_SLL:
192                        return TRACE_TYPE_LINUX_SLL;
193#endif
194#ifdef DLT_PFLOG
195                case DLT_PFLOG:
196                        return TRACE_TYPE_PFLOG;
197#endif
198        }
199        return -1;
200}
201
202static int8_t pcap_get_direction(const struct libtrace_packet_t *packet) {
203        int8_t direction  = -1;
204        switch(pcap_get_link_type(packet)) {
205                case TRACE_TYPE_LINUX_SLL:
206                {
207                        struct trace_sll_header_t *sll;
208                        sll = trace_get_link(packet);
209                        if (!sll) {
210                                return -1;
211                        }
212                        /* 0 == LINUX_SLL_HOST */
213                        /* the Waikato Capture point defines "packets
214                         * originating locally" (ie, outbound), with a
215                         * direction of 0, and "packets destined locally"
216                         * (ie, inbound), with a direction of 1.
217                         * This is kind-of-opposite to LINUX_SLL.
218                         * We return consistent values here, however
219                         *
220                         * Note that in recent versions of pcap, you can
221                         * use "inbound" and "outbound" on ppp in linux
222                         */
223                        if (ntohs(sll->pkttype == 0)) {
224                                direction = 1;
225                        } else {
226                                direction = 0;
227                        }
228                        break;
229
230                }
231                case TRACE_TYPE_PFLOG:
232                {
233                        struct trace_pflog_header_t *pflog;
234                        pflog = trace_get_link(packet);
235                        if (!pflog) {
236                                return -1;
237                        }
238                        /* enum    { PF_IN=0, PF_OUT=1 }; */
239                        if (ntohs(pflog->dir==0)) {
240
241                                direction = 1;
242                        }
243                        else {
244                                direction = 0;
245                        }
246                        break;
247                }
248                default:
249                        break;
250        }       
251        return direction;
252}
253
254
255static struct timeval pcap_get_timeval(const struct libtrace_packet_t *packet) { 
256        struct pcap_pkthdr *pcapptr = (struct pcap_pkthdr *)packet->buffer;
257        return pcapptr->ts;
258}
259
260
261static int pcap_get_capture_length(const struct libtrace_packet_t *packet) {
262        struct pcap_pkthdr *pcapptr = 0;
263        pcapptr = (struct pcap_pkthdr *)packet->buffer;
264        return pcapptr->caplen;
265}
266
267static int pcap_get_wire_length(const struct libtrace_packet_t *packet) {
268        struct pcap_pkthdr *pcapptr = 0;
269        pcapptr = (struct pcap_pkthdr *)packet->buffer;
270        return ntohs(pcapptr->len);
271}
272
273static size_t pcap_set_capture_length(struct libtrace_packet_t *packet,size_t size) {
274        struct pcap_pkthdr *pcapptr = 0;
275        assert(packet);
276        if (size > packet->size) {
277                // can't make a packet larger
278                return packet->size;
279        }
280        pcapptr = (struct pcap_pkthdr *)packet->buffer;
281        pcapptr->caplen = size + sizeof(struct pcap_pkthdr);
282        packet->size = pcapptr->caplen;
283        return packet->size;
284}
285
286static int pcap_get_fd(struct libtrace_packet_t *packet) {
287        return pcap_fileno(packet->trace->format_data->input.pcap);
288}
289
290static void pcap_help() {
291        printf("pcap format module: $Revision$\n");
292        printf("Supported input URIs:\n");
293        printf("\tpcap:/path/to/file\n");
294        printf("\n");
295        printf("\te.g.: pcap:/tmp/trace.pcap\n");
296        printf("\n");
297        printf("Supported output URIs:\n");
298        printf("\tnone\n");
299        printf("\n");
300}
301
302static void pcapint_help() {
303        printf("pcapint format module: $Revision$\n");
304        printf("Supported input URIs:\n");
305        printf("\tpcapint:interface\n");
306        printf("\n");
307        printf("\te.g.: pcapint:eth0\n");
308        printf("\n");
309        printf("Supported output URIs:\n");
310        printf("\tnone\n");
311        printf("\n");
312}
313
314
315static struct libtrace_format_t pcap = {
316        "pcap",
317        "$Id$",
318        pcap_init_input,                /* init_input */
319        NULL,                           /* init_output */
320        NULL,                           /* config_output */
321        pcap_fin_input,                 /* fin_input */
322        NULL,                           /* fin_output */
323        pcap_read_packet,               /* read_packet */
324        NULL,                           /* write_packet */
325        pcap_get_link,                  /* get_link */
326        pcap_get_link_type,             /* get_link_type */
327        pcap_get_direction,             /* get_direction */
328        NULL,                           /* set_direction */
329        NULL,                           /* get_erf_timestamp */
330        pcap_get_timeval,               /* get_timeval */
331        NULL,                           /* get_seconds */
332        pcap_get_capture_length,        /* get_capture_length */
333        pcap_get_wire_length,           /* get_wire_length */
334        pcap_set_capture_length,        /* set_capture_length */
335        NULL,                           /* get_fd */
336        trace_event_trace,              /* trace_event */
337        pcap_help                       /* help */
338};
339
340static struct libtrace_format_t pcapint = {
341        "pcapint",
342        "$Id$",
343        pcapint_init_input,             /* init_input */
344        NULL,                           /* init_output */
345        NULL,                           /* config_output */
346        pcap_fin_input,                 /* fin_input */
347        NULL,                           /* fin_output */
348        pcap_read_packet,               /* read_packet */
349        NULL,                           /* write_packet */
350        pcap_get_link,                  /* get_link */
351        pcap_get_link_type,             /* get_link_type */
352        pcap_get_direction,             /* get_direction */
353        NULL,                           /* set_direction */
354        NULL,                           /* get_erf_timestamp */
355        pcap_get_timeval,               /* get_timeval */
356        NULL,                           /* get_seconds */
357        pcap_get_capture_length,        /* get_capture_length */
358        pcap_get_wire_length,           /* get_wire_length */
359        pcap_set_capture_length,        /* set_capture_length */
360        pcap_get_fd,                    /* get_fd */
361        trace_event_device,             /* trace_event */
362        pcapint_help                    /* help */
363};
364
365void __attribute__((constructor)) pcap_constructor() {
366        register_format(&pcap);
367        register_format(&pcapint);
368}
369
370
371#endif
Note: See TracBrowser for help on using the repository browser.