source: lib/format_pcapfile.c @ c0cd256

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

Remove old CONSTRUCTOR initialisation code, and only rely on the newer
trace_init() function.

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