/src/wireshark/epan/dissectors/packet-ppcap.c
Line | Count | Source |
1 | | /* packet-ppcap.c |
2 | | * Copyright 2012, 2014, Ericsson AB |
3 | | * |
4 | | * Wireshark - Network traffic analyzer |
5 | | * By Gerald Combs <gerald@wireshark.org> |
6 | | * Copyright 1998 Gerald Combs |
7 | | * |
8 | | * SPDX-License-Identifier: GPL-2.0-or-later |
9 | | * |
10 | | */ |
11 | | |
12 | | #include "config.h" |
13 | | |
14 | | #include <epan/packet.h> |
15 | | #include <epan/address_types.h> |
16 | | |
17 | | #include <wsutil/ws_roundup.h> |
18 | | |
19 | | #include "packet-mtp3.h" |
20 | | |
21 | 0 | #define INVALID_SSN 0xff |
22 | | |
23 | | void proto_register_ppcap(void); |
24 | | |
25 | | static uint8_t ssn; |
26 | | |
27 | | static dissector_handle_t ppcap_handle; |
28 | | static dissector_handle_t mtp3_handle; /* MTP3 handle */ |
29 | | static dissector_handle_t tcap_handle; /* TCAP handle */ |
30 | | static dissector_handle_t bssap_handle; /* BSSAP handle */ |
31 | | static dissector_handle_t ranap_handle; /* RANAP handle */ |
32 | | static dissector_handle_t h248_handle; /* H248 handle */ |
33 | | static dissector_handle_t sip_handle; /* SIP handle */ |
34 | | static dissector_handle_t sccp_handle; /* SCCP handle */ |
35 | | static dissector_handle_t sgsap_handle; /* SGSAP handle */ |
36 | | static dissector_handle_t gtpv2_handle; /* GTPv2 handle */ |
37 | | |
38 | | static dissector_table_t sccp_ssn_dissector_table; |
39 | | |
40 | | static mtp3_addr_pc_t* mtp3_addr_opc; |
41 | | static mtp3_addr_pc_t* mtp3_addr_dpc; |
42 | | |
43 | | static int ss7pc_address_type = -1; |
44 | | |
45 | | static int ett_ppcap; |
46 | | static int ett_ppcap1; |
47 | | static int ett_ppcap_new; |
48 | | |
49 | | static const value_string payload_tag_values[] = { |
50 | | { 1, "Payload Type"}, |
51 | | { 2, "Payload Data"}, |
52 | | { 3, "Source Address"}, |
53 | | { 4, "Destination Address"}, |
54 | | { 5, "Local Port"}, |
55 | | { 6, "Remote Port"}, |
56 | | { 7, "Transfer Protocol used for message"}, |
57 | | { 8, "SCTP association ID" }, |
58 | | {256, "Info String"}, |
59 | | {0, NULL}, |
60 | | |
61 | | }; |
62 | | |
63 | | static const value_string address_type_values[] = { |
64 | | {1, "SSN+SPC"}, |
65 | | {2, "SPC"}, |
66 | | {3, "IP Address"}, |
67 | | {4, "Node Id"}, |
68 | | {0, NULL}, |
69 | | |
70 | | }; |
71 | | |
72 | | /* Initialise the header fields */ |
73 | | |
74 | | static int proto_ppcap; |
75 | | static int hf_ppcap_length; |
76 | | static int hf_ppcap_payload_type; |
77 | | static int hf_ppcap_ssn; |
78 | | static int hf_ppcap_spc; |
79 | | static int hf_ppcap_ssn1; |
80 | | static int hf_ppcap_spc1; |
81 | | static int hf_ppcap_opc; |
82 | | static int hf_ppcap_dpc; |
83 | | static int hf_ppcap_source_nodeid; |
84 | | static int hf_ppcap_destination_nodeid; |
85 | | /*static int hf_ppcap_source_address_type; */ |
86 | | /*static int hf_ppcap_destination_address_type; */ |
87 | | static int hf_ppcap_address_type; |
88 | | static int hf_ppcap_source_ip_address1; |
89 | | static int hf_ppcap_source_ip_address2; |
90 | | static int hf_ppcap_destination_ip_address1; |
91 | | static int hf_ppcap_destination_ip_address2; |
92 | | static int hf_ppcap_reserved; |
93 | | static int hf_ppcap_destreserved; |
94 | | static int hf_ppcap_info; |
95 | | static int hf_ppcap_payload_data; |
96 | | static int hf_ppcap_local_port; |
97 | | static int hf_ppcap_remote_port; |
98 | | static int hf_ppcap_transport_prot; |
99 | | static int hf_ppcap_sctp_assoc; |
100 | | |
101 | | /* Initialize the subtree pointers */ |
102 | | |
103 | | void proto_reg_handoff_ppcap(void); |
104 | | |
105 | | |
106 | | /* PPCAP payload types */ |
107 | | typedef enum { |
108 | | PPCAP_UNKNOWN = 0, |
109 | | PPCAP_MTP3 = 1, |
110 | | PPCAP_TCAP = 2, |
111 | | PPCAP_BSSAP = 3, |
112 | | PPCAP_RANAP = 4, |
113 | | PPCAP_H248 = 5, |
114 | | PPCAP_SIP = 6, |
115 | | PPCAP_SCCP = 7, |
116 | | PPCAP_SGSAP = 8, |
117 | | PPCAP_GTPV2 = 9 |
118 | | } payload_type_type; |
119 | | |
120 | | static int dissect_ppcap_payload_type(tvbuff_t *, packet_info *, proto_tree *, int, payload_type_type *); |
121 | | static int dissect_ppcap_source_address(tvbuff_t *, packet_info *, proto_tree *, int); |
122 | | static int dissect_ppcap_destination_address(tvbuff_t *, packet_info *, proto_tree *, int); |
123 | | static int dissect_ppcap_info_string(tvbuff_t *, proto_tree *, int); |
124 | | static int dissect_ppcap_local_port(tvbuff_t *, proto_tree *, int); |
125 | | static int dissect_ppcap_remote_port(tvbuff_t *,proto_tree *, int); |
126 | | static int dissect_ppcap_transport_protocol(tvbuff_t *,proto_tree *, int); |
127 | | static int dissect_ppcap_sctp_assoc(tvbuff_t *, proto_tree *, int); |
128 | | static int dissect_ppcap_payload_data(tvbuff_t *, packet_info *, proto_tree *, int, proto_tree *, payload_type_type); |
129 | | |
130 | | /*Dissecting the function PPCAP */ |
131 | | |
132 | | static int |
133 | | dissect_ppcap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
134 | 0 | { |
135 | 0 | proto_item *ti; |
136 | 0 | proto_tree *ppcap_tree, *ppcap_tree1; |
137 | 0 | uint16_t msg_type; |
138 | 0 | unsigned offset = 0; |
139 | 0 | payload_type_type payload_type = PPCAP_UNKNOWN; |
140 | | |
141 | | /* Do not carry the SSN over from another packet */ |
142 | 0 | ssn = INVALID_SSN; |
143 | |
|
144 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPCAP"); |
145 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
146 | |
|
147 | 0 | ti = proto_tree_add_item(tree, proto_ppcap, tvb, 0, -1, ENC_NA); |
148 | 0 | ppcap_tree = proto_item_add_subtree(ti, ett_ppcap); |
149 | |
|
150 | 0 | while (tvb_reported_length_remaining(tvb, offset) > 0) |
151 | 0 | { |
152 | 0 | msg_type = tvb_get_ntohs(tvb, offset); |
153 | 0 | ppcap_tree1 = proto_tree_add_subtree(ppcap_tree, tvb, offset, 2, ett_ppcap1, NULL, |
154 | 0 | val_to_str(pinfo->pool, msg_type, payload_tag_values, "Unknown PPCAP message type (%u)")); |
155 | 0 | offset = offset + 2; |
156 | 0 | switch (msg_type) { |
157 | 0 | case 1: |
158 | 0 | payload_type = PPCAP_UNKNOWN; |
159 | 0 | offset = dissect_ppcap_payload_type(tvb, pinfo, ppcap_tree1, offset, &payload_type); |
160 | 0 | break; |
161 | 0 | case 2: |
162 | 0 | offset = dissect_ppcap_payload_data(tvb, pinfo, ppcap_tree1, offset, tree, payload_type); |
163 | 0 | break; |
164 | 0 | case 3: |
165 | 0 | offset = dissect_ppcap_source_address(tvb, pinfo, ppcap_tree1, offset); |
166 | 0 | break; |
167 | 0 | case 4: |
168 | 0 | offset = dissect_ppcap_destination_address(tvb, pinfo, ppcap_tree1, offset); |
169 | 0 | break; |
170 | 0 | case 5: |
171 | 0 | offset = dissect_ppcap_local_port(tvb,ppcap_tree1, offset); |
172 | 0 | break; |
173 | 0 | case 6: |
174 | 0 | offset = dissect_ppcap_remote_port(tvb,ppcap_tree1, offset); |
175 | 0 | break; |
176 | 0 | case 7: |
177 | 0 | offset = dissect_ppcap_transport_protocol(tvb,ppcap_tree1, offset); |
178 | 0 | break; |
179 | 0 | case 8: |
180 | 0 | offset = dissect_ppcap_sctp_assoc(tvb, ppcap_tree1, offset); |
181 | 0 | break; |
182 | 0 | case 256: |
183 | 0 | offset = dissect_ppcap_info_string(tvb, ppcap_tree1, offset); |
184 | 0 | break; |
185 | 0 | } |
186 | 0 | } |
187 | 0 | return tvb_captured_length(tvb); |
188 | 0 | } |
189 | | |
190 | | |
191 | | /* Dissecting the function Payload type to compare the protocol type */ |
192 | | |
193 | | /* |
194 | | ******************************************************* |
195 | | * Payload Type * |
196 | | * * |
197 | | ******************************************************* |
198 | | */ |
199 | | |
200 | | |
201 | | |
202 | | static int |
203 | | dissect_ppcap_payload_type(tvbuff_t *tvb, packet_info *pinfo, proto_tree * ppcap_tree1, int offset, payload_type_type *payload_type) |
204 | 0 | { |
205 | 0 | char *string; |
206 | 0 | uint16_t msg_len =0; |
207 | 0 | msg_len = tvb_get_ntohs(tvb, offset); |
208 | 0 | proto_tree_add_item( ppcap_tree1, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN); |
209 | 0 | offset = offset + 2; |
210 | 0 | string = (char*)tvb_get_string_enc(pinfo->pool, tvb, offset, msg_len, ENC_UTF_8|ENC_NA); |
211 | 0 | if (strcmp(string,"mtp3") == 0) { |
212 | 0 | *payload_type = PPCAP_MTP3; |
213 | 0 | }else if (strcmp(string,"tcap") == 0) { |
214 | 0 | *payload_type = PPCAP_TCAP; |
215 | 0 | }else if (strcmp(string,"bssap") == 0) { |
216 | 0 | *payload_type = PPCAP_BSSAP; |
217 | 0 | }else if (strcmp(string,"ranap") == 0) { |
218 | 0 | *payload_type = PPCAP_RANAP; |
219 | 0 | }else if (strcmp(string,"h248") == 0) { |
220 | 0 | *payload_type = PPCAP_H248; |
221 | 0 | }else if (strcmp(string,"sip") == 0) { |
222 | 0 | *payload_type = PPCAP_SIP; |
223 | 0 | }else if (strcmp(string,"sccp") == 0) { |
224 | 0 | *payload_type = PPCAP_SCCP; |
225 | 0 | }else if (strcmp(string, "sgsap") == 0) { |
226 | 0 | *payload_type = PPCAP_SGSAP; |
227 | 0 | }else if (strcmp(string, "gtpv2") == 0) { |
228 | 0 | *payload_type = PPCAP_GTPV2; |
229 | 0 | } |
230 | |
|
231 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_payload_type, tvb, offset, msg_len, ENC_UTF_8); |
232 | |
|
233 | 0 | msg_len = WS_ROUNDUP_4(msg_len); |
234 | 0 | offset += msg_len; |
235 | 0 | return offset; |
236 | 0 | } |
237 | | |
238 | | /* Dissecting the function Source Address */ |
239 | | |
240 | | /* |
241 | | |
242 | | ******************************************************* |
243 | | * Reserved * Address Type * |
244 | | * * * |
245 | | ******************************************************* |
246 | | * Address Value * |
247 | | * * |
248 | | ******************************************************* |
249 | | */ |
250 | | |
251 | | static int |
252 | | dissect_ppcap_source_address(tvbuff_t *tvb, packet_info *pinfo, proto_tree * ppcap_tree1, int offset) |
253 | 0 | { |
254 | 0 | int key1; |
255 | 0 | uint16_t msg_len; |
256 | 0 | msg_len = tvb_get_ntohs(tvb, offset); |
257 | 0 | proto_tree_add_item( ppcap_tree1, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN); |
258 | 0 | offset = offset + 2; |
259 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_reserved, tvb, offset, 2, ENC_BIG_ENDIAN); |
260 | 0 | offset += 2; |
261 | |
|
262 | 0 | key1 = tvb_get_ntohs(tvb, offset); |
263 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN); |
264 | 0 | offset += 2; |
265 | |
|
266 | 0 | if (key1 == 1) |
267 | 0 | { |
268 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn, tvb, offset, 1, ENC_BIG_ENDIAN); |
269 | 0 | offset += 1; |
270 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_spc, tvb, offset, 3, ENC_BIG_ENDIAN); |
271 | | /*src_addr1 = (uint32_t )tvb_get_ntoh24(tvb, offset);*/ |
272 | 0 | mtp3_addr_opc = wmem_new0(pinfo->pool, mtp3_addr_pc_t); |
273 | 0 | mtp3_addr_opc->pc = (uint32_t )tvb_get_ntoh24(tvb, offset); |
274 | 0 | mtp3_addr_opc->type = ITU_STANDARD; |
275 | 0 | mtp3_addr_opc->ni = 0; |
276 | | /*set_address(&pinfo->net_src, ss7pc_address_type, sizeof(mtp3_addr_pc_t), (uint8_t *) mtp3_addr_opc);*/ |
277 | 0 | set_address(&pinfo->src, ss7pc_address_type, sizeof(mtp3_addr_pc_t), (uint8_t *) mtp3_addr_opc); |
278 | 0 | msg_len = WS_ROUNDUP_4(msg_len); |
279 | |
|
280 | 0 | offset += msg_len-1; |
281 | 0 | return offset; |
282 | 0 | } |
283 | 0 | else if (key1 == 2) |
284 | 0 | { |
285 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_opc, tvb, offset, msg_len, ENC_BIG_ENDIAN); |
286 | | |
287 | | /*src_addr1 = (uint32_t )tvb_get_ntoh24(tvb, offset);*/ |
288 | 0 | mtp3_addr_opc = wmem_new0(pinfo->pool, mtp3_addr_pc_t); |
289 | 0 | mtp3_addr_opc->pc = tvb_get_ntohl(tvb, offset); |
290 | 0 | mtp3_addr_opc->type = ITU_STANDARD; |
291 | 0 | mtp3_addr_opc->ni = 0; |
292 | 0 | set_address(&pinfo->src, ss7pc_address_type, sizeof(mtp3_addr_pc_t), (uint8_t *) mtp3_addr_opc); |
293 | 0 | } |
294 | 0 | else if (key1 == 3) |
295 | 0 | { |
296 | 0 | if (msg_len%16 != 0) |
297 | 0 | { |
298 | |
|
299 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_source_ip_address1, tvb, offset, msg_len, ENC_BIG_ENDIAN); |
300 | 0 | set_address_tvb(&pinfo->net_src, AT_IPv4, 4, tvb, offset); |
301 | 0 | copy_address_shallow(&pinfo->src, &pinfo->net_src); |
302 | 0 | } |
303 | 0 | else |
304 | 0 | { |
305 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_source_ip_address2, tvb, offset, msg_len, ENC_NA); |
306 | 0 | if (msg_len >= 16) { |
307 | 0 | set_address_tvb(&pinfo->net_src, AT_IPv6, 16, tvb, offset); |
308 | 0 | copy_address_shallow(&pinfo->src, &pinfo->net_src); |
309 | 0 | } |
310 | 0 | } |
311 | 0 | } |
312 | | |
313 | 0 | else if (key1 == 4) |
314 | | |
315 | 0 | { |
316 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_source_nodeid, tvb, offset, msg_len, ENC_ASCII); |
317 | 0 | if (msg_len) { |
318 | | /* AT_STRINGZ needs a NUL terminated copy, not packet bytes */ |
319 | 0 | char *nodeid = (char *)tvb_get_string_enc(pinfo->pool, tvb, offset, msg_len, ENC_UTF_8); |
320 | 0 | set_address(&pinfo->net_src, AT_STRINGZ, (int)strlen(nodeid) + 1, nodeid); |
321 | 0 | copy_address_shallow(&pinfo->src, &pinfo->net_src); |
322 | 0 | } |
323 | 0 | } |
324 | 0 | msg_len = WS_ROUNDUP_4(msg_len); |
325 | 0 | offset += msg_len; |
326 | 0 | return offset; |
327 | 0 | } |
328 | | |
329 | | /* Dissecting the function Destination Address */ |
330 | | |
331 | | /* |
332 | | ******************************************************* |
333 | | * Reserved * Address Type * |
334 | | * * * |
335 | | ******************************************************* |
336 | | * Address Value * |
337 | | * * |
338 | | ******************************************************* |
339 | | */ |
340 | | |
341 | | |
342 | | static int |
343 | | dissect_ppcap_destination_address(tvbuff_t *tvb, packet_info * pinfo, proto_tree * ppcap_tree1, int offset) |
344 | 0 | { |
345 | 0 | int key2; |
346 | 0 | uint16_t msg_len; |
347 | 0 | msg_len = tvb_get_ntohs(tvb, offset); |
348 | 0 | proto_tree_add_item( ppcap_tree1, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN); |
349 | 0 | offset = offset + 2; |
350 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_destreserved, tvb, offset, 2, ENC_BIG_ENDIAN); |
351 | 0 | offset += 2; |
352 | |
|
353 | 0 | key2 = tvb_get_ntohs(tvb, offset); |
354 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_address_type, tvb, offset, 2, ENC_BIG_ENDIAN); |
355 | 0 | offset += 2; |
356 | |
|
357 | 0 | if (key2 == 1) |
358 | 0 | { |
359 | 0 | ssn = tvb_get_uint8(tvb, offset); |
360 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_ssn1, tvb, offset, 1, ENC_BIG_ENDIAN); |
361 | 0 | offset += 1; |
362 | |
|
363 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_spc1, tvb, offset, 3, ENC_BIG_ENDIAN); |
364 | | |
365 | | /*dst_addr1 = (uint32_t )tvb_get_ntoh24(tvb, offset);*/ |
366 | 0 | mtp3_addr_dpc = wmem_new0(pinfo->pool, mtp3_addr_pc_t); |
367 | 0 | mtp3_addr_dpc->pc = (uint32_t)tvb_get_ntoh24(tvb, offset); |
368 | 0 | mtp3_addr_dpc->type = ITU_STANDARD; |
369 | 0 | mtp3_addr_dpc->ni = 0; |
370 | 0 | set_address(&pinfo->dst, ss7pc_address_type, sizeof(mtp3_addr_pc_t), (uint8_t *) mtp3_addr_dpc); |
371 | |
|
372 | 0 | msg_len = WS_ROUNDUP_4(msg_len); |
373 | |
|
374 | 0 | offset += msg_len-1; |
375 | 0 | return offset; |
376 | |
|
377 | 0 | } |
378 | 0 | else if (key2 == 2) |
379 | 0 | { |
380 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_dpc, tvb, offset, 4, ENC_BIG_ENDIAN); |
381 | | |
382 | | /*dst_addr1 = (uint32_t )tvb_get_ntoh24(tvb, offset);*/ |
383 | 0 | mtp3_addr_dpc = wmem_new0(pinfo->pool, mtp3_addr_pc_t); |
384 | 0 | mtp3_addr_dpc->pc = tvb_get_ntohl(tvb, offset); |
385 | 0 | mtp3_addr_dpc->type = ITU_STANDARD; |
386 | 0 | mtp3_addr_dpc->ni = 0; |
387 | 0 | set_address(&pinfo->dst, ss7pc_address_type, sizeof(mtp3_addr_pc_t), (uint8_t *) mtp3_addr_dpc); |
388 | 0 | } |
389 | 0 | else if (key2 == 3) |
390 | 0 | { |
391 | 0 | if (msg_len%16 != 0) |
392 | 0 | { |
393 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_destination_ip_address1, tvb, offset, msg_len, ENC_BIG_ENDIAN); |
394 | 0 | set_address_tvb(&pinfo->net_dst, AT_IPv4, 4, tvb, offset); |
395 | 0 | copy_address_shallow(&pinfo->dst, &pinfo->net_dst); |
396 | 0 | } |
397 | 0 | else |
398 | 0 | { |
399 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_destination_ip_address2, tvb, offset, msg_len, ENC_NA); |
400 | 0 | if (msg_len >= 16) { |
401 | 0 | set_address_tvb(&pinfo->net_dst, AT_IPv6, 16, tvb, offset); |
402 | 0 | copy_address_shallow(&pinfo->dst, &pinfo->net_dst); |
403 | 0 | } |
404 | 0 | } |
405 | 0 | } |
406 | | |
407 | 0 | else if (key2 == 4) |
408 | 0 | { |
409 | 0 | const uint8_t *string; |
410 | 0 | proto_tree_add_item_ret_string(ppcap_tree1, hf_ppcap_destination_nodeid, tvb, offset, msg_len, ENC_UTF_8|ENC_NA, pinfo->pool, &string); |
411 | 0 | if (msg_len && string) { |
412 | 0 | set_address(&pinfo->net_dst, AT_STRINGZ, (int)strlen((const char *)string) + 1, string); |
413 | 0 | copy_address_shallow(&pinfo->dst, &pinfo->net_dst); |
414 | 0 | } |
415 | 0 | } |
416 | | |
417 | 0 | msg_len = WS_ROUNDUP_4(msg_len); |
418 | |
|
419 | 0 | offset += msg_len; |
420 | |
|
421 | 0 | return offset; |
422 | 0 | } |
423 | | |
424 | | /* Dissecting the function Info String */ |
425 | | |
426 | | /* |
427 | | ******************************************************* |
428 | | * Info * |
429 | | * * |
430 | | ******************************************************* |
431 | | */ |
432 | | |
433 | | static int |
434 | | dissect_ppcap_info_string(tvbuff_t *tvb, proto_tree * ppcap_tree1, int offset) |
435 | 0 | { |
436 | 0 | uint16_t msg_len; |
437 | 0 | msg_len = tvb_get_ntohs(tvb, offset); |
438 | 0 | proto_tree_add_item( ppcap_tree1, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN); |
439 | 0 | offset = offset + 2; |
440 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_info, tvb, offset, msg_len, ENC_ASCII); |
441 | |
|
442 | 0 | msg_len = WS_ROUNDUP_4(msg_len); |
443 | 0 | offset += msg_len; |
444 | 0 | return offset; |
445 | 0 | } |
446 | | |
447 | | /* Dissecting the function Local Port */ |
448 | | |
449 | | /* |
450 | | ******************************************************* |
451 | | * Local Port * |
452 | | * * |
453 | | ******************************************************* |
454 | | */ |
455 | | static int |
456 | | dissect_ppcap_local_port(tvbuff_t *tvb,proto_tree * ppcap_tree1, int offset) |
457 | 0 | { |
458 | 0 | proto_tree_add_item(ppcap_tree1,hf_ppcap_local_port,tvb,offset,2,ENC_BIG_ENDIAN); |
459 | 0 | offset = offset+6; /*Adding offset of filler bytes without text*/ |
460 | 0 | return offset; |
461 | 0 | } |
462 | | |
463 | | /* Dissecting the function Remote Port */ |
464 | | |
465 | | /* |
466 | | ******************************************************* |
467 | | * Remote Port * |
468 | | * * |
469 | | ******************************************************* |
470 | | */ |
471 | | |
472 | | static int |
473 | | dissect_ppcap_remote_port(tvbuff_t *tvb,proto_tree * ppcap_tree1, int offset) |
474 | 0 | { |
475 | 0 | proto_tree_add_item(ppcap_tree1,hf_ppcap_remote_port,tvb,offset,2,ENC_BIG_ENDIAN); |
476 | 0 | offset = offset+6; /*Adding offset of filler bytes without text*/ |
477 | 0 | return offset; |
478 | 0 | } |
479 | | |
480 | | /* Dissecting the function TCP SIP Message */ |
481 | | |
482 | | /* |
483 | | ******************************************************* |
484 | | * Transport protocol * |
485 | | * * |
486 | | ******************************************************* |
487 | | */ |
488 | | |
489 | | static int |
490 | | dissect_ppcap_transport_protocol(tvbuff_t *tvb,proto_tree * ppcap_tree1, int offset) |
491 | 0 | { |
492 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN); |
493 | 0 | offset = offset + 2; |
494 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_transport_prot, tvb, offset, 4, ENC_ASCII); |
495 | 0 | offset += 4; |
496 | |
|
497 | 0 | return offset; |
498 | 0 | } |
499 | | |
500 | | static int |
501 | | dissect_ppcap_sctp_assoc(tvbuff_t *tvb _U_, proto_tree * tree _U_, int offset) |
502 | 0 | { |
503 | 0 | uint16_t length; |
504 | 0 | proto_tree_add_item_ret_uint16(tree, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN, &length); |
505 | 0 | offset += 2; |
506 | |
|
507 | 0 | proto_tree_add_item(tree, hf_ppcap_sctp_assoc, tvb, offset, length, ENC_ASCII); |
508 | | |
509 | | /* The string can be 1 -15 characters long but the IE is padded to 16 bytes*/ |
510 | |
|
511 | 0 | return offset + 16; |
512 | 0 | } |
513 | | |
514 | | /* Dissecting the function Payload Data to call the protocol that based upon the type decided in the Payload Type */ |
515 | | |
516 | | /* |
517 | | ******************************************************* |
518 | | * Payload Data * |
519 | | * * |
520 | | ******************************************************* |
521 | | */ |
522 | | |
523 | | |
524 | | static int |
525 | | dissect_ppcap_payload_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree * ppcap_tree1, int offset, proto_tree *tree, payload_type_type payload_type) |
526 | 0 | { |
527 | 0 | tvbuff_t *next_tvb; |
528 | 0 | uint16_t msg_len; |
529 | 0 | msg_len = tvb_get_ntohs(tvb, offset); |
530 | 0 | proto_tree_add_item( ppcap_tree1, hf_ppcap_length, tvb, offset, 2, ENC_BIG_ENDIAN); |
531 | 0 | offset = offset + 2; |
532 | 0 | proto_tree_add_item(ppcap_tree1, hf_ppcap_payload_data, tvb, offset, msg_len, ENC_NA); |
533 | |
|
534 | 0 | msg_len = WS_ROUNDUP_4(msg_len); |
535 | |
|
536 | 0 | next_tvb = tvb_new_subset_remaining(tvb, offset); |
537 | |
|
538 | 0 | switch (payload_type) { |
539 | 0 | case PPCAP_MTP3: |
540 | 0 | call_dissector(mtp3_handle, next_tvb, pinfo, tree); /* calling the MTP3 handle */ |
541 | 0 | break; |
542 | 0 | case PPCAP_TCAP: |
543 | | /* |
544 | | * The protocol which runs on TCAP takes the SSN value from the SCCP layer which is missing in this case. |
545 | | * So we have made code changes for TCAP handle as below for taking the SSN value from ppcap. |
546 | | */ |
547 | 0 | if (ssn != INVALID_SSN && dissector_try_uint(sccp_ssn_dissector_table, ssn, next_tvb, pinfo, tree)) { |
548 | 0 | return offset+msg_len; |
549 | 0 | }else{ |
550 | 0 | call_dissector(tcap_handle, next_tvb, pinfo, tree); /* calling the TCAP handle */ |
551 | 0 | } |
552 | 0 | break; |
553 | 0 | case PPCAP_BSSAP: |
554 | 0 | call_dissector(bssap_handle, next_tvb, pinfo, tree); /* calling the BSSAP handle */ |
555 | 0 | break; |
556 | 0 | case PPCAP_RANAP: |
557 | 0 | call_dissector(ranap_handle, next_tvb, pinfo, tree); /* calling the RANAP handle */ |
558 | 0 | break; |
559 | 0 | case PPCAP_H248: |
560 | 0 | call_dissector(h248_handle, next_tvb, pinfo, tree); /* calling the H248 handle */ |
561 | 0 | break; |
562 | 0 | case PPCAP_SIP: |
563 | 0 | call_dissector(sip_handle, next_tvb, pinfo, tree); /* calling the SIP handle */ |
564 | 0 | break; |
565 | 0 | case PPCAP_SCCP: |
566 | 0 | call_dissector(sccp_handle, next_tvb, pinfo, tree); /* calling the SCCP handle */ |
567 | 0 | break; |
568 | 0 | case PPCAP_SGSAP: |
569 | 0 | call_dissector(sgsap_handle, next_tvb, pinfo, tree); /* calling the SGSAP handle */ |
570 | 0 | break; |
571 | 0 | case PPCAP_GTPV2: |
572 | 0 | call_dissector(gtpv2_handle, next_tvb, pinfo, tree); /* calling the GTPv2 handle */ |
573 | 0 | break; |
574 | 0 | default: |
575 | 0 | call_data_dissector(next_tvb, pinfo, tree); /* calling the DATA handle */ |
576 | 0 | break; |
577 | 0 | } |
578 | | |
579 | 0 | offset += msg_len; |
580 | 0 | return offset; |
581 | 0 | } |
582 | | |
583 | | /* Registering the hf variables */ |
584 | | |
585 | | void proto_register_ppcap(void) |
586 | 16 | { |
587 | | |
588 | 16 | static hf_register_info hf[] = { |
589 | 16 | { &hf_ppcap_length, |
590 | 16 | { "Length", "ppcap.length", |
591 | 16 | FT_UINT16, BASE_DEC, NULL, 0x00, NULL, HFILL}}, |
592 | 16 | { &hf_ppcap_payload_type, |
593 | 16 | { "Payload Type", "ppcap.payload_type", FT_STRING, |
594 | 16 | BASE_NONE, NULL, 0x0 , NULL, HFILL}}, |
595 | 16 | { &hf_ppcap_reserved, |
596 | 16 | { "Reserved", "ppcap.reserved", FT_UINT16, |
597 | 16 | BASE_DEC, NULL, 0x00, NULL, HFILL}}, |
598 | 16 | { &hf_ppcap_address_type, |
599 | 16 | { "Address Type", "ppcap.address_type", FT_UINT16, |
600 | 16 | BASE_DEC, VALS(address_type_values), 0x00 , NULL, HFILL}}, |
601 | | #if 0 |
602 | | { &hf_ppcap_source_address_type, |
603 | | { "Source Address Type", "ppcap.source_address_type", FT_UINT16, |
604 | | BASE_DEC, VALS(address_type_values), 0x00 , NULL, HFILL}}, |
605 | | #endif |
606 | 16 | { &hf_ppcap_ssn, |
607 | 16 | { "SSN", "ppcap.ssn", FT_UINT16, |
608 | 16 | BASE_DEC, NULL, 0x00, NULL, HFILL}}, |
609 | 16 | { &hf_ppcap_spc, |
610 | 16 | {"OPC", "ppcap.spc", FT_UINT24, |
611 | 16 | BASE_DEC, NULL, 0x00, NULL, HFILL}}, |
612 | 16 | { &hf_ppcap_opc, |
613 | 16 | { "OPC", "ppcap.opc", FT_UINT16, |
614 | 16 | BASE_DEC, NULL, 0x00, NULL, HFILL}}, |
615 | 16 | { &hf_ppcap_source_ip_address1, |
616 | 16 | { "Source IP Address", "ppcap.source_ip_address1", FT_IPv4, |
617 | 16 | BASE_NONE, NULL, 0x00, NULL, HFILL}}, |
618 | 16 | { &hf_ppcap_source_ip_address2, |
619 | 16 | { "Source IP Address", "ppcap.source_ip_address2", FT_IPv6, |
620 | 16 | BASE_NONE, NULL, 0x00, NULL, HFILL}}, |
621 | 16 | { &hf_ppcap_destreserved, |
622 | 16 | { "Reserved", "ppcap.destreserved", FT_UINT16, |
623 | 16 | BASE_DEC, NULL, 0x00, NULL, HFILL}}, |
624 | | #if 0 |
625 | | { &hf_ppcap_destination_address_type, |
626 | | { "Destination Address Type", "ppcap.destination_address_type", FT_UINT16, |
627 | | BASE_DEC, VALS(address_type_values), 0x00, NULL, HFILL}}, |
628 | | #endif |
629 | 16 | { &hf_ppcap_ssn1, |
630 | 16 | { "SSN", "ppcap.ssn1", FT_UINT8, |
631 | 16 | BASE_DEC, NULL, 0x00, NULL, HFILL}}, |
632 | 16 | { &hf_ppcap_spc1, |
633 | 16 | { "DPC", "ppcap.spc1", FT_UINT24, |
634 | 16 | BASE_DEC, NULL, 0x00, NULL, HFILL}}, |
635 | 16 | { &hf_ppcap_dpc, |
636 | 16 | { "DPC", "ppcap.dpc", FT_UINT32, |
637 | 16 | BASE_DEC, NULL, 0x00, NULL, HFILL}}, |
638 | 16 | { &hf_ppcap_destination_ip_address1, |
639 | 16 | { "Destination IP Address", "ppcap.destination_ip_address1", FT_IPv4, |
640 | 16 | BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
641 | 16 | { &hf_ppcap_destination_ip_address2, |
642 | 16 | { "Destination IP Address", "ppcap.destination_ip_address2", FT_IPv6, |
643 | 16 | BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
644 | 16 | { &hf_ppcap_source_nodeid, |
645 | 16 | { "Source Node ID", "ppcap.source_nodeid", FT_STRING, |
646 | 16 | BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
647 | 16 | { &hf_ppcap_destination_nodeid, |
648 | 16 | { "Destination Node ID", "ppcap.destination_address", FT_STRING, |
649 | 16 | BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
650 | 16 | { &hf_ppcap_info, |
651 | 16 | { "Info", "ppcap.info", FT_STRING, |
652 | 16 | BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
653 | 16 | { &hf_ppcap_payload_data, |
654 | 16 | { "Payload Data", "ppcap.payload_data", FT_BYTES, |
655 | 16 | BASE_NONE, NULL, 0x0, NULL, HFILL}}, |
656 | 16 | { &hf_ppcap_local_port, |
657 | 16 | { "Local Port", "ppcap.local_port", FT_UINT16, |
658 | 16 | BASE_DEC, NULL, 0x00, NULL, HFILL}}, |
659 | 16 | { &hf_ppcap_remote_port, |
660 | 16 | { "Remote Port", "ppcap.remote_port", FT_UINT16, |
661 | 16 | BASE_DEC, NULL, 0x00, NULL, HFILL}}, |
662 | 16 | { &hf_ppcap_transport_prot, |
663 | 16 | { "Transport Protocol", "ppcap.transport_prot", FT_STRING, |
664 | 16 | BASE_NONE, NULL, 0x0 , NULL, HFILL}}, |
665 | 16 | { &hf_ppcap_sctp_assoc, |
666 | 16 | { "SCTP Association ID", "ppcap.sctp_assoc", FT_STRING, |
667 | 16 | BASE_NONE, NULL, 0x0 , NULL, HFILL } }, |
668 | 16 | }; |
669 | | |
670 | 16 | static int *ett[]= { |
671 | 16 | &ett_ppcap, |
672 | 16 | &ett_ppcap1, |
673 | 16 | &ett_ppcap_new, |
674 | 16 | }; |
675 | 16 | proto_ppcap = proto_register_protocol("Proprietary PCAP", "PPCAP", "ppcap"); |
676 | 16 | proto_register_field_array(proto_ppcap , hf , array_length(hf)); |
677 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
678 | 16 | register_dissector("ppcap", dissect_ppcap, proto_ppcap); |
679 | | |
680 | 16 | } |
681 | | |
682 | | void proto_reg_handoff_ppcap(void) |
683 | 16 | { |
684 | 16 | ppcap_handle = find_dissector_add_dependency("ppcap", proto_ppcap); |
685 | 16 | mtp3_handle = find_dissector_add_dependency("mtp3", proto_ppcap); /* calling the protocol MTP3 */ |
686 | 16 | tcap_handle = find_dissector_add_dependency("tcap", proto_ppcap); /* calling the protocol TCAP */ |
687 | 16 | bssap_handle = find_dissector_add_dependency("bssap", proto_ppcap); /* calling the protocol BSSAP */ |
688 | 16 | ranap_handle = find_dissector_add_dependency("ranap", proto_ppcap); /* calling the protocol RANAP */ |
689 | 16 | h248_handle = find_dissector_add_dependency("h248", proto_ppcap); /* calling the protocol H248 */ |
690 | 16 | sip_handle = find_dissector_add_dependency("sip", proto_ppcap); /* calling the protocol SIP */ |
691 | 16 | sccp_handle = find_dissector_add_dependency("sccp", proto_ppcap); /* calling the protocol SCCP */ |
692 | 16 | sgsap_handle = find_dissector_add_dependency("sgsap", proto_ppcap); /* calling the protocol SGSAP */ |
693 | 16 | gtpv2_handle = find_dissector_add_dependency("gtpv2", proto_ppcap); /* calling the protocol GTPv2 */ |
694 | | |
695 | 16 | sccp_ssn_dissector_table = find_dissector_table("sccp.ssn"); |
696 | | |
697 | 16 | ss7pc_address_type = address_type_get_by_name("AT_SS7PC"); |
698 | 16 | } |
699 | | |
700 | | /* |
701 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
702 | | * |
703 | | * Local variables: |
704 | | * c-basic-offset: 8 |
705 | | * tab-width: 8 |
706 | | * indent-tabs-mode: t |
707 | | * End: |
708 | | * |
709 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
710 | | * :indentSize=8:tabSize=8:noTabs=false: |
711 | | */ |