/src/wireshark/epan/dissectors/packet-pdc.c
Line | Count | Source |
1 | | /* packet-pdc.c |
2 | | * Routines for PDC dissection |
3 | | * Copyright 2014, Antony Bridle <antony.bridle@nats.co.uk> |
4 | | * |
5 | | * Wireshark - Network traffic analyzer |
6 | | * By Gerald Combs <gerald@wireshark.org> |
7 | | * Copyright 1998 Gerald Combs |
8 | | * |
9 | | * SPDX-License-Identifier: GPL-2.0-or-later |
10 | | */ |
11 | | |
12 | | #include "config.h" |
13 | | |
14 | | #include <epan/packet.h> |
15 | | #include "packet-tcp.h" |
16 | | |
17 | | void proto_register_pdc(void); |
18 | | void proto_reg_handoff_pdc(void); |
19 | | |
20 | | /* PDC version */ |
21 | | #define PDC_VERSION 2 |
22 | | |
23 | 0 | #define SIMPDU 1 |
24 | 0 | #define RSMPDU 2 |
25 | 0 | #define DRMPDU 3 |
26 | 0 | #define DTMPDU 4 |
27 | 0 | #define ADMPDU 5 |
28 | 0 | #define EDMPDU 6 |
29 | 0 | #define AKMPDU 8 |
30 | | |
31 | | /*Variable length Parameter Codes*/ |
32 | 0 | #define PARAM_CODE_VERSION 2 |
33 | 0 | #define PARAM_CODE_REFERENCES 3 |
34 | 0 | #define PARAM_CODE_TRANSPORT 4 |
35 | | |
36 | | /* required for the TCP split packet combining */ |
37 | | #define PDC_MSG_SIZE_FIELD_LENGTH 2 /* minimum amount of data to find out how big the split packet should be when recombined */ |
38 | | #define FRAME_HEADER_LEN 8 |
39 | | |
40 | | /* global handle for our dissector */ |
41 | | static dissector_handle_t pdc_tcp_handle; |
42 | | |
43 | | /* global handle for calling asterix decoder if required */ |
44 | | static dissector_handle_t asterix_handle; |
45 | | |
46 | | static int proto_pdc; |
47 | | |
48 | | /*HF Declarations*/ |
49 | | static int hf_pdc_len; |
50 | | static int hf_pdc_mpdu_code; |
51 | | static int hf_pdc_credit; |
52 | | static int hf_pdc_simpdu_state; |
53 | | static int hf_pdc_yr_admu_nr; |
54 | | static int hf_pdc_akmpdu_mns; |
55 | | static int hf_pdc_akmpdu_cdt; |
56 | | static int hf_pdc_simpdu_var; |
57 | | static int hf_pdc_simpdu_var_len; |
58 | | static int hf_pdc_simpdu_param; |
59 | | static int hf_pdc_simpdu_var_version; |
60 | | static int hf_pdc_simpdu_var_REFSRC; |
61 | | static int hf_pdc_simpdu_var_REFDEST; |
62 | | static int hf_pdc_simpdu_var_TSEL; |
63 | | static int hf_pdc_drmpdu_abort; |
64 | | static int hf_pdc_drmpdu_reason; |
65 | | static int hf_pdc_drmpdu_mode; |
66 | | static int hf_pdc_drmpdu_init; |
67 | | static int hf_pdc_dtmpdu_user_size; |
68 | | static int hf_pdc_admpdu_admpdunr; |
69 | | static int hf_pdc_admpdu_size; |
70 | | |
71 | | /*Tree Declarations*/ |
72 | | static int ett_pdc; |
73 | | static int ett_pdc_simpdu_var; |
74 | | |
75 | | |
76 | | /*Value String Declarations*/ |
77 | | static const value_string valstr_simpdu_state[] = { |
78 | | { 1, "Operational" }, |
79 | | { 2, "Standby" }, |
80 | | { 3, "Master" }, |
81 | | { 4, "Slave" }, |
82 | | { 5, "Single" }, |
83 | | { 0, NULL } |
84 | | }; |
85 | | |
86 | | static const value_string valstr_simpdu_param[] = { |
87 | | { 2, "Version Number" }, |
88 | | { 3, "References" }, |
89 | | { 4, "Transport Selector" }, |
90 | | { 0, NULL } |
91 | | }; |
92 | | |
93 | | static const value_string valstr_mpdus[] = { |
94 | | { 1, "State Information" }, |
95 | | { 2, "Request State" }, |
96 | | { 3, "Disconnect Request" }, |
97 | | { 4, "Data" }, |
98 | | { 5, "Acknowledged Data" }, |
99 | | { 6, "Expedited Data" }, |
100 | | { 8, "Data Acknowledgement" }, |
101 | | { 0, NULL } |
102 | | }; |
103 | | |
104 | | static const value_string valstr_drmpdu_abort[] = { |
105 | | { 0, "Orderly Release" }, |
106 | | { 1, "Abortive Release" }, |
107 | | { 0, NULL } |
108 | | }; |
109 | | |
110 | | static const value_string valstr_drmpdu_mode[] = { |
111 | | { 0, "Node Shutdown" }, |
112 | | { 7, "PDC Release"}, |
113 | | { 0, NULL } |
114 | | }; |
115 | | |
116 | | static const value_string valstr_drmpdu_initatior[] = { |
117 | | { 0, "Server" }, |
118 | | { 15, "Client"}, |
119 | | { 0, NULL } |
120 | | }; |
121 | | |
122 | | static const value_string valstr_drmpdu_reason[] = { |
123 | | { 0, "Reason Not Specified" }, |
124 | | { 1, "Normal Disconnect Initiated by the MS-User" }, |
125 | | { 2, "Protocol Error" }, |
126 | | { 3, "Connection Request Refused" }, |
127 | | { 4, "The Remote Operational MS Entity Does Not Respond" }, |
128 | | { 5, "The Protocol Version Is Not Supported" }, |
129 | | { 6, "Mismatched References" }, |
130 | | { 0, NULL } |
131 | | }; |
132 | | |
133 | | /* start of functions here */ |
134 | | static int dissect_simpdu(tvbuff_t *tvb, proto_tree *tree, uint16_t offset, uint8_t lenIndicator) |
135 | 0 | { |
136 | 0 | int bytesProcessed; |
137 | 0 | uint8_t paramCode; |
138 | 0 | proto_item *simpduItem; |
139 | 0 | proto_tree *simpduVarTree; |
140 | 0 | proto_tree *simpduVarTree1; |
141 | |
|
142 | 0 | bytesProcessed = 0; |
143 | | |
144 | | /*Add the Credit allocation*/ |
145 | 0 | proto_tree_add_item(tree, hf_pdc_credit, tvb, offset, 1, ENC_BIG_ENDIAN); |
146 | 0 | bytesProcessed += 1; |
147 | | |
148 | | /*Add the State*/ |
149 | 0 | proto_tree_add_item(tree, hf_pdc_simpdu_state, tvb, offset + bytesProcessed , 1, ENC_BIG_ENDIAN); |
150 | 0 | bytesProcessed += 1; |
151 | | |
152 | | /*Add the YR-ADMU-NR*/ |
153 | 0 | proto_tree_add_item(tree, hf_pdc_yr_admu_nr, tvb, offset + bytesProcessed , 4, ENC_BIG_ENDIAN); |
154 | 0 | bytesProcessed += 4; |
155 | | |
156 | | /*Determine what's in the variable part*/ |
157 | 0 | if (lenIndicator > 7) |
158 | 0 | { |
159 | | /*Add the Variable Length Tree*/ |
160 | 0 | simpduItem = proto_tree_add_item (tree, hf_pdc_simpdu_var, tvb, offset + bytesProcessed, lenIndicator - 7, ENC_NA); |
161 | 0 | simpduVarTree = proto_item_add_subtree (simpduItem, ett_pdc_simpdu_var); |
162 | |
|
163 | 0 | while ((offset + bytesProcessed) < ( lenIndicator + 1 )) |
164 | 0 | { |
165 | | /*Get the parameter code*/ |
166 | 0 | paramCode = tvb_get_uint8(tvb, offset + bytesProcessed); |
167 | 0 | simpduItem = proto_tree_add_item (simpduVarTree, hf_pdc_simpdu_param, tvb, offset + bytesProcessed, 1, ENC_BIG_ENDIAN); |
168 | 0 | simpduVarTree1 = proto_item_add_subtree (simpduItem, ett_pdc_simpdu_var); |
169 | 0 | bytesProcessed += 1; |
170 | 0 | switch (paramCode) |
171 | 0 | { |
172 | 0 | case PARAM_CODE_VERSION: |
173 | 0 | proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_len, tvb, offset + bytesProcessed, 1, ENC_BIG_ENDIAN); |
174 | 0 | proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_version, tvb, offset + bytesProcessed + 1, 1, ENC_BIG_ENDIAN); |
175 | 0 | bytesProcessed += 2; |
176 | 0 | break; |
177 | 0 | case PARAM_CODE_REFERENCES: |
178 | 0 | proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_len, tvb, offset + bytesProcessed, 1, ENC_BIG_ENDIAN); |
179 | 0 | proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_REFSRC, tvb, offset + bytesProcessed + 1, 2, ENC_BIG_ENDIAN); |
180 | 0 | proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_REFDEST, tvb, offset + bytesProcessed + 3, 2, ENC_BIG_ENDIAN); |
181 | 0 | bytesProcessed += 5; |
182 | 0 | break; |
183 | 0 | case PARAM_CODE_TRANSPORT: |
184 | 0 | proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_len, tvb, offset + bytesProcessed, 1, ENC_BIG_ENDIAN); |
185 | 0 | proto_tree_add_item(simpduVarTree1, hf_pdc_simpdu_var_TSEL, tvb, offset + bytesProcessed + 1, 2, ENC_BIG_ENDIAN); |
186 | 0 | bytesProcessed += 3; |
187 | 0 | break; |
188 | 0 | } |
189 | 0 | } /* end of whileloop */ |
190 | 0 | } |
191 | 0 | return (bytesProcessed); |
192 | 0 | } |
193 | | |
194 | | static int dissect_rsmpdu(void) |
195 | 0 | { |
196 | 0 | return 0; |
197 | 0 | } |
198 | | |
199 | | static int dissect_drmpdu(tvbuff_t *tvb, proto_tree *tree, uint16_t offset) |
200 | 0 | { |
201 | | /*DR-MPDU*/ |
202 | 0 | proto_tree_add_item(tree, hf_pdc_drmpdu_abort, tvb, offset, 1, ENC_BIG_ENDIAN); |
203 | 0 | proto_tree_add_item(tree, hf_pdc_drmpdu_mode, tvb, offset, 1, ENC_BIG_ENDIAN); |
204 | 0 | proto_tree_add_item(tree, hf_pdc_drmpdu_init, tvb, offset, 1, ENC_BIG_ENDIAN); |
205 | 0 | proto_tree_add_item(tree, hf_pdc_drmpdu_reason, tvb, offset + 1, 1, ENC_BIG_ENDIAN); |
206 | |
|
207 | 0 | return 2; |
208 | 0 | } |
209 | | |
210 | | #if (PDC_VERSION == 2) |
211 | | static int dissect_admpdu(tvbuff_t *tvb, proto_tree *parent_tree, proto_tree *tree, uint16_t offset, packet_info *pinfo) |
212 | 0 | { |
213 | 0 | uint16_t userDataLen; |
214 | 0 | uint16_t returnLen; |
215 | 0 | tvbuff_t *asterixTVB; |
216 | | |
217 | | /*Add the ad*/ |
218 | 0 | proto_tree_add_item(tree, hf_pdc_admpdu_admpdunr, tvb, offset, 4, ENC_BIG_ENDIAN); |
219 | 0 | offset += 4; |
220 | |
|
221 | 0 | proto_tree_add_item(tree, hf_pdc_admpdu_size, tvb, offset, 2, ENC_BIG_ENDIAN); |
222 | | /* length of user data field */ |
223 | 0 | userDataLen = tvb_get_ntohs(tvb, offset); |
224 | 0 | offset += 2; |
225 | |
|
226 | 0 | returnLen = userDataLen + 6; |
227 | 0 | asterixTVB = tvb_new_subset_length(tvb, offset, userDataLen); |
228 | |
|
229 | 0 | if (asterix_handle != NULL) |
230 | 0 | call_dissector(asterix_handle, asterixTVB, pinfo, parent_tree); |
231 | |
|
232 | 0 | return (returnLen); |
233 | 0 | } |
234 | | #else |
235 | | static int dissect_admpdu(tvbuff_t *tvb, proto_tree *parent_tree _U_, proto_tree *tree, uint16_t offset, packet_info *pinfo _U_) |
236 | | { |
237 | | /*Add the ad*/ |
238 | | proto_tree_add_item(tree, hf_pdc_admpdu_admpdunr, tvb, offset, 4, ENC_BIG_ENDIAN); |
239 | | |
240 | | return 2; |
241 | | } |
242 | | #endif |
243 | | |
244 | | #if (PDC_VERSION == 2) |
245 | | static int dissect_dtmpdu(tvbuff_t *tvb, proto_tree *parent_tree, proto_tree *tree, uint16_t offset, packet_info *pinfo) |
246 | 0 | { |
247 | 0 | uint16_t userDataLen; |
248 | 0 | uint16_t returnLen; |
249 | 0 | tvbuff_t *asterixTVB; |
250 | |
|
251 | 0 | proto_tree_add_item(tree, hf_pdc_dtmpdu_user_size, tvb, offset, 2, ENC_BIG_ENDIAN); |
252 | | /* length of user data field */ |
253 | 0 | userDataLen = tvb_get_ntohs(tvb, 2); |
254 | 0 | returnLen = userDataLen + 2; |
255 | 0 | asterixTVB = tvb_new_subset_length(tvb, offset + 2, userDataLen); |
256 | |
|
257 | 0 | if (asterix_handle != NULL) |
258 | 0 | call_dissector(asterix_handle, asterixTVB, pinfo, parent_tree); |
259 | |
|
260 | 0 | return (returnLen); |
261 | 0 | } |
262 | | #else |
263 | | static int dissect_dtmpdu(tvbuff_t *tvb _U_, proto_tree *parent_tree _U_, proto_tree *tree _U_, uint16_t offset _U_, packet_info *pinfo _U_) |
264 | | { |
265 | | return 2; |
266 | | } |
267 | | #endif |
268 | | |
269 | | |
270 | | #if (PDC_VERSION == 2) |
271 | | static int dissect_edmpdu(tvbuff_t *tvb, proto_tree *parent_tree, proto_tree *tree, uint16_t offset, packet_info *pinfo) |
272 | 0 | { |
273 | 0 | uint16_t userDataLen; |
274 | 0 | uint16_t returnLen; |
275 | 0 | tvbuff_t *asterixTVB; |
276 | |
|
277 | 0 | proto_tree_add_item(tree, hf_pdc_dtmpdu_user_size, tvb, offset, 2, ENC_BIG_ENDIAN); |
278 | | /* length of user data field */ |
279 | 0 | userDataLen = tvb_get_ntohs(tvb, 2); |
280 | 0 | returnLen = userDataLen + 2; |
281 | 0 | asterixTVB = tvb_new_subset_length(tvb, offset + 2, userDataLen); |
282 | |
|
283 | 0 | if (asterix_handle != NULL) |
284 | 0 | call_dissector(asterix_handle, asterixTVB, pinfo, parent_tree); |
285 | |
|
286 | 0 | return (returnLen); |
287 | 0 | } |
288 | | #else |
289 | | static int dissect_edmpdu(tvbuff_t *tvb _U_, proto_tree *parent_tree _U_, proto_tree *tree _U_, uint16_t offset _U_, packet_info *pinfo _U_) |
290 | | { |
291 | | return 2; |
292 | | } |
293 | | #endif |
294 | | |
295 | | static int dissect_akmpdu(tvbuff_t *tvb, proto_tree *tree, uint16_t offset) |
296 | 0 | { |
297 | 0 | proto_tree_add_item(tree, hf_pdc_akmpdu_mns, tvb, offset, 2, ENC_BIG_ENDIAN); |
298 | 0 | proto_tree_add_item(tree, hf_pdc_akmpdu_cdt, tvb, offset, 2, ENC_BIG_ENDIAN); |
299 | 0 | proto_tree_add_item(tree, hf_pdc_yr_admu_nr, tvb, offset + 2, 4, ENC_BIG_ENDIAN); |
300 | 0 | return (6); |
301 | 0 | } |
302 | | |
303 | | static int dissect_pdc_packet(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo) |
304 | 0 | { |
305 | 0 | unsigned i = 0; |
306 | 0 | uint8_t len_indicator; |
307 | 0 | uint8_t mpduCode; |
308 | 0 | uint16_t length; |
309 | 0 | proto_item *pdcPacketItem; |
310 | 0 | proto_tree *pdcPacketTree; |
311 | |
|
312 | 0 | length = 0; |
313 | | |
314 | | /*Get the length indictor and the MPDU Code*/ |
315 | 0 | len_indicator = tvb_get_uint8 (tvb, i); |
316 | 0 | mpduCode = tvb_get_uint8 (tvb, i + 1); |
317 | 0 | length += 2; |
318 | | |
319 | | /*Add the PDC Tree*/ |
320 | 0 | pdcPacketItem = proto_tree_add_item (tree, proto_pdc, tvb, i, len_indicator + 1, ENC_NA); |
321 | 0 | pdcPacketTree = proto_item_add_subtree (pdcPacketItem, ett_pdc); |
322 | | |
323 | | /*Add the Length and packet type*/ |
324 | 0 | proto_tree_add_item(pdcPacketTree, hf_pdc_len, tvb, i, 1, ENC_BIG_ENDIAN); |
325 | 0 | proto_tree_add_item(pdcPacketTree, hf_pdc_mpdu_code, tvb, i + 1, 1, ENC_BIG_ENDIAN); |
326 | | |
327 | | /*Call the correct dissecting function*/ |
328 | 0 | switch (mpduCode) |
329 | 0 | { |
330 | 0 | case SIMPDU: |
331 | 0 | length += dissect_simpdu(tvb, pdcPacketTree, length, len_indicator); |
332 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "SIMPDU"); |
333 | 0 | break; |
334 | 0 | case RSMPDU: |
335 | 0 | length += dissect_rsmpdu(); |
336 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "RSMPDU"); |
337 | 0 | break; |
338 | 0 | case DRMPDU: |
339 | 0 | length += dissect_drmpdu(tvb, pdcPacketTree, length); |
340 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "DRMPDU"); |
341 | 0 | break; |
342 | 0 | case DTMPDU: |
343 | 0 | length += dissect_dtmpdu(tvb, tree, pdcPacketTree, length, pinfo); |
344 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "DTMPDU"); |
345 | 0 | break; |
346 | 0 | case ADMPDU: |
347 | 0 | length += dissect_admpdu(tvb, tree, pdcPacketTree, length, pinfo); |
348 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "ADMPDU"); |
349 | 0 | break; |
350 | 0 | case EDMPDU: |
351 | 0 | length += dissect_edmpdu(tvb, tree, pdcPacketTree, length, pinfo); |
352 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "EDMPDU"); |
353 | 0 | break; |
354 | 0 | case AKMPDU: |
355 | 0 | length += dissect_akmpdu(tvb, pdcPacketTree, length); |
356 | 0 | col_set_str(pinfo->cinfo, COL_INFO, "AKMPDU"); |
357 | 0 | break; |
358 | 0 | default: |
359 | 0 | break; |
360 | 0 | }; |
361 | 0 | return (length); /* XXX: returned length ignored by caller: Remove keeping track of data processed ? */ |
362 | | /* col_set_str() could then be done separately with 'if (tree)' around the dissection */ |
363 | 0 | } |
364 | | |
365 | | /* Actual dissector bits and bytes done here */ |
366 | | static int dissect_pdc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) |
367 | 0 | { |
368 | | /*Set the Column*/ |
369 | 0 | col_set_str(pinfo->cinfo, COL_PROTOCOL, "PDC"); |
370 | 0 | col_clear(pinfo->cinfo, COL_INFO); |
371 | |
|
372 | 0 | dissect_pdc_packet(tvb, tree, pinfo); |
373 | |
|
374 | 0 | return tvb_reported_length(tvb); |
375 | 0 | } |
376 | | |
377 | | /* function to provide TCP split packet combiner with size of packet */ |
378 | | static unsigned get_pdc_message_len(packet_info *pinfo _U_, tvbuff_t *tvb, |
379 | | int offset, void *data _U_) |
380 | 0 | { |
381 | 0 | unsigned size; |
382 | 0 | unsigned extra; |
383 | 0 | uint8_t mpdu_type; |
384 | |
|
385 | 0 | mpdu_type = tvb_get_uint8(tvb, offset+1); |
386 | 0 | switch (mpdu_type) |
387 | 0 | { |
388 | 0 | case SIMPDU: |
389 | 0 | size = tvb_get_uint8(tvb, offset); |
390 | 0 | extra = 1; |
391 | 0 | break; |
392 | 0 | case RSMPDU: |
393 | 0 | size = tvb_get_uint8(tvb, offset); |
394 | 0 | extra = 1; |
395 | 0 | break; |
396 | 0 | case DRMPDU: |
397 | 0 | size = tvb_get_uint8(tvb, offset); |
398 | 0 | extra = 1; |
399 | 0 | break; |
400 | 0 | case DTMPDU: |
401 | 0 | size = tvb_get_ntohs(tvb, offset+2); |
402 | 0 | extra = 4; |
403 | 0 | break; |
404 | 0 | case ADMPDU: |
405 | 0 | size = tvb_get_ntohs(tvb, offset+6); |
406 | 0 | extra = 8; |
407 | 0 | break; |
408 | 0 | case EDMPDU: |
409 | 0 | size = tvb_get_uint8(tvb, offset); |
410 | 0 | extra = 1; |
411 | 0 | break; |
412 | 0 | case AKMPDU: |
413 | 0 | size = tvb_get_uint8(tvb, offset)+1; |
414 | 0 | extra = 0; |
415 | 0 | break; |
416 | 0 | default: |
417 | 0 | size = 0; |
418 | 0 | extra = 0; |
419 | 0 | } |
420 | 0 | return size + extra; |
421 | 0 | } |
422 | | |
423 | | /* top level call to recombine split tcp packets */ |
424 | | |
425 | | static int tcp_dissect_pdc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) |
426 | 0 | { |
427 | 0 | uint8_t mpdu_type; |
428 | 0 | uint8_t minimum_bytes; |
429 | |
|
430 | 0 | mpdu_type = tvb_get_uint8(tvb,1); |
431 | 0 | switch (mpdu_type) |
432 | 0 | { |
433 | 0 | case SIMPDU: |
434 | 0 | minimum_bytes = 2; |
435 | 0 | break; |
436 | 0 | case RSMPDU: |
437 | 0 | minimum_bytes = 2; |
438 | 0 | break; |
439 | 0 | case DRMPDU: |
440 | 0 | minimum_bytes = 2; |
441 | 0 | break; |
442 | 0 | case DTMPDU: |
443 | 0 | minimum_bytes = 4; |
444 | 0 | break; |
445 | 0 | case ADMPDU: |
446 | 0 | minimum_bytes = 8; |
447 | 0 | break; |
448 | 0 | case EDMPDU: |
449 | 0 | minimum_bytes = 2; |
450 | 0 | break; |
451 | 0 | case AKMPDU: |
452 | 0 | minimum_bytes = 2; |
453 | 0 | break; |
454 | 0 | default: |
455 | 0 | minimum_bytes = 2; |
456 | 0 | break; |
457 | 0 | } |
458 | 0 | tcp_dissect_pdus(tvb, pinfo, tree, true, minimum_bytes, get_pdc_message_len, dissect_pdc, NULL); |
459 | 0 | return tvb_captured_length(tvb); |
460 | 0 | } |
461 | | |
462 | | void proto_register_pdc(void) |
463 | 16 | { |
464 | 16 | static hf_register_info hf[] = |
465 | 16 | { |
466 | 16 | { &hf_pdc_len, |
467 | 16 | { "Length Indicator", "pdc.li", |
468 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
469 | | |
470 | 16 | { &hf_pdc_mpdu_code, |
471 | 16 | { "MPDU code", "pdc.mpducode", |
472 | 16 | FT_UINT8, BASE_DEC, VALS(valstr_mpdus), 0x0, NULL, HFILL }}, |
473 | | |
474 | 16 | { &hf_pdc_credit, |
475 | 16 | { "Credit", "pdc.cdt", |
476 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
477 | | |
478 | 16 | { &hf_pdc_yr_admu_nr, |
479 | 16 | { "YR-ADMU-NR", "pdc.yradmunr", |
480 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, NULL , HFILL }}, |
481 | | |
482 | 16 | { &hf_pdc_simpdu_state, |
483 | 16 | { "State", "pdc.state", |
484 | 16 | FT_UINT8, BASE_DEC, VALS(valstr_simpdu_state), 0x0, NULL, HFILL }}, |
485 | | |
486 | 16 | { &hf_pdc_akmpdu_mns, |
487 | 16 | { "MNS", "pdc.akmpdu.mns", |
488 | 16 | FT_UINT16, BASE_DEC, NULL, 0x8000, NULL, HFILL }}, |
489 | | |
490 | 16 | { &hf_pdc_akmpdu_cdt, |
491 | 16 | { "CDT", "pdc.akmpdu.cdt", |
492 | 16 | FT_UINT16, BASE_DEC, NULL, 0x07FF, NULL, HFILL }}, |
493 | | |
494 | 16 | { &hf_pdc_simpdu_var, |
495 | 16 | { "Variable Part", "pdc.simpdu.variable", |
496 | 16 | FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }}, |
497 | | |
498 | 16 | { &hf_pdc_simpdu_param, |
499 | 16 | { "Parameter", "pdc.simpdu.param", |
500 | 16 | FT_UINT8, BASE_DEC, VALS(valstr_simpdu_param), 0x0, NULL, HFILL }}, |
501 | | |
502 | 16 | { &hf_pdc_simpdu_var_len, |
503 | 16 | { "Length", "pdc.simpdu.variable.length", |
504 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
505 | | |
506 | 16 | { &hf_pdc_simpdu_var_version, |
507 | 16 | { "PDC Version Number", "pdc.simpdu.variable.version", |
508 | 16 | FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
509 | | |
510 | 16 | { &hf_pdc_simpdu_var_REFSRC, |
511 | 16 | { "Reference Source", "pdc.simpdu.variable.refsrc", |
512 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0,NULL, HFILL }}, |
513 | | |
514 | 16 | { &hf_pdc_simpdu_var_REFDEST, |
515 | 16 | { "Reference Destination", "pdc.simpdu.variable.refdst", |
516 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0,NULL, HFILL }}, |
517 | | |
518 | 16 | { &hf_pdc_simpdu_var_TSEL, |
519 | 16 | { "Transport Selector", "pdc.simpdu.tsel", |
520 | 16 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, |
521 | | |
522 | 16 | { &hf_pdc_drmpdu_abort, |
523 | 16 | { "Abort", "pdc.drmpdu.abort", |
524 | 16 | FT_UINT8, BASE_DEC, VALS(valstr_drmpdu_abort), 0x80, NULL, HFILL }}, |
525 | | |
526 | 16 | { &hf_pdc_drmpdu_reason, |
527 | 16 | { "Reason", "pdc.drmpdu.reason", |
528 | 16 | FT_UINT8, BASE_DEC, VALS(valstr_drmpdu_reason), 0x0, NULL, HFILL }}, |
529 | | |
530 | 16 | { &hf_pdc_drmpdu_mode, |
531 | 16 | { "Mode", "pdc.drmpdu.mode", |
532 | 16 | FT_UINT8, BASE_DEC, VALS(valstr_drmpdu_mode), 0x70, NULL, HFILL }}, |
533 | | |
534 | 16 | { &hf_pdc_drmpdu_init, |
535 | 16 | { "Reason", "pdc.drmpdu.init", |
536 | 16 | FT_UINT8, BASE_DEC, VALS(valstr_drmpdu_initatior), 0x0F, NULL, HFILL }}, |
537 | | |
538 | 16 | { &hf_pdc_dtmpdu_user_size, |
539 | 16 | { "User Data Length", "pdc.dtmpdu.usersize", |
540 | 16 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL , HFILL }}, |
541 | | |
542 | 16 | { &hf_pdc_admpdu_admpdunr, |
543 | 16 | { "AD-MPDU-NR", "pdc.admpdu.admpdunr", |
544 | 16 | FT_UINT32, BASE_DEC, NULL, 0x0, NULL , HFILL }}, |
545 | | |
546 | 16 | { &hf_pdc_admpdu_size, |
547 | 16 | { "User Data Size", "pdc.admpdu.usersize", |
548 | 16 | FT_UINT16, BASE_DEC, NULL, 0x0, NULL , HFILL }}, |
549 | 16 | }; |
550 | | |
551 | | /* Setup protocol subtree array */ |
552 | 16 | static int *ett[] = { |
553 | 16 | &ett_pdc, |
554 | 16 | &ett_pdc_simpdu_var |
555 | 16 | }; |
556 | | |
557 | 16 | proto_pdc = proto_register_protocol ("PDC Protocol", "PDC", "pdc"); |
558 | | |
559 | | /*Required Function Calls to register the header fields and subtrees used*/ |
560 | 16 | proto_register_field_array(proto_pdc, hf, array_length(hf)); |
561 | 16 | proto_register_subtree_array(ett, array_length(ett)); |
562 | | |
563 | | /* Register our dissector handle */ |
564 | 16 | pdc_tcp_handle = register_dissector("pdc", tcp_dissect_pdc, proto_pdc); |
565 | 16 | } |
566 | | |
567 | | /* Function to add pdc dissector to tcp.port dissector table and to get handle for asterix dissector */ |
568 | | void proto_reg_handoff_pdc(void) |
569 | 16 | { |
570 | 16 | asterix_handle = find_dissector_add_dependency("asterix", proto_pdc); |
571 | 16 | dissector_add_for_decode_as_with_preference("tcp.port", pdc_tcp_handle); |
572 | 16 | } |
573 | | |
574 | | /* |
575 | | * Editor modelines - https://www.wireshark.org/tools/modelines.html |
576 | | * |
577 | | * Local variables: |
578 | | * c-basic-offset: 8 |
579 | | * tab-width: 8 |
580 | | * indent-tabs-mode: t |
581 | | * End: |
582 | | * |
583 | | * vi: set shiftwidth=8 tabstop=8 noexpandtab: |
584 | | * :indentSize=8:tabSize=8:noTabs=false: |
585 | | */ |