source: examples/pcap2erf/pcap2erf.c @ afd0b73

4.0.1-hotfixescachetimestampsdevelopdpdk-ndagetsilivegetfragoffhelplibtrace4ndag_formatpfringrc-4.0.1rc-4.0.2rc-4.0.3rc-4.0.4ringdecrementfixringperformanceringtimestampfixes
Last change on this file since afd0b73 was d56089a, checked in by Shane Alcock <salcock@…>, 16 years ago

Updated examples and tools to use new function names

  • Property mode set to 100644
File size: 6.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 <stdio.h>
32#include <stdlib.h>
33#include <assert.h>
34#include <string.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <fcntl.h>
38#include <pcap.h>
39#include <netinet/in.h>
40#include <netinet/ip.h>
41#include <netinet/tcp.h>
42#include <netinet/udp.h>
43#include <arpa/inet.h>
44#include <sys/socket.h>
45#include <unistd.h>
46#include <linux/if_ether.h>
47
48//extern "C" {
49#include "dagformat.h"
50#include "libtrace.h"
51//}
52
53struct libtrace_t *trace;
54int                _fcs_bits = 32;
55#define SCANSIZE 4096
56char buffer[SCANSIZE];
57
58struct network_id {
59    uint32_t network;
60    uint32_t netmask;
61    struct network_id *next;
62} *head = NULL;
63
64
65/* one big glorious function */
66int main(int argc, char *argv[]) {
67
68    char *uri;
69    int psize = 0;
70    char *filename;
71    FILE* input;
72   
73    struct pcap_pkthdr *header;
74    struct libtrace_packet_t *packet = trace_create_packet();
75    unsigned long seconds, subseconds;
76    unsigned short rlen, lctr, wlen, offset, pad;
77    unsigned char type, flags;
78    struct network_id* locals;
79    uint32_t address = 0;
80    uint32_t netmask = 0;
81    int data_size;
82    struct libtrace_tcp *tcpptr = 0;
83    int octets[4];
84    int hlen;
85    struct libtrace_ip *ipptr;
86
87   
88    // 2 parameters only, both neccessary
89    if (argc == 3) {
90        uri = strdup(argv[1]);
91        filename = strdup(argv[2]);
92    }
93    else
94    {
95        // this message isnt very good
96        fprintf(stderr, 
97                "Usage: %s <source> <local_list>\n"
98                "\n"
99                "  <source> is a libtrace pcap uri, eg:\n"
100                "       pcapint:eth0\n"
101                "       pcap:/path/to/trace.pcap\n"
102                "  <local_list> is the name of a file which contains pairs of networks\n"
103                "  and netmasks for internal networks, one per line\n"
104                "  eg:\n"
105                "       192.168.0.0 255.255.255.0\n"
106                "       192.168.1.0 255.255.255.0\n",
107                argv[0]);
108        exit(1);
109    }
110    //---------------------------------------------------------------------
111
112    // open list of internal networks
113    if( (input = fopen(filename, "r")) == NULL )
114                return -1;
115
116    // read the network/mask pairs in
117    while(1)
118    {
119        int num = fscanf(input,"%d.%d.%d.%d"
120                ,&octets[0],&octets[1],&octets[2],&octets[3]);
121
122        // might as well do some error checking, give a message
123        if(num != 4)
124            if(num < 1)
125                break;
126            else
127            {
128                fprintf(stderr, "Error reading network in networks file\n");
129                exit(1);
130            }
131       
132        // pack the bytes into a single number
133        for(int i=0; i<4; i++)
134        {
135            address = address << 8;
136            address = address | octets[i];
137        }
138
139        if( (fscanf(input,"%d.%d.%d.%d"
140                        ,&octets[0],&octets[1],&octets[2],&octets[3])) != 4)
141        {
142            fprintf(stderr, "Error reading netmask in networks file\n");
143            exit(1);
144        }
145        for(int i=0; i<4; i++)
146        {
147            netmask = netmask << 8;
148            netmask = netmask | octets[i];
149        }
150
151        // tack this new address onto the front of the list
152        network_id *newId = new network_id;
153        newId->network = address;
154        newId->netmask = netmask;
155        newId->next = head;
156        head = newId;
157    }
158    fclose(input);
159    //----------------------------------------------------------------------
160
161    // create an trace to the given uri
162    trace = trace_create(uri);
163
164    for (;;) {
165        if ((psize = trace_read_packet(trace, &packet)) 
166                == -1) {
167            // terminate
168            break;
169        }
170        // buffer returned is pcap-->ethernet-->upperlayers
171        header = (struct pcap_pkthdr*)packet.buffer;
172
173        // if this isnt an ip packet, ignore it
174        if(! ((packet.buffer + sizeof(struct pcap_pkthdr))[12] == 8 &&
175            (packet.buffer + sizeof(struct pcap_pkthdr))[13] == 0))
176            continue;
177       
178
179        ipptr = trace_get_ip(&packet);
180        hlen = ipptr->ip_hl*4;
181
182        // work out how much packet we need...ethernet + ip + whatever
183        switch(ipptr->ip_p)
184        {
185            case 1: data_size = 14 + hlen; break;
186            case 6: tcpptr = (struct libtrace_tcp *) ((uint8_t *)ipptr + hlen);
187                    data_size = 14 + hlen + (tcpptr->doff*4); break;
188            case 17: data_size = 14 + hlen + 8; break;
189            default: data_size = 14 + (ipptr->ip_hl*4); break;
190        };
191
192        // start making the erf header
193        subseconds = (unsigned long)header->ts.tv_usec;
194        seconds = (unsigned long)header->ts.tv_sec;
195        fwrite(&subseconds, 4, 1, stdout);
196        fwrite(&seconds, 4, 1, stdout);
197
198        // type is always ethernet afaic
199        type = 2;
200        fwrite(&type, 1, 1, stdout);
201
202        // set the direction based on the list of local addresses
203        locals = head;
204        while(locals != NULL)
205        {
206            if((locals->netmask&ntohl(ipptr->ip_src.s_addr)) == locals->network)
207            {
208                flags = 0;
209                break;
210            }
211            locals = locals->next;
212        }
213       
214        // address didnt match any in list, so its foreign
215        if(locals == NULL)
216            flags = 1;
217
218        // 8 = truncated record, 4 = varying record lengths...
219        //flags = flags + 12;//XXX
220
221        // flags is only being used for interface
222        fwrite(&flags, 1, 1, stdout);
223
224        // rlen = length of packet that we will keep + dag header
225        rlen = htons(data_size+18);
226        fwrite(&rlen, 2, 1, stdout);
227       
228        // loss counter can stay at zero
229        lctr = 0;
230        fwrite(&lctr, 2, 1, stdout);
231
232        // this is total length of packet that we saw I think
233        //wlen = htons(data_size);
234        wlen = htons(header->len);//XXX
235        fwrite(&wlen, 2, 1, stdout);
236
237        // never have an offset
238        offset = 0;
239        fwrite(&offset, 1, 1, stdout);
240
241        // no padding
242        pad = 0;
243        fwrite(&pad, 1, 1, stdout);
244        // 18 bytes of header so far
245
246        // write as much of the packet as we need (just the headers)
247        fwrite(packet.buffer + sizeof(pcap_pkthdr), 1, data_size, stdout);
248    }
249
250    trace_destroy(trace);
251    return 0;
252}
253
Note: See TracBrowser for help on using the repository browser.