more decompress
[wireshark-sm.git] / epan / exported_pdu.c
blobdfa109e421a54f94e3889aa529c467878c873f94
1 /*
2 * exported_pdu.c
3 * exported_pdu helper functions
4 * Copyright 2013, Anders Broman <anders-broman@ericsson.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
14 #include <glib.h>
16 #include <epan/packet.h>
17 #include <epan/exported_pdu.h>
18 #include <epan/tap.h>
19 #include <wiretap/wtap.h>
21 #include <wsutil/pint.h>
23 static GSList *export_pdu_tap_name_list;
24 static wmem_map_t *export_pdu_encap_table;
26 static int exp_pdu_data_ip_size(const address* addr)
28 if (addr->type == AT_IPv4){
29 return 4 + EXP_PDU_TAG_IPV4_LEN;
30 } else if(addr->type == AT_IPv6){
31 return 4 + EXP_PDU_TAG_IPV6_LEN;
34 return 0;
37 static int exp_pdu_data_src_ip_size(packet_info *pinfo, void* data _U_)
39 return exp_pdu_data_ip_size(&pinfo->net_src);
42 static int exp_pdu_data_src_ip_populate_data(packet_info *pinfo, void* data _U_, uint8_t *tlv_buffer, uint32_t buffer_size _U_)
44 if(pinfo->net_src.type == AT_IPv4){
45 phton16(tlv_buffer+0, EXP_PDU_TAG_IPV4_SRC);
46 phton16(tlv_buffer+2, EXP_PDU_TAG_IPV4_LEN); /* tag length */
47 memcpy(tlv_buffer+4, pinfo->net_src.data, EXP_PDU_TAG_IPV4_LEN);
48 return 4 + EXP_PDU_TAG_IPV4_LEN;
49 }else if(pinfo->net_src.type == AT_IPv6){
50 phton16(tlv_buffer+0, EXP_PDU_TAG_IPV6_SRC);
51 phton16(tlv_buffer+2, EXP_PDU_TAG_IPV6_LEN); /* tag length */
52 memcpy(tlv_buffer+4, pinfo->net_src.data, EXP_PDU_TAG_IPV6_LEN);
53 return 4 + EXP_PDU_TAG_IPV6_LEN;
56 return 0;
59 static int exp_pdu_data_dst_ip_size(packet_info *pinfo, void* data _U_)
61 return exp_pdu_data_ip_size(&pinfo->net_dst);
64 static int exp_pdu_data_dst_ip_populate_data(packet_info *pinfo, void* data _U_, uint8_t *tlv_buffer, uint32_t buffer_size _U_)
66 if(pinfo->net_dst.type == AT_IPv4){
67 phton16(tlv_buffer+0, EXP_PDU_TAG_IPV4_DST);
68 phton16(tlv_buffer+2, EXP_PDU_TAG_IPV4_LEN); /* tag length */
69 memcpy(tlv_buffer+4, pinfo->net_dst.data, EXP_PDU_TAG_IPV4_LEN);
70 return 4 + EXP_PDU_TAG_IPV4_LEN;
71 }else if(pinfo->net_dst.type == AT_IPv6){
72 phton16(tlv_buffer+0, EXP_PDU_TAG_IPV6_DST);
73 phton16(tlv_buffer+2, EXP_PDU_TAG_IPV6_LEN); /* tag length */
74 memcpy(tlv_buffer+4, pinfo->net_dst.data, EXP_PDU_TAG_IPV6_LEN);
75 return 4 + EXP_PDU_TAG_IPV6_LEN;
78 return 0;
81 static int exp_pdu_data_port_type_size(packet_info *pinfo _U_, void* data _U_)
83 return EXP_PDU_TAG_PORT_LEN + 4;
86 static unsigned exp_pdu_ws_port_type_to_exp_pdu_port_type(port_type pt)
88 switch (pt)
90 case PT_NONE:
91 return EXP_PDU_PT_NONE;
92 case PT_SCTP:
93 return EXP_PDU_PT_SCTP;
94 case PT_TCP:
95 return EXP_PDU_PT_TCP;
96 case PT_UDP:
97 return EXP_PDU_PT_UDP;
98 case PT_DCCP:
99 return EXP_PDU_PT_DCCP;
100 case PT_IPX:
101 return EXP_PDU_PT_IPX;
102 case PT_DDP:
103 return EXP_PDU_PT_DDP;
104 case PT_IDP:
105 return EXP_PDU_PT_IDP;
106 case PT_USB:
107 return EXP_PDU_PT_USB;
108 case PT_I2C:
109 return EXP_PDU_PT_I2C;
110 case PT_IBQP:
111 return EXP_PDU_PT_IBQP;
112 case PT_BLUETOOTH:
113 return EXP_PDU_PT_BLUETOOTH;
114 case PT_IWARP_MPA:
115 return EXP_PDU_PT_IWARP_MPA;
116 case PT_MCTP:
117 return EXP_PDU_PT_MCTP;
120 DISSECTOR_ASSERT(false);
121 return EXP_PDU_PT_NONE;
124 static int exp_pdu_data_port_type_populate_data(packet_info *pinfo, void* data, uint8_t *tlv_buffer, uint32_t buffer_size _U_)
126 unsigned pt;
128 phton16(tlv_buffer+0, EXP_PDU_TAG_PORT_TYPE);
129 phton16(tlv_buffer+2, EXP_PDU_TAG_PORT_TYPE_LEN); /* tag length */
130 pt = exp_pdu_ws_port_type_to_exp_pdu_port_type(pinfo->ptype);
131 phton32(tlv_buffer+4, pt);
133 return exp_pdu_data_port_type_size(pinfo, data);
136 static int exp_pdu_data_port_size(packet_info *pinfo _U_, void* data _U_)
138 return EXP_PDU_TAG_PORT_LEN + 4;
141 static int exp_pdu_data_port_populate_data(uint32_t port, uint8_t porttype, uint8_t *tlv_buffer, uint32_t buffer_size _U_)
143 phton16(tlv_buffer+0, porttype);
144 phton16(tlv_buffer+2, EXP_PDU_TAG_PORT_LEN); /* tag length */
145 phton32(tlv_buffer+4, port);
147 return EXP_PDU_TAG_PORT_LEN + 4;
150 static int exp_pdu_data_src_port_populate_data(packet_info *pinfo, void* data _U_, uint8_t *tlv_buffer, uint32_t buffer_size)
152 return exp_pdu_data_port_populate_data(pinfo->srcport, EXP_PDU_TAG_SRC_PORT, tlv_buffer, buffer_size);
155 static int exp_pdu_data_dst_port_populate_data(packet_info *pinfo, void* data _U_, uint8_t *tlv_buffer, uint32_t buffer_size)
157 return exp_pdu_data_port_populate_data(pinfo->destport, EXP_PDU_TAG_DST_PORT, tlv_buffer, buffer_size);
160 static int exp_pdu_data_orig_frame_num_size(packet_info *pinfo _U_, void* data _U_)
162 return EXP_PDU_TAG_ORIG_FNO_LEN + 4;
165 static int exp_pdu_data_orig_frame_num_populate_data(packet_info *pinfo, void* data, uint8_t *tlv_buffer, uint32_t buffer_size _U_)
167 phton16(tlv_buffer+0, EXP_PDU_TAG_ORIG_FNO);
168 phton16(tlv_buffer+2, EXP_PDU_TAG_ORIG_FNO_LEN); /* tag length */
169 phton32(tlv_buffer+4, pinfo->num);
171 return exp_pdu_data_orig_frame_num_size(pinfo, data);
174 WS_DLL_PUBLIC int exp_pdu_data_dissector_table_num_value_size(packet_info *pinfo _U_, void* data _U_)
176 return EXP_PDU_TAG_DISSECTOR_TABLE_NUM_VAL_LEN + 4;
179 WS_DLL_PUBLIC int exp_pdu_data_dissector_table_num_value_populate_data(packet_info *pinfo _U_, void* data, uint8_t *tlv_buffer, uint32_t buffer_size _U_)
181 uint32_t value = GPOINTER_TO_UINT(data);
183 phton16(tlv_buffer+0, EXP_PDU_TAG_DISSECTOR_TABLE_NAME_NUM_VAL);
184 phton16(tlv_buffer+2, EXP_PDU_TAG_DISSECTOR_TABLE_NUM_VAL_LEN); /* tag length */
185 phton32(tlv_buffer+4, value);
187 return exp_pdu_data_dissector_table_num_value_size(pinfo, data);
190 exp_pdu_data_item_t exp_pdu_data_src_ip = {exp_pdu_data_src_ip_size, exp_pdu_data_src_ip_populate_data, NULL};
191 exp_pdu_data_item_t exp_pdu_data_dst_ip = {exp_pdu_data_dst_ip_size, exp_pdu_data_dst_ip_populate_data, NULL};
192 exp_pdu_data_item_t exp_pdu_data_port_type = {exp_pdu_data_port_type_size, exp_pdu_data_port_type_populate_data, NULL};
193 exp_pdu_data_item_t exp_pdu_data_src_port = {exp_pdu_data_port_size, exp_pdu_data_src_port_populate_data, NULL};
194 exp_pdu_data_item_t exp_pdu_data_dst_port = {exp_pdu_data_port_size, exp_pdu_data_dst_port_populate_data, NULL};
195 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};
197 exp_pdu_data_t *export_pdu_create_common_tags(packet_info *pinfo, const char *proto_name, uint16_t tag_type)
199 const exp_pdu_data_item_t *common_exp_pdu_items[] = {
200 &exp_pdu_data_src_ip,
201 &exp_pdu_data_dst_ip,
202 &exp_pdu_data_port_type,
203 &exp_pdu_data_src_port,
204 &exp_pdu_data_dst_port,
205 &exp_pdu_data_orig_frame_num,
206 NULL
209 return export_pdu_create_tags(pinfo, proto_name, tag_type, common_exp_pdu_items);
213 * Allocates and fills the exp_pdu_data_t struct according to the list of items
215 * The tags in the tag buffer SHOULD be added in numerical order.
217 exp_pdu_data_t *
218 export_pdu_create_tags(packet_info *pinfo, const char* proto_name, uint16_t tag_type, const exp_pdu_data_item_t **items_list)
220 exp_pdu_data_t *exp_pdu_data;
221 const exp_pdu_data_item_t **loop_items = items_list;
222 int tag_buf_size = 0;
223 int proto_str_len, proto_tag_len, buf_remaining, item_size;
224 uint8_t* buffer_data;
226 DISSECTOR_ASSERT(proto_name != NULL);
227 DISSECTOR_ASSERT((tag_type == EXP_PDU_TAG_DISSECTOR_NAME) || (tag_type == EXP_PDU_TAG_HEUR_DISSECTOR_NAME) || (tag_type == EXP_PDU_TAG_DISSECTOR_TABLE_NAME));
229 exp_pdu_data = wmem_new(pinfo->pool, exp_pdu_data_t);
231 /* Start by computing size of protocol name as a tag */
232 proto_str_len = (int)strlen(proto_name);
234 /* Ensure that tag length is a multiple of 4 bytes */
235 proto_tag_len = ((proto_str_len + 3) & 0xfffffffc);
237 /* Add Tag + length */
238 tag_buf_size += (proto_tag_len + 4);
240 /* Compute size of items */
241 while (*loop_items) {
242 tag_buf_size += (*loop_items)->size_func(pinfo, (*loop_items)->data);
243 loop_items++;
246 /* Add end of options length */
247 tag_buf_size+=4;
249 exp_pdu_data->tlv_buffer = (uint8_t *)wmem_alloc0(pinfo->pool, tag_buf_size);
250 exp_pdu_data->tlv_buffer_len = tag_buf_size;
252 buffer_data = exp_pdu_data->tlv_buffer;
253 buf_remaining = exp_pdu_data->tlv_buffer_len;
255 /* Start by adding protocol name as a tag */
256 phton16(buffer_data+0, tag_type);
257 phton16(buffer_data+2, proto_tag_len); /* tag length */
258 memcpy(buffer_data+4, proto_name, proto_str_len);
259 buffer_data += (proto_tag_len+4);
260 buf_remaining -= (proto_tag_len+4);
262 /* Populate data */
263 loop_items = items_list;
264 while (*loop_items) {
265 item_size = (*loop_items)->populate_data(pinfo, (*loop_items)->data, buffer_data, buf_remaining);
266 buffer_data += item_size;
267 buf_remaining -= item_size;
268 loop_items++;
271 return exp_pdu_data;
275 register_export_pdu_tap_with_encap(const char *name, int encap)
277 char *tap_name = g_strdup(name);
278 export_pdu_tap_name_list = g_slist_prepend(export_pdu_tap_name_list, tap_name);
279 wmem_map_insert(export_pdu_encap_table, tap_name, GINT_TO_POINTER(encap));
280 return register_tap(tap_name);
284 register_export_pdu_tap(const char *name)
286 #if 0
287 /* XXX: We could register it like this, but don't have to, since
288 * export_pdu_tap_get_encap() returns WTAP_ENCAP_WIRESHARK_UPPER_PDU
289 * if it's not in the encap hash table anyway.
291 return register_export_pdu_tap_with_encap(name, WTAP_ENCAP_WIRESHARK_UPPER_PDU);
292 #endif
293 char *tap_name = g_strdup(name);
294 export_pdu_tap_name_list = g_slist_prepend(export_pdu_tap_name_list, tap_name);
295 return register_tap(tap_name);
298 static
299 int sort_pdu_tap_name_list(const void *a, const void *b)
301 return g_strcmp0((const char *)a, (const char*)b);
304 GSList *
305 get_export_pdu_tap_list(void)
307 export_pdu_tap_name_list = g_slist_sort(export_pdu_tap_name_list, sort_pdu_tap_name_list);
308 return export_pdu_tap_name_list;
312 export_pdu_tap_get_encap(const char* name)
314 void *value;
315 if (wmem_map_lookup_extended(export_pdu_encap_table, name, NULL, &value)) {
316 return GPOINTER_TO_INT(value);
319 return WTAP_ENCAP_WIRESHARK_UPPER_PDU;
322 void export_pdu_init(void)
324 export_pdu_encap_table = wmem_map_new(wmem_epan_scope(), wmem_str_hash, g_str_equal);
327 void export_pdu_cleanup(void)
329 g_slist_free_full(export_pdu_tap_name_list, g_free);
333 * Editor modelines - https://www.wireshark.org/tools/modelines.html
335 * Local variables:
336 * c-basic-offset: 8
337 * tab-width: 8
338 * indent-tabs-mode: t
339 * End:
341 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
342 * :indentSize=8:tabSize=8:noTabs=false: