source: examples/pcap2erf/pcap2erf.c @ 167adf2

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

added pcap2erf sample rtclient

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