source: libpacketdump/libpacketdump.cc @ 9c6005f

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

tracepktdump now outputs the libtrace direction value for each packet

  • Property mode set to 100644
File size: 4.7 KB
Line 
1#include <libtrace.h>
2#include <err.h>
3#include <time.h>
4#include "libpacketdump.h"
5#include "config.h"
6#include <stdio.h>
7#include <netdb.h>
8#include <stdlib.h>
9#include <getopt.h>
10
11#include <sys/socket.h>
12
13#ifdef HAVE_NETINET_ETHER
14#  include <netinet/ether.h>
15#endif
16
17
18#ifdef HAVE_INTTYPES_H
19#  include <inttypes.h>
20#else
21#  error "Can't find inttypes.h"
22#endif
23
24#ifdef HAVE_LIMITS_H
25#  include <limits.h>
26#endif
27
28#ifdef HAVE_SYS_LIMITS_H
29#  include <sys/limits.h>
30#endif
31
32#ifdef HAVE_SYS_TYPES_H
33#  include <sys/types.h>
34#endif
35#include <net/if.h>
36#include <netinet/in.h>
37#include <stdio.h>
38
39#include <net/if_arp.h>
40#ifdef HAVE_NETINET_IF_ETHER_H
41#  include <netinet/if_ether.h>
42#endif
43#include <dlfcn.h>
44#include <map>
45#include <string>
46#include <ctype.h>
47#include "libpacketdump.h"
48extern "C"{
49#include "grammar.h"
50}
51
52enum decode_style_t {
53    DECODE_NORMAL,
54    DECODE_PARSER
55};
56
57typedef void (*decode_norm_t)(uint16_t type,char *packet,int len);
58typedef void (*decode_parser_t)(uint16_t type,char *packet,int len, element_t* el);
59
60typedef union decode_funcs {
61    decode_norm_t decode_n;
62    decode_parser_t decode_p;
63} decode_funcs_t;
64
65typedef struct decoder {
66    enum decode_style_t style;
67    decode_funcs_t *func;
68    element_t *el; // make a union of structs with all args in it for all funcs?
69} decode_t;
70
71
72static std::map<std::string,std::map<uint16_t,decode_t> > decoders;
73
74#define WIDTH 16
75
76#ifndef DIRNAME
77#define DIRNAME "./"
78#warning "No DIRNAME set!"
79#endif
80
81void trace_dump_packet(struct libtrace_packet_t *packet)
82{
83        time_t sec = (time_t)trace_get_seconds(packet);
84        char *link=(char *)trace_get_link(packet);
85
86        printf("\n%s",ctime(&sec));
87        printf(" Capture: Packet Length: %i/%i Direction Value: %i\n",
88                        (int)trace_get_capture_length(packet),
89                        (int)trace_get_wire_length(packet),
90                        (int)trace_get_direction(packet));
91        if (!link) 
92                printf(" [No link layer available]\n");
93        else
94                decode_next(link,trace_get_capture_length(packet), "link",
95                        trace_get_link_type(packet));
96}
97
98static void generic_decode(uint16_t type,char *packet, int len) {
99        int i;
100        printf(" Unknown Protocol: %i",type);
101        for(i=0;i<len; /* Nothing */ ) {
102                int j;
103                printf("\n ");
104                for(j=0;j<WIDTH;j++) {
105                        if (i+j<len)
106                                printf(" %02x",(unsigned char)packet[i+j]);
107                        else
108                                printf("   ");
109                }
110                printf("    ");
111                for(j=0;j<WIDTH;j++) {
112                        if (i+j<len)
113                                if (isprint((unsigned char)packet[i+j]))
114                                        printf("%c",(unsigned char)packet[i+j]);
115                                else
116                                        printf(".");
117                        else
118                                printf("   ");
119                }
120                if (i+WIDTH>len)
121                        break;
122                else
123                        i+=WIDTH;
124        }
125        printf("\n");
126}
127
128void decode_next(char *packet,int len,char *proto_name,int type)
129{
130        std::string sname(proto_name);
131
132        // if we haven't worked out how to decode this type yet, load the
133        // appropriate files to do so
134        if (decoders[sname].find(type)==decoders[sname].end()) {
135                void *hdl;
136                char name[1024];
137                decode_funcs_t *func = new decode_funcs_t;
138                decode_t dec;
139                snprintf(name,sizeof(name),"%s/%s_%i.so",DIRNAME,sname.c_str(),type);
140                hdl = dlopen(name,RTLD_LAZY);
141                if (!hdl) {
142                        // if there is no shared library, try a protocol file
143                        snprintf(name,sizeof(name),"%s/%s_%i.protocol",
144                                DIRNAME,sname.c_str(),type);
145                        hdl = parse_protocol_file(name);
146
147                        if(!hdl)
148                        {
149                                // no protocol file either, use a generic one
150                                func->decode_n = generic_decode;
151                                dec.style = DECODE_NORMAL;
152                                dec.el = NULL;
153                        } else {
154                                // use the protocol file
155                                func->decode_p = decode_protocol_file;
156                                dec.style = DECODE_PARSER;
157                                dec.el = (element_t*)hdl;
158                        }
159                } else {
160                        void *s=dlsym(hdl,"decode");
161                        if (!s) {
162                                // the shared library doesnt have a decode func
163                                // TODO should try the protocol file now
164                                func->decode_n = generic_decode;
165                                dec.style = DECODE_NORMAL;
166                                dec.el = NULL;
167                        }
168                        else
169                        {
170                                // use the shared library
171                                func->decode_n = (decode_norm_t)s;
172                                dec.style = DECODE_NORMAL;
173                                dec.el = NULL; 
174                        }
175                }
176                dec.func = func;
177                decoders[sname][type] = dec;
178        }
179
180        if (decoders[sname][type].func->decode_n == generic_decode) {
181                /* We can't decode a link, so lets skip that and see if libtrace
182                 * knows how to find us the ip header
183                 */
184                if (sname=="link") {
185                        uint16_t newtype;
186                        uint32_t newlen=len;
187                        void *network=trace_get_payload_from_link(packet,
188                                        (libtrace_linktype_t)type,
189                                        &newtype,&newlen);
190                        if (network) {
191                                printf("skipping unknown link header of type %i to %i\n",type,newtype);
192                                decode_next((char*)network,newlen,"eth",newtype);
193                                return;
194                        }
195                }
196                else {
197                        printf("unknown protocol %s/%i\n",sname.c_str(),type);
198                }
199        }
200
201        // decode using the appropriate function
202        switch(decoders[sname][type].style)
203        {
204                case DECODE_NORMAL:
205                        decoders[sname][type].func->decode_n(type,packet,len);
206                        break;
207
208                case DECODE_PARSER:
209                        decoders[sname][type].func->decode_p(type,packet,len,
210                                decoders[sname][type].el);
211                        break;
212
213        };
214}
Note: See TracBrowser for help on using the repository browser.