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
16 #include <epan/packet.h>
17 #include <epan/exported_pdu.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
;
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
;
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
;
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
)
91 return EXP_PDU_PT_NONE
;
93 return EXP_PDU_PT_SCTP
;
95 return EXP_PDU_PT_TCP
;
97 return EXP_PDU_PT_UDP
;
99 return EXP_PDU_PT_DCCP
;
101 return EXP_PDU_PT_IPX
;
103 return EXP_PDU_PT_DDP
;
105 return EXP_PDU_PT_IDP
;
107 return EXP_PDU_PT_USB
;
109 return EXP_PDU_PT_I2C
;
111 return EXP_PDU_PT_IBQP
;
113 return EXP_PDU_PT_BLUETOOTH
;
115 return EXP_PDU_PT_IWARP_MPA
;
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_
)
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
,
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.
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
);
246 /* Add end of options length */
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);
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
;
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
)
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
);
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
);
299 int sort_pdu_tap_name_list(const void *a
, const void *b
)
301 return g_strcmp0((const char *)a
, (const char*)b
);
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
)
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
338 * indent-tabs-mode: t
341 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
342 * :indentSize=8:tabSize=8:noTabs=false: