TODO SMB2 NegotiateContext....
[metze/wireshark/wip.git] / epan / exported_pdu.c
1 /*
2  * exported_pdu.c
3  * exported_pdu helper functions
4  * Copyright 2013, Anders Broman <anders-broman@ericsson.com>
5  *
6  * Wireshark - Network traffic analyzer
7  * By Gerald Combs <gerald@wireshark.org>
8  * Copyright 1998 Gerald Combs
9  *
10  * SPDX-License-Identifier: GPL-2.0-or-later
11  */
12
13 #include "config.h"
14 #include <glib.h>
15
16 #include <epan/packet.h>
17 #include <epan/exported_pdu.h>
18 #include <epan/address_types.h>
19 #include <epan/tap.h>
20
21 static GSList *export_pdu_tap_name_list = NULL;
22
23 static int exp_pdu_data_ip_size(const address* addr)
24 {
25         if (addr->type == AT_IPv4){
26                 return 4 + EXP_PDU_TAG_IPV4_LEN;
27         } else if(addr->type == AT_IPv6){
28                 return 4 + EXP_PDU_TAG_IPV6_LEN;
29         }
30
31         return 0;
32 }
33
34 static int exp_pdu_data_src_ip_size(packet_info *pinfo, void* data _U_)
35 {
36         return exp_pdu_data_ip_size(&pinfo->net_src);
37 }
38
39 static int exp_pdu_data_src_ip_populate_data(packet_info *pinfo, void* data _U_, guint8 *tlv_buffer, guint32 buffer_size _U_)
40 {
41         if(pinfo->net_src.type == AT_IPv4){
42                 tlv_buffer[0] = 0;
43                 tlv_buffer[1] = EXP_PDU_TAG_IPV4_SRC;
44                 tlv_buffer[2] = 0;
45                 tlv_buffer[3] = EXP_PDU_TAG_IPV4_LEN; /* tag length */
46                 memcpy(tlv_buffer+4, pinfo->net_src.data, EXP_PDU_TAG_IPV4_LEN);
47                 return 4 + EXP_PDU_TAG_IPV4_LEN;
48         }else if(pinfo->net_src.type == AT_IPv6){
49                 tlv_buffer[0] = 0;
50                 tlv_buffer[1] = EXP_PDU_TAG_IPV6_SRC;
51                 tlv_buffer[2] = 0;
52                 tlv_buffer[3] = EXP_PDU_TAG_IPV6_LEN; /* tag length */
53                 memcpy(tlv_buffer+4, pinfo->net_src.data, EXP_PDU_TAG_IPV6_LEN);
54                 return 4 + EXP_PDU_TAG_IPV6_LEN;
55         }
56
57         return 0;
58 }
59
60 static int exp_pdu_data_dst_ip_size(packet_info *pinfo, void* data _U_)
61 {
62         return exp_pdu_data_ip_size(&pinfo->net_dst);
63 }
64
65 static int exp_pdu_data_dst_ip_populate_data(packet_info *pinfo, void* data _U_, guint8 *tlv_buffer, guint32 buffer_size _U_)
66 {
67         if(pinfo->net_dst.type == AT_IPv4){
68                 tlv_buffer[0] = 0;
69                 tlv_buffer[1] = EXP_PDU_TAG_IPV4_DST;
70                 tlv_buffer[2] = 0;
71                 tlv_buffer[3] = EXP_PDU_TAG_IPV4_LEN; /* tag length */
72                 memcpy(tlv_buffer+4, pinfo->net_dst.data, EXP_PDU_TAG_IPV4_LEN);
73                 return 4 + EXP_PDU_TAG_IPV4_LEN;
74         }else if(pinfo->net_dst.type == AT_IPv6){
75                 tlv_buffer[0] = 0;
76                 tlv_buffer[1] = EXP_PDU_TAG_IPV6_DST;
77                 tlv_buffer[2] = 0;
78                 tlv_buffer[3] = EXP_PDU_TAG_IPV6_LEN; /* tag length */
79                 memcpy(tlv_buffer+4, pinfo->net_dst.data, EXP_PDU_TAG_IPV6_LEN);
80                 return 4 + EXP_PDU_TAG_IPV6_LEN;
81         }
82
83         return 0;
84 }
85
86 static int exp_pdu_data_port_type_size(packet_info *pinfo _U_, void* data _U_)
87 {
88         return EXP_PDU_TAG_PORT_LEN + 4;
89 }
90
91 static guint exp_pdu_new_to_old_port_type(port_type pt)
92 {
93         switch (pt)
94         {
95         case PT_NONE:
96                 return OLD_PT_NONE;
97         case PT_SCTP:
98                 return OLD_PT_SCTP;
99         case PT_TCP:
100                 return OLD_PT_TCP;
101         case PT_UDP:
102                 return OLD_PT_UDP;
103         case PT_DCCP:
104                 return OLD_PT_DCCP;
105         case PT_IPX:
106                 return OLD_PT_IPX;
107         case PT_DDP:
108                 return OLD_PT_DDP;
109         case PT_IDP:
110                 return OLD_PT_IDP;
111         case PT_USB:
112                 return OLD_PT_USB;
113         case PT_I2C:
114                 return OLD_PT_I2C;
115         case PT_IBQP:
116                 return OLD_PT_IBQP;
117         case PT_BLUETOOTH:
118                 return OLD_PT_BLUETOOTH;
119         }
120
121         DISSECTOR_ASSERT(FALSE);
122         return OLD_PT_NONE;
123 }
124
125 static int exp_pdu_data_port_type_populate_data(packet_info *pinfo, void* data, guint8 *tlv_buffer, guint32 buffer_size _U_)
126 {
127         guint pt;
128
129         tlv_buffer[0] = 0;
130         tlv_buffer[1] = EXP_PDU_TAG_PORT_TYPE;
131         tlv_buffer[2] = 0;
132         tlv_buffer[3] = EXP_PDU_TAG_PORT_TYPE_LEN; /* tag length */
133         pt = exp_pdu_new_to_old_port_type(pinfo->ptype);
134         tlv_buffer[4] = (pt & 0xff000000) >> 24;
135         tlv_buffer[5] = (pt & 0x00ff0000) >> 16;
136         tlv_buffer[6] = (pt & 0x0000ff00) >> 8;
137         tlv_buffer[7] = (pt & 0x000000ff);
138
139         return exp_pdu_data_port_type_size(pinfo, data);
140 }
141
142 static int exp_pdu_data_port_size(packet_info *pinfo _U_, void* data _U_)
143 {
144         return EXP_PDU_TAG_PORT_LEN + 4;
145 }
146
147 static int exp_pdu_data_port_populate_data(guint32 port, guint8 porttype, guint8 *tlv_buffer, guint32 buffer_size _U_)
148 {
149         tlv_buffer[0] = 0;
150         tlv_buffer[1] = porttype;
151         tlv_buffer[2] = 0;
152         tlv_buffer[3] = EXP_PDU_TAG_PORT_LEN; /* tag length */
153         tlv_buffer[4] = (port & 0xff000000) >> 24;
154         tlv_buffer[5] = (port & 0x00ff0000) >> 16;
155         tlv_buffer[6] = (port & 0x0000ff00) >> 8;
156         tlv_buffer[7] = (port & 0x000000ff);
157
158         return EXP_PDU_TAG_PORT_LEN + 4;
159 }
160
161 static int exp_pdu_data_src_port_populate_data(packet_info *pinfo, void* data _U_, guint8 *tlv_buffer, guint32 buffer_size)
162 {
163         return exp_pdu_data_port_populate_data(pinfo->srcport, EXP_PDU_TAG_SRC_PORT, tlv_buffer, buffer_size);
164 }
165
166 static int exp_pdu_data_dst_port_populate_data(packet_info *pinfo, void* data _U_, guint8 *tlv_buffer, guint32 buffer_size)
167 {
168         return exp_pdu_data_port_populate_data(pinfo->destport, EXP_PDU_TAG_DST_PORT, tlv_buffer, buffer_size);
169 }
170
171 static int exp_pdu_data_orig_frame_num_size(packet_info *pinfo _U_, void* data _U_)
172 {
173         return EXP_PDU_TAG_ORIG_FNO_LEN + 4;
174 }
175
176 static int exp_pdu_data_orig_frame_num_populate_data(packet_info *pinfo, void* data, guint8 *tlv_buffer, guint32 buffer_size _U_)
177 {
178         tlv_buffer[0] = 0;
179         tlv_buffer[1] = EXP_PDU_TAG_ORIG_FNO;
180         tlv_buffer[2] = 0;
181         tlv_buffer[3] = EXP_PDU_TAG_ORIG_FNO_LEN; /* tag length */
182         tlv_buffer[4] = (pinfo->num & 0xff000000) >> 24;
183         tlv_buffer[5] = (pinfo->num & 0x00ff0000) >> 16;
184         tlv_buffer[6] = (pinfo->num & 0x0000ff00) >> 8;
185         tlv_buffer[7] = (pinfo->num & 0x000000ff);
186
187         return exp_pdu_data_orig_frame_num_size(pinfo, data);
188 }
189
190 WS_DLL_PUBLIC int exp_pdu_data_dissector_table_num_value_size(packet_info *pinfo _U_, void* data _U_)
191 {
192         return EXP_PDU_TAG_DISSECTOR_TABLE_NUM_VAL_LEN + 4;
193 }
194
195 WS_DLL_PUBLIC int exp_pdu_data_dissector_table_num_value_populate_data(packet_info *pinfo _U_, void* data, guint8 *tlv_buffer, guint32 buffer_size _U_)
196 {
197         guint32 value = GPOINTER_TO_UINT(data);
198
199         tlv_buffer[0] = 0;
200         tlv_buffer[1] = EXP_PDU_TAG_DISSECTOR_TABLE_NAME_NUM_VAL;
201         tlv_buffer[2] = 0;
202         tlv_buffer[3] = EXP_PDU_TAG_DISSECTOR_TABLE_NUM_VAL_LEN; /* tag length */
203         tlv_buffer[4] = (value & 0xff000000) >> 24;
204         tlv_buffer[5] = (value & 0x00ff0000) >> 16;
205         tlv_buffer[6] = (value & 0x0000ff00) >> 8;
206         tlv_buffer[7] = (value & 0x000000ff);
207
208         return exp_pdu_data_dissector_table_num_value_size(pinfo, data);
209 }
210
211
212 exp_pdu_data_item_t exp_pdu_data_src_ip = {exp_pdu_data_src_ip_size, exp_pdu_data_src_ip_populate_data, NULL};
213 exp_pdu_data_item_t exp_pdu_data_dst_ip = {exp_pdu_data_dst_ip_size, exp_pdu_data_dst_ip_populate_data, NULL};
214 exp_pdu_data_item_t exp_pdu_data_port_type = {exp_pdu_data_port_type_size, exp_pdu_data_port_type_populate_data, NULL};
215 exp_pdu_data_item_t exp_pdu_data_src_port = {exp_pdu_data_port_size, exp_pdu_data_src_port_populate_data, NULL};
216 exp_pdu_data_item_t exp_pdu_data_dst_port = {exp_pdu_data_port_size, exp_pdu_data_dst_port_populate_data, NULL};
217 exp_pdu_data_item_t exp_pdu_data_orig_frame_num = {exp_pdu_data_orig_frame_num_size, exp_pdu_data_orig_frame_num_populate_data, NULL};
218
219 exp_pdu_data_t *export_pdu_create_common_tags(packet_info *pinfo, const char *proto_name, guint16 tag_type)
220 {
221         const exp_pdu_data_item_t *common_exp_pdu_items[] = {
222                 &exp_pdu_data_src_ip,
223                 &exp_pdu_data_dst_ip,
224                 &exp_pdu_data_port_type,
225                 &exp_pdu_data_src_port,
226                 &exp_pdu_data_dst_port,
227                 &exp_pdu_data_orig_frame_num,
228                 NULL
229         };
230
231         return export_pdu_create_tags(pinfo, proto_name, tag_type, common_exp_pdu_items);
232 }
233
234 /**
235  * Allocates and fills the exp_pdu_data_t struct according to the list of items
236  *
237  * The tags in the tag buffer SHOULD be added in numerical order.
238  */
239 exp_pdu_data_t *
240 export_pdu_create_tags(packet_info *pinfo, const char* proto_name, guint16 tag_type, const exp_pdu_data_item_t **items_list)
241 {
242         exp_pdu_data_t *exp_pdu_data;
243         const exp_pdu_data_item_t **loop_items = items_list;
244         int tag_buf_size = 0;
245         int proto_str_len, proto_tag_len, buf_remaining, item_size;
246         guint8* buffer_data;
247
248         DISSECTOR_ASSERT(proto_name != NULL);
249         DISSECTOR_ASSERT((tag_type == EXP_PDU_TAG_PROTO_NAME) || (tag_type == EXP_PDU_TAG_HEUR_PROTO_NAME) || (tag_type == EXP_PDU_TAG_DISSECTOR_TABLE_NAME));
250
251         exp_pdu_data = (exp_pdu_data_t *)wmem_alloc(wmem_packet_scope(), sizeof(exp_pdu_data_t));
252
253         /* Start by computing size of protocol name as a tag */
254         proto_str_len = (int)strlen(proto_name);
255
256         /* Ensure that tag length is a multiple of 4 bytes */
257         proto_tag_len = ((proto_str_len + 3) & 0xfffffffc);
258
259         /* Add Tag + length */
260         tag_buf_size += (proto_tag_len + 4);
261
262         /* Compute size of items */
263         while (*loop_items) {
264                 tag_buf_size += (*loop_items)->size_func(pinfo, (*loop_items)->data);
265                 loop_items++;
266         }
267
268         /* Add end of options length */
269         tag_buf_size+=4;
270
271         exp_pdu_data->tlv_buffer = (guint8 *)wmem_alloc0(wmem_packet_scope(), tag_buf_size);
272         exp_pdu_data->tlv_buffer_len = tag_buf_size;
273
274         buffer_data = exp_pdu_data->tlv_buffer;
275         buf_remaining = exp_pdu_data->tlv_buffer_len;
276
277         /* Start by adding protocol name as a tag */
278         buffer_data[0] = (tag_type & 0xff00) >> 8;
279         buffer_data[1] = tag_type & 0x00ff;
280         buffer_data[2] = (proto_tag_len & 0xff00) >> 8;
281         buffer_data[3] = proto_tag_len & 0x00ff; /* tag length */
282         memcpy(buffer_data+4, proto_name, proto_str_len);
283         buffer_data += (proto_tag_len+4);
284         buf_remaining -= (proto_tag_len+4);
285
286         /* Populate data */
287         loop_items = items_list;
288         while (*loop_items) {
289                 item_size = (*loop_items)->populate_data(pinfo, (*loop_items)->data, buffer_data, buf_remaining);
290                 buffer_data += item_size;
291                 buf_remaining -= item_size;
292                 loop_items++;
293         }
294
295         return exp_pdu_data;
296 }
297
298 gint
299 register_export_pdu_tap(const char *name)
300 {
301         gchar *tap_name = g_strdup(name);
302         export_pdu_tap_name_list = g_slist_prepend(export_pdu_tap_name_list, tap_name);
303         return register_tap(tap_name);
304 }
305
306 static
307 gint sort_pdu_tap_name_list(gconstpointer a, gconstpointer b)
308 {
309         return g_strcmp0((const char *)a, (const char*)b);
310 }
311
312 GSList *
313 get_export_pdu_tap_list(void)
314 {
315         export_pdu_tap_name_list = g_slist_sort(export_pdu_tap_name_list, sort_pdu_tap_name_list);
316         return export_pdu_tap_name_list;
317 }
318
319 void export_pdu_init(void)
320 {
321 }
322
323 void export_pdu_cleanup(void)
324 {
325         g_slist_free_full(export_pdu_tap_name_list, g_free);
326 }
327
328 /*
329  * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
330  *
331  * Local variables:
332  * c-basic-offset: 8
333  * tab-width: 8
334  * indent-tabs-mode: t
335  * End:
336  *
337  * vi: set shiftwidth=8 tabstop=8 noexpandtab:
338  * :indentSize=8:tabSize=8:noTabs=false:
339  */