For proto_tree_add_item(..., proto_xxx, ...)use ENC_NA as the encoding arg.
[obnox/wireshark/wip.git] / epan / dissectors / packet-sebek.c
1 /* packet-sebek.c
2  * Routines for Sebek - Kernel based data capture - packet dissection
3  * Modified to add sebek V3
4  * Copyright 2006, Camilo Viecco <cviecco@indiana.edu>
5  * Copyright 1999, Nathan Neulinger <nneul@umr.edu>
6  *
7  * See: http://project.honeynet.org/tools/sebek/ for more details
8  *
9  * $Id$
10  *
11  * Wireshark - Network traffic analyzer
12  * By Gerald Combs <gerald@wireshark.org>
13  * Copyright 1998 Gerald Combs
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28  */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <string.h>
35 #include <time.h>
36 #include <math.h>
37 #include <glib.h>
38
39 #include <epan/packet.h>
40 #include <epan/addr_resolv.h>
41
42 /*
43   Sebek v2:
44
45         IP address:     32bit unsigned
46         MAGIC Val:      32bit unsigned
47         Sebek Ver:      16bit unsigned    #value must match 2
48         Type            16bit unsigned
49         Counter:        32bit unsigned
50         Time_sec:       32bit unsigned
51         Time_usec:      32bit unsigned
52         Proc ID:        32bit unsigned
53         User ID:        32bit unsigned
54         File Desc:      32bit unsigned
55         Command:        12char array
56         Length:         Data Length
57
58         Data:           Variable Length data
59
60
61   Sebek v3 header
62         IP address:     32bit unsigned
63         MAGIC Val:      32bit unsigned
64         Sebek Ver:      16bit unsigned    #value must match 3
65         Type            16bit unsigned
66         Counter:        32bit unsigned
67         Time_sec:       32bit unsigned
68         Time_usec:      32bit unsigned
69         Parent_pid:     32bit unsigned
70         Proc ID:        32bit unsigned
71         User ID:        32bit unsigned
72         File Desc:      32bit unsigned
73         inode:          32bit unsigned
74         Command:        12char array
75         Length:         Data Length
76         Data:           Variable data length
77
78     Sebekv3 has a sock_socket_record subheader for IPV4:
79         Dest_ip:         32bit unsigned
80         Dest_port:       16bit unsigned
81         Src_ip:          32bit unsigned
82         src_port:        16bit unsigned
83         call:            16bit unsigned
84         proto             8bit unsigned
85
86  */
87
88 /* By default, but can be completely different */
89 #define UDP_PORT_SEBEK  1101
90
91 static int proto_sebek = -1;
92
93 static int hf_sebek_magic = -1;
94 static int hf_sebek_version = -1;
95 static int hf_sebek_type = -1;
96 static int hf_sebek_counter = -1;
97 static int hf_sebek_time = -1;
98 static int hf_sebek_pid = -1;
99 static int hf_sebek_uid = -1;
100 static int hf_sebek_fd = -1;
101 static int hf_sebek_cmd = -1;
102 static int hf_sebek_len = -1;
103 static int hf_sebek_data = -1;
104 static int hf_sebek_ppid = -1;
105 static int hf_sebek_inode = -1;
106 static int hf_sebek_socket_src_ip=-1;
107 static int hf_sebek_socket_src_port=-1;
108 static int hf_sebek_socket_dst_ip=-1;
109 static int hf_sebek_socket_dst_port=-1;
110 static int hf_sebek_socket_call=-1;
111 static int hf_sebek_socket_proto=-1;
112
113
114 static gint ett_sebek = -1;
115
116 /* dissect_sebek - dissects sebek packet data
117  * tvb - tvbuff for packet data (IN)
118  * pinfo - packet info
119  * proto_tree - resolved protocol tree
120  */
121 static void
122 dissect_sebek(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
123 {
124         proto_tree      *sebek_tree;
125         proto_item      *ti;
126         int offset = 0;
127         nstime_t ts;
128         int sebek_ver = 0;
129         int sebek_type = 0;
130         int cmd_len = 0;
131
132         col_set_str(pinfo->cinfo, COL_PROTOCOL, "SEBEK");
133
134         if (check_col(pinfo->cinfo, COL_INFO))
135         {
136                 col_set_str(pinfo->cinfo, COL_INFO, "SEBEK - ");
137
138                 if (tvb_length(tvb)<6)
139                         sebek_ver = 0;
140                 else
141                         sebek_ver = tvb_get_ntohs(tvb, 4);
142
143                 switch (sebek_ver) {
144                         case 2: col_append_fstr(pinfo->cinfo, COL_INFO, " pid(%d)", tvb_get_ntohl(tvb, 20));
145                                 col_append_fstr(pinfo->cinfo, COL_INFO, " uid(%d)", tvb_get_ntohl(tvb, 24));
146                                 col_append_fstr(pinfo->cinfo, COL_INFO, " fd(%d)", tvb_get_ntohl(tvb, 28));
147                                 col_append_fstr(pinfo->cinfo, COL_INFO, " cmd: %s", tvb_format_text(tvb, 32, 12));
148                                 break;
149                         case 3: col_append_fstr(pinfo->cinfo, COL_INFO, " pid(%d)", tvb_get_ntohl(tvb, 24));
150                                 col_append_fstr(pinfo->cinfo, COL_INFO, " uid(%d)", tvb_get_ntohl(tvb, 28));
151                                 col_append_fstr(pinfo->cinfo, COL_INFO, " fd(%d)", tvb_get_ntohl(tvb, 32));
152                                 cmd_len = tvb_strnlen(tvb, 40, 12);
153                                 if (cmd_len<0)
154                                         cmd_len = 0;
155                                 col_append_fstr(pinfo->cinfo, COL_INFO, " cmd: %s", tvb_format_text(tvb, 40, cmd_len));
156                                 break;
157                         default:
158                                 break;
159                 }
160         }
161
162
163         if (tree) {
164                 /* Adding Sebek item and subtree */
165                 ti = proto_tree_add_item(tree, proto_sebek, tvb, 0, -1, ENC_NA);
166                 sebek_tree = proto_item_add_subtree(ti, ett_sebek);
167
168                 /* check for minimum length before deciding where to go*/
169                 if (tvb_length(tvb)<6)
170                         sebek_ver = 0;
171                 else
172                         sebek_ver = tvb_get_ntohs(tvb, 4);
173
174                 switch (sebek_ver) {
175                         case 2: proto_tree_add_item(sebek_tree, hf_sebek_magic, tvb, offset, 4, ENC_BIG_ENDIAN);
176                                 offset += 4;
177
178                                 proto_tree_add_item(sebek_tree, hf_sebek_version, tvb, offset, 2, ENC_BIG_ENDIAN);
179                                 offset += 2;
180
181                                 proto_tree_add_item(sebek_tree, hf_sebek_type, tvb, offset, 2, ENC_BIG_ENDIAN);
182                                 offset += 2;
183
184                                 proto_tree_add_item(sebek_tree, hf_sebek_counter, tvb, offset, 4, ENC_BIG_ENDIAN);
185                                 offset += 4;
186
187                                 ts.secs = tvb_get_ntohl(tvb, offset);
188                                 ts.nsecs = tvb_get_ntohl(tvb, offset+4);
189                                 proto_tree_add_time(sebek_tree, hf_sebek_time, tvb, offset, 8, &ts);
190                                 offset += 8;
191
192                                 proto_tree_add_item(sebek_tree, hf_sebek_pid, tvb, offset, 4, ENC_BIG_ENDIAN);
193                                 offset += 4;
194
195                                 proto_tree_add_item(sebek_tree, hf_sebek_uid, tvb, offset, 4, ENC_BIG_ENDIAN);
196                                 offset += 4;
197
198                                 proto_tree_add_item(sebek_tree, hf_sebek_fd, tvb, offset, 4, ENC_BIG_ENDIAN);
199                                 offset += 4;
200
201                                 proto_tree_add_item(sebek_tree, hf_sebek_cmd, tvb, offset, 12, ENC_ASCII|ENC_NA);
202                                 offset += 12;
203
204                                 proto_tree_add_item(sebek_tree, hf_sebek_len, tvb, offset, 4, ENC_BIG_ENDIAN);
205                                 offset += 4;
206
207                                 proto_tree_add_item(sebek_tree, hf_sebek_data, tvb, offset, -1, ENC_ASCII|ENC_NA);
208
209                                 break;
210
211                         case 3: proto_tree_add_item(sebek_tree, hf_sebek_magic, tvb, offset, 4, ENC_BIG_ENDIAN);
212                                 offset += 4;
213
214                                 proto_tree_add_item(sebek_tree, hf_sebek_version, tvb, offset, 2, ENC_BIG_ENDIAN);
215                                 offset += 2;
216
217                                 sebek_type=tvb_get_ntohs(tvb, offset);
218                                 proto_tree_add_item(sebek_tree, hf_sebek_type, tvb, offset, 2, ENC_BIG_ENDIAN);
219                                 offset += 2;
220
221                                 proto_tree_add_item(sebek_tree, hf_sebek_counter, tvb, offset, 4, ENC_BIG_ENDIAN);
222                                 offset += 4;
223
224                                 ts.secs = tvb_get_ntohl(tvb, offset);
225                                 ts.nsecs = tvb_get_ntohl(tvb, offset+4);
226                                 proto_tree_add_time(sebek_tree, hf_sebek_time, tvb, offset, 8, &ts);
227                                 offset += 8;
228
229                                 proto_tree_add_item(sebek_tree, hf_sebek_ppid, tvb, offset, 4, ENC_BIG_ENDIAN);
230                                 offset += 4;
231
232                                 proto_tree_add_item(sebek_tree, hf_sebek_pid, tvb, offset, 4, ENC_BIG_ENDIAN);
233                                 offset += 4;
234
235                                 proto_tree_add_item(sebek_tree, hf_sebek_uid, tvb, offset, 4, ENC_BIG_ENDIAN);
236                                 offset += 4;
237
238                                 proto_tree_add_item(sebek_tree, hf_sebek_fd, tvb, offset, 4, ENC_BIG_ENDIAN);
239                                 offset += 4;
240
241                                 proto_tree_add_item(sebek_tree, hf_sebek_inode, tvb, offset, 4, ENC_BIG_ENDIAN);
242                                 offset += 4;
243
244                                 proto_tree_add_item(sebek_tree, hf_sebek_cmd, tvb, offset, 12, ENC_ASCII|ENC_NA);
245                                 offset += 12;
246
247                                 proto_tree_add_item(sebek_tree, hf_sebek_len, tvb, offset, 4, ENC_BIG_ENDIAN);
248                                 offset += 4;
249
250                                 if (sebek_type == 2) {
251                                         /*data is socket data, process accordingly*/
252                                         proto_tree_add_item(sebek_tree, hf_sebek_socket_dst_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
253                                         offset += 4;
254                                         proto_tree_add_item(sebek_tree, hf_sebek_socket_dst_port, tvb, offset, 2, ENC_BIG_ENDIAN);
255                                         offset += 2;
256                                         proto_tree_add_item(sebek_tree, hf_sebek_socket_src_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
257                                         offset += 4;
258                                         proto_tree_add_item(sebek_tree, hf_sebek_socket_src_port, tvb, offset, 2, ENC_BIG_ENDIAN);
259                                         offset += 2;
260                                         proto_tree_add_item(sebek_tree, hf_sebek_socket_call, tvb, offset, 2, ENC_BIG_ENDIAN);
261                                         offset += 2;
262                                         proto_tree_add_item(sebek_tree, hf_sebek_socket_proto, tvb, offset, 1, ENC_BIG_ENDIAN);
263                                         offset += 1;
264                                 } else {
265                                         proto_tree_add_item(sebek_tree, hf_sebek_data, tvb, offset, -1, ENC_ASCII|ENC_NA);
266                                 }
267
268                                 break;
269
270                         default:
271                                 break;
272
273                 }
274         }
275 }
276
277 void
278 proto_register_sebek(void)
279 {
280         static hf_register_info hf[] = {
281                 { &hf_sebek_magic, {
282                         "Magic", "sebek.magic", FT_UINT32, BASE_HEX,
283                         NULL, 0, "Magic Number", HFILL }},
284                 { &hf_sebek_version, {
285                         "Version", "sebek.version", FT_UINT16, BASE_DEC,
286                         NULL, 0, "Version Number", HFILL }},
287                 { &hf_sebek_type, {
288                         "Type", "sebek.type", FT_UINT16, BASE_DEC,
289                         NULL, 0, NULL, HFILL }},
290                 { &hf_sebek_counter, {
291                         "Counter", "sebek.counter", FT_UINT32, BASE_DEC,
292                         NULL, 0, NULL, HFILL }},
293                 { &hf_sebek_time, {
294                         "Time", "sebek.time.sec", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL,
295                         NULL, 0, NULL, HFILL }},
296                 { &hf_sebek_pid, {
297                         "Process ID", "sebek.pid", FT_UINT32, BASE_DEC,
298                         NULL, 0, NULL, HFILL }},
299                 { &hf_sebek_uid, {
300                         "User ID", "sebek.uid", FT_UINT32, BASE_DEC,
301                         NULL, 0, NULL, HFILL }},
302                 { &hf_sebek_fd, {
303                         "File Descriptor", "sebek.fd", FT_UINT32, BASE_DEC,
304                         NULL, 0, "File Descriptor Number", HFILL }},
305                 { &hf_sebek_cmd, {
306                         "Command Name", "sebek.cmd", FT_STRING, BASE_NONE,
307                         NULL, 0, NULL, HFILL }},
308                 { &hf_sebek_len, {
309                         "Data Length", "sebek.len", FT_UINT32, BASE_DEC,
310                         NULL, 0, NULL, HFILL }},
311                 { &hf_sebek_ppid, {
312                         "Parent Process ID", "sebek.ppid", FT_UINT32, BASE_DEC,
313                         NULL, 0, "Process ID", HFILL }},
314                 { &hf_sebek_inode, {
315                         "Inode ID", "sebek.inode", FT_UINT32, BASE_DEC,
316                         NULL, 0, "Process ID", HFILL }},
317                 { &hf_sebek_data, {
318                         "Data", "sebek.data", FT_STRING, BASE_NONE,
319                         NULL, 0, NULL, HFILL }},
320                 { &hf_sebek_socket_src_ip, {
321                         "Socket.local_ip", "sebek.socket.src_ip", FT_IPv4, BASE_NONE,
322                         NULL, 0, "Socket.src_ip", HFILL }},
323                 { &hf_sebek_socket_src_port, {
324                         "Socket.local_port", "sebek.socket.src_port", FT_UINT16, BASE_DEC,
325                         NULL, 0, "Socket.src_port", HFILL }},
326                 { &hf_sebek_socket_dst_ip, {
327                         "Socket.remote_ip", "sebek.socket.dst_ip", FT_IPv4, BASE_NONE,
328                         NULL, 0, "Socket.dst_ip", HFILL }},
329                 { &hf_sebek_socket_dst_port, {
330                         "Socket.remote_port", "sebek.socket.dst_port", FT_UINT16, BASE_DEC,
331                         NULL, 0, "Socket.dst_port", HFILL }},
332                 { &hf_sebek_socket_call, {
333                         "Socket.Call_id", "sebek.socket.call", FT_UINT16, BASE_DEC,
334                         NULL, 0, "Socket.call", HFILL }},
335                 { &hf_sebek_socket_proto, {
336                         "Socket.ip_proto", "sebek.socket.ip_proto", FT_UINT8, BASE_DEC,
337                         NULL, 0, NULL, HFILL }}
338         };
339         static gint *ett[] = {
340                 &ett_sebek
341         };
342
343         proto_sebek = proto_register_protocol("SEBEK - Kernel Data Capture", "SEBEK", "sebek");
344         proto_register_field_array(proto_sebek, hf, array_length(hf));
345         proto_register_subtree_array(ett, array_length(ett));
346 }
347
348 void
349 proto_reg_handoff_sebek(void)
350 {
351         dissector_handle_t sebek_handle;
352
353         sebek_handle = create_dissector_handle(dissect_sebek, proto_sebek);
354         dissector_add_uint("udp.port", UDP_PORT_SEBEK, sebek_handle);
355 }