source: examples/pcap2erf/pcap2erf.c @ 9729a8d

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

added license information

  • Property mode set to 100644
File size: 6.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 <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
48extern "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 *hostname;
69    int psize = 0;
70    int status = 0;
71    char *filename;
72    FILE* input;
73   
74    struct pcap_pkthdr *header;
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 tcphdr *tcpptr = 0;
83    int octets[4];
84    int hlen;
85    ip *ipptr;
86
87   
88    // 2 parameters only, both neccessary
89    if (argc == 3) {
90        hostname = 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 hostname, on the default port
162    trace = create_trace(hostname);
163
164    for (;;) {
165        if ((psize = libtrace_read_packet(trace, buffer,SCANSIZE, &status)) 
166                == -1) {
167            // terminate
168            break;
169        }
170        // buffer returned is pcap-->ethernet-->upperlayers
171        header = (struct pcap_pkthdr*) buffer;
172
173        // if this isnt an ip packet, ignore it
174        if(! ((buffer + sizeof(struct pcap_pkthdr))[12] == 8 &&
175            (buffer + sizeof(struct pcap_pkthdr))[13] == 0))
176            continue;
177       
178        ipptr = (ip *)(buffer + (sizeof(uint8_t)*30));// wtf is 30
179        hlen = ipptr->ip_hl*4;
180
181        // work out how much packet we need...ethernet + ip + whatever
182        switch(ipptr->ip_p)
183        {
184            case 1: data_size = 14 + hlen; break;
185            case 6: tcpptr = (struct tcphdr *) ((uint8_t *)ipptr + hlen);
186                    data_size = 14 + hlen + (tcpptr->doff*4); break;
187            case 17: data_size = 14 + hlen + 8; break;
188            default: data_size = 14 + (ipptr->ip_hl*4); break;
189        };
190
191        // start making the erf header
192        subseconds = (unsigned long)header->ts.tv_usec;
193        seconds = (unsigned long)header->ts.tv_sec;
194        fwrite(&subseconds, 4, 1, stdout);
195        fwrite(&seconds, 4, 1, stdout);
196
197        // type is always ethernet afaic
198        type = 2;
199        fwrite(&type, 1, 1, stdout);
200
201        // set the direction based on the list of local addresses
202        locals = head;
203        while(locals != NULL)
204        {
205            if((locals->netmask&ntohl(ipptr->ip_src.s_addr)) == locals->network)
206            {
207                flags = 0;
208                break;
209            }
210            locals = locals->next;
211        }
212       
213        // address didnt match any in list, so its foreign
214        if(locals == NULL)
215            flags = 1;
216
217        // 8 = truncated record, 4 = varying record lengths...
218        //flags = flags + 12;//XXX
219
220        // flags is only being used for interface
221        fwrite(&flags, 1, 1, stdout);
222
223        // rlen = length of packet that we will keep + dag header
224        rlen = htons(data_size+18);
225        fwrite(&rlen, 2, 1, stdout);
226       
227        // loss counter can stay at zero
228        lctr = 0;
229        fwrite(&lctr, 2, 1, stdout);
230
231        // this is total length of packet that we saw I think
232        //wlen = htons(data_size);
233        wlen = htons(header->len);//XXX
234        fwrite(&wlen, 2, 1, stdout);
235
236        // never have an offset
237        offset = 0;
238        fwrite(&offset, 1, 1, stdout);
239
240        // no padding
241        pad = 0;
242        fwrite(&pad, 1, 1, stdout);
243        // 18 bytes of header so far
244
245        // write as much of the packet as we need (just the headers)
246        fwrite(buffer + sizeof(pcap_pkthdr), 1, data_size, stdout);
247    }
248
249    destroy_trace(trace);
250    return 0;
251}
252
Note: See TracBrowser for help on using the repository browser.