source: lib/format_pcapfile.c @ 91db67b

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since 91db67b was 91db67b, checked in by Perry Lorier <perry@…>, 15 years ago

Clean up the various usages of TRACE_ERR_*, add TRACE_ERR_UNSUPPORTED and
shuffle which error was returned where. Document their new usages.

Closes: #13

Also, fix the 802.1q definitions.

  • Property mode set to 100644
File size: 9.2 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
37#include <sys/stat.h>
38#include <assert.h>
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <errno.h>
43
44#define DATA(x) ((struct pcapfile_format_data_t*)((x)->format_data))
45
46struct pcapfile_format_data_t {
47        libtrace_io_t *file;
48        struct pcapfile_header_t {
49                uint32_t magic_number;   /* magic number */
50                uint16_t version_major;  /* major version number */
51                uint16_t version_minor;  /* minor version number */
52                int32_t  thiszone;       /* GMT to local correction */
53                uint32_t sigfigs;        /* timestamp accuracy */
54                uint32_t snaplen;        /* aka "wirelen" */
55                uint32_t network;        /* data link type */
56        } header;
57};
58
59static int pcapfile_init_input(struct libtrace_t *libtrace) {
60        libtrace->format_data = malloc(sizeof(struct pcapfile_format_data_t));
61
62        DATA(libtrace)->file=NULL;
63
64        return 0;
65}
66
67static uint16_t swaps(libtrace_t *libtrace, uint16_t num)
68{
69        if (DATA(libtrace)->header.magic_number == 0xd4c3b2a1)
70                return ((num<<8)&0xFF00)|((num>>8)&0x00FF);
71        return num;
72}
73
74static uint32_t swapl(libtrace_t *libtrace, uint32_t num)
75{
76        if (DATA(libtrace)->header.magic_number == 0xd4c3b2a1)
77                return 
78                           ((num&0x000000FF)<<24)
79                        || ((num&0x0000FF00)<<8)
80                        || ((num&0x00FF0000)>>8)
81                        || ((num&0xFF000000)>>24);
82        return num;
83}
84
85
86static int pcapfile_start_input(libtrace_t *libtrace) 
87{
88        int err;
89
90        if (!DATA(libtrace)->file) {
91                DATA(libtrace)->file=trace_open_file(libtrace);
92
93                if (!DATA(libtrace)->file)
94                        return -1;
95
96                err=libtrace_io_read(DATA(libtrace)->file,
97                                &DATA(libtrace)->header,
98                                sizeof(DATA(libtrace)->header));
99
100                if (err<1)
101                        return -1;
102               
103                if (swapl(libtrace,DATA(libtrace)->header.magic_number) != 0xa1b2c3d4) {
104                        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"Not a pcap tracefile\n");
105                        return -1; /* Not a pcap file */
106                }
107
108                if (swaps(libtrace,DATA(libtrace)->header.version_major)!=2
109                        && swaps(libtrace,DATA(libtrace)->header.version_minor)!=4) {
110                        trace_set_err(libtrace,TRACE_ERR_INIT_FAILED,"Unknown pcap tracefile version %d.%d\n",
111                                        swaps(libtrace,
112                                                DATA(libtrace)->header.version_major),
113                                        swaps(libtrace,
114                                                DATA(libtrace)->header.version_minor));
115                        return -1;
116                }
117
118        }
119
120        return 0;
121}
122
123static int pcapfile_config_input(libtrace_t *libtrace,
124                trace_option_t option,
125                void *data)
126{
127        trace_set_err(libtrace,TRACE_ERR_UNKNOWN_OPTION,
128                        "Unknown option %i", option);
129        return -1;
130}
131
132static int pcapfile_fin_input(libtrace_t *libtrace) 
133{
134        libtrace_io_close(DATA(libtrace)->file);
135        free(libtrace->format_data);
136        return 0; /* success */
137}
138
139struct pcapfile_pkt_hdr_t {
140        uint32_t ts_sec;
141        uint32_t ts_usec;
142        uint32_t caplen;
143        uint32_t wirelen;
144};
145
146static int pcapfile_read_packet(struct libtrace_t *libtrace, struct libtrace_packet_t *packet) {
147        int err;
148
149        assert(libtrace->format_data);
150
151        packet->type = pcap_dlt_to_rt(swapl(libtrace,
152                                DATA(libtrace)->header.network));
153
154        if (!packet->buffer || packet->buf_control == TRACE_CTRL_EXTERNAL) {
155                packet->buffer = malloc(LIBTRACE_PACKET_BUFSIZE);
156                packet->buf_control = TRACE_CTRL_PACKET;
157        }
158
159        err=libtrace_io_read(DATA(libtrace)->file,
160                        packet->buffer,
161                        sizeof(struct pcapfile_pkt_hdr_t));
162
163        if (err<0) {
164                trace_set_err(libtrace,errno,"reading packet");
165                return -1;
166        }
167        if (err==0) {
168                /* EOF */
169                return 0;
170        }
171
172        packet->header = packet->buffer;
173
174
175        err=libtrace_io_read(DATA(libtrace)->file,
176                        (char*)packet->buffer+sizeof(struct pcapfile_pkt_hdr_t),
177                        swapl(libtrace,((struct pcapfile_pkt_hdr_t*)packet->buffer)->caplen)
178                        );
179
180       
181        if (err<0) {
182                trace_set_err(libtrace,errno,"reading packet");
183                return -1;
184        }
185        if (err==0) {
186                return 0;
187        }
188
189        packet->payload = (char*)packet->buffer
190                + sizeof(struct pcapfile_pkt_hdr_t);
191       
192        return sizeof(struct pcapfile_pkt_hdr_t)
193                +swapl(libtrace,((struct pcapfile_pkt_hdr_t*)packet->buffer)->caplen);
194}
195
196
197static libtrace_linktype_t pcapfile_get_link_type(
198                const libtrace_packet_t *packet) 
199{
200
201        return pcap_dlt_to_libtrace(
202                        swapl(packet->trace,
203                                DATA(packet->trace)->header.network
204                             )
205                        );
206}
207
208static int8_t pcapfile_get_direction(const libtrace_packet_t *packet) 
209{
210        int8_t direction  = -1;
211        switch(pcapfile_get_link_type(packet)) {
212                case TRACE_TYPE_LINUX_SLL:
213                {
214                        libtrace_sll_header_t *sll;
215                        sll = trace_get_link(packet);
216                        if (!sll) {
217                                trace_set_err(packet->trace,
218                                        TRACE_ERR_BAD_PACKET,
219                                                "Bad or missing packet");
220                                return -1;
221                        }
222                        /* 0 == LINUX_SLL_HOST */
223                        /* the Waikato Capture point defines "packets
224                         * originating locally" (ie, outbound), with a
225                         * direction of 0, and "packets destined locally"
226                         * (ie, inbound), with a direction of 1.
227                         * This is kind-of-opposite to LINUX_SLL.
228                         * We return consistent values here, however
229                         *
230                         * Note that in recent versions of pcap, you can
231                         * use "inbound" and "outbound" on ppp in linux
232                         */
233                        if (ntohs(sll->pkttype == 0)) {
234                                direction = 1;
235                        } else {
236                                direction = 0;
237                        }
238                        break;
239
240                }
241                case TRACE_TYPE_PFLOG:
242                {
243                        libtrace_pflog_header_t *pflog;
244                        pflog = trace_get_link(packet);
245                        if (!pflog) {
246                                trace_set_err(packet->trace,
247                                                TRACE_ERR_BAD_PACKET,
248                                                "Bad or missing packet");
249                                return -1;
250                        }
251                        /* enum    { PF_IN=0, PF_OUT=1 }; */
252                        if (ntohs(pflog->dir==0)) {
253
254                                direction = 1;
255                        }
256                        else {
257                                direction = 0;
258                        }
259                        break;
260                }
261                default:
262                        break;
263        }       
264        return direction;
265}
266
267
268static struct timeval pcapfile_get_timeval(
269                const struct libtrace_packet_t *packet) 
270{
271        struct pcapfile_pkt_hdr_t *hdr =
272                (struct pcapfile_pkt_hdr_t*)packet->header;
273        struct timeval ts;
274        ts.tv_sec = swapl(packet->trace,hdr->ts_sec);
275        ts.tv_usec = swapl(packet->trace,hdr->ts_usec);
276        return ts;
277}
278
279
280static int pcapfile_get_capture_length(const libtrace_packet_t *packet) {
281        struct pcapfile_pkt_hdr_t *pcapptr
282                = (struct pcapfile_pkt_hdr_t *)packet->header;
283
284        return swapl(packet->trace,pcapptr->caplen);
285}
286
287static int pcapfile_get_wire_length(const libtrace_packet_t *packet) {
288        struct pcapfile_pkt_hdr_t *pcapptr
289                = (struct pcapfile_pkt_hdr_t *)packet->header;
290        if (packet->type==pcap_dlt_to_rt(TRACE_DLT_EN10MB))
291                /* Include the missing FCS */
292                return swapl(packet->trace,pcapptr->wirelen)+4; 
293        else
294                return swapl(packet->trace,pcapptr->wirelen);
295}
296
297static int pcapfile_get_framing_length(const libtrace_packet_t *packet UNUSED) {
298        return sizeof(struct pcapfile_pkt_hdr_t);
299}
300
301static size_t pcapfile_set_capture_length(libtrace_packet_t *packet,size_t size) {
302        struct pcapfile_pkt_hdr_t *pcapptr = 0;
303        assert(packet);
304        if (size > trace_get_capture_length(packet)) {
305                /* can't make a packet larger */
306                return trace_get_capture_length(packet);
307        }
308        pcapptr = (struct pcapfile_pkt_hdr_t *)packet->header;
309        pcapptr->caplen = swapl(packet->trace,size);
310        return trace_get_capture_length(packet);
311}
312
313static void pcapfile_help() {
314        printf("pcapfile format module: $Revision$\n");
315        printf("Supported input URIs:\n");
316        printf("\tpcapfile:/path/to/file\n");
317        printf("\tpcapfile:/path/to/file.gz\n");
318        printf("\n");
319        printf("\te.g.: pcapfile:/tmp/trace.pcap\n");
320        printf("\n");
321}
322
323static struct libtrace_format_t pcapfile = {
324        "pcapfile",
325        "$Id$",
326        TRACE_FORMAT_PCAPFILE,
327        pcapfile_init_input,            /* init_input */
328        pcapfile_config_input,          /* config_input */
329        pcapfile_start_input,           /* start_input */
330        NULL,                           /* pause_input */
331        NULL,                   /* init_output */
332        NULL,                           /* config_output */
333        NULL,                           /* start_output */
334        pcapfile_fin_input,             /* fin_input */
335        NULL,                           /* fin_output */
336        pcapfile_read_packet,           /* read_packet */
337        NULL,                           /* fin_packet */
338        NULL,                           /* write_packet */
339        pcapfile_get_link_type,         /* get_link_type */
340        pcapfile_get_direction,         /* get_direction */
341        NULL,                           /* set_direction */
342        NULL,                           /* get_erf_timestamp */
343        pcapfile_get_timeval,           /* get_timeval */
344        NULL,                           /* get_seconds */
345        NULL,                           /* seek_erf */
346        NULL,                           /* seek_timeval */
347        NULL,                           /* seek_seconds */
348        pcapfile_get_capture_length,    /* get_capture_length */
349        pcapfile_get_wire_length,       /* get_wire_length */
350        pcapfile_get_framing_length,    /* get_framing_length */
351        pcapfile_set_capture_length,    /* set_capture_length */
352        NULL,                           /* get_fd */
353        trace_event_trace,              /* trace_event */
354        pcapfile_help,                  /* help */
355        NULL                            /* next pointer */
356};
357
358
359void CONSTRUCTOR pcapfile_constructor() {
360        register_format(&pcapfile);
361}
362
363
Note: See TracBrowser for help on using the repository browser.