Trivial warning fixes
[obnox/wireshark/wip.git] / epan / dissectors / packet-pktgen.c
1 /* packet-pktgen.c
2  * Routines for "Linux pktgen" dissection
3  * Copyright 2006 _FF_ 
4  * Francesco Fondelli <francesco dot fondelli, gmail dot com>
5  *
6  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  * 
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  * 
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  * 
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
25  */
26
27 /* FF:
28  * The linux packet generator is a tool to generate packets at very high speed in the kernel.
29  * See linux/net/core/pktgen.c and linux/Documentation/networking/pktgen.txt for more info.
30  */
31
32 #ifdef HAVE_CONFIG_H
33 # include "config.h"
34 #endif
35
36 #if 0
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #endif
41
42 #include <glib.h>
43
44 #include <epan/packet.h>
45
46 /* magic num used for heuristic */
47 static const guint8 pktgen_magic[] = { 0xbe, 0x9b, 0xe9, 0x55 };
48
49 /* Initialize the protocol and registered fields */
50 static int proto_pktgen = -1;
51
52 /* pktgen header */
53 static int hf_pktgen_magic = -1;
54 static int hf_pktgen_seqnum = -1;
55 static int hf_pktgen_tvsec = -1;
56 static int hf_pktgen_tvusec = -1;
57 static int hf_pktgen_timestamp = -1;
58
59 /* Initialize the subtree pointer */
60 static gint ett_pktgen = -1;
61
62 /* data dissector handle */
63 static dissector_handle_t data_handle;
64
65 /* entry point */
66 static gboolean dissect_pktgen(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
67 {
68     proto_item *ti = NULL;
69     proto_item *tmp = NULL;
70     proto_tree *pktgen_tree = NULL;
71     guint32 offset = 0;
72     nstime_t tstamp;
73
74     /* check for min size */
75     if(tvb_length(tvb) < 16) {  /* Not a PKTGEN packet. */
76         return FALSE;
77     }
78     
79     /* check for magic number */
80     if(tvb_memeql(tvb, 0, pktgen_magic, 4) == -1) { /* Not a PKTGEN packet. */
81         return FALSE;
82     }
83         
84     /* Make entries in Protocol column and Info column on summary display */
85     
86     if(check_col(pinfo->cinfo, COL_PROTOCOL)) 
87         col_set_str(pinfo->cinfo, COL_PROTOCOL, "PKTGEN");
88     
89     if(check_col(pinfo->cinfo, COL_INFO)) {
90         col_add_fstr(pinfo->cinfo, COL_INFO, "Seq: %u", tvb_get_ntohl(tvb, 4));
91     }
92     
93     if(tree) {
94         
95         /* create display subtree for the protocol */
96         
97         ti = proto_tree_add_item(tree, proto_pktgen, tvb, 0, -1, FALSE);
98         
99         pktgen_tree = proto_item_add_subtree(ti, ett_pktgen);
100         
101         /* add items to the subtree */
102         
103         proto_tree_add_item(pktgen_tree, hf_pktgen_magic, tvb, offset, 4, FALSE);
104         offset+=4;
105
106         proto_tree_add_item(pktgen_tree, hf_pktgen_seqnum, tvb, offset, 4, FALSE);
107         offset+=4;
108
109         tstamp.secs = tvb_get_ntohl(tvb, offset);
110         tmp = proto_tree_add_item(pktgen_tree, hf_pktgen_tvsec, tvb, offset, 4, FALSE);
111         PROTO_ITEM_SET_GENERATED(tmp);
112         offset+=4;
113
114         tstamp.nsecs = tvb_get_ntohl(tvb, offset) /* microsecond on the wire so... */ * 1000;
115         tmp = proto_tree_add_item(pktgen_tree, hf_pktgen_tvusec, tvb, offset, 4, FALSE);
116         PROTO_ITEM_SET_GENERATED(tmp);
117         offset+=4;
118         
119         proto_tree_add_time(pktgen_tree, hf_pktgen_timestamp, tvb, offset - 8, 8, &tstamp);
120         
121 #if 0
122         if(tvb_length_remaining(tvb, offset)) /* random data */
123             proto_tree_add_text(pktgen_tree, tvb, offset, -1, "Data (%u bytes)",
124                                 tvb_length_remaining(tvb, offset));
125 #else
126         if(tvb_length_remaining(tvb, offset)) /* random data */
127             call_dissector(data_handle, tvb_new_subset(tvb, offset, -1, -1), pinfo,
128                 pktgen_tree);
129 #endif
130     }
131
132     return TRUE;
133 }
134
135
136 /* Register the protocol with Wireshark */
137 void proto_register_pktgen(void)
138 {                 
139     /* Setup list of header fields */
140     
141     static hf_register_info hf[] = {
142         
143         { &hf_pktgen_magic,
144           { 
145               "Magic number", "pktgen.magic", 
146               FT_UINT32, BASE_HEX, NULL, 0x0, 
147               "The pktgen magic number", HFILL
148           }
149         },
150         
151         { &hf_pktgen_seqnum,
152           { 
153               "Sequence number", "pktgen.seqnum", 
154               FT_UINT32, BASE_DEC, NULL, 0x0, 
155               "Sequence number", HFILL
156           }
157         },
158
159         { &hf_pktgen_tvsec,
160           { 
161               "Timestamp tvsec", "pktgen.tvsec", 
162               FT_UINT32, BASE_DEC, NULL, 0x0, 
163               "Timestamp tvsec part", HFILL
164           }
165         },
166
167         { &hf_pktgen_tvusec,
168           { 
169               "Timestamp tvusec", "pktgen.tvusec", 
170               FT_UINT32, BASE_DEC, NULL, 0x0, 
171               "Timestamp tvusec part", HFILL
172           }
173         },
174
175         { &hf_pktgen_timestamp,
176           { 
177               "Timestamp", "pktgen.timestamp", 
178               FT_ABSOLUTE_TIME, BASE_HEX, NULL, 0x0,
179               "Timestamp", HFILL
180           }
181         }               
182     };
183         
184     /* Setup protocol subtree array */
185         
186     static gint *ett[] = {
187         &ett_pktgen
188     };
189         
190     /* Register the protocol name and description */
191         
192     proto_pktgen = proto_register_protocol("Linux Kernel Packet Generator", "PKTGEN", "pktgen");
193         
194     /* Required function calls to register the header fields and subtrees used */
195         
196     proto_register_field_array(proto_pktgen, hf, array_length(hf));
197     proto_register_subtree_array(ett, array_length(ett));
198 }
199
200
201 void proto_reg_handoff_pktgen(void)
202 {
203     /* Register as a heuristic UDP dissector */
204     heur_dissector_add("udp", dissect_pktgen, proto_pktgen);
205
206     /* Find data dissector handle */
207     data_handle = find_dissector("data");
208 }