Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-cfdp.c
blob9b38d1ce4ee3b52eade76ac547924625946c762c
1 /* packet-cfdp.c
2 * Routines for CCSDS File Delivery Protocol (CFDP) dissection
3 * Copyright 2013, Juan Antonio Montesinos juan.mondl@gmail.com
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * Slightly updated to allow more in-depth decoding when called
10 * with the 'dissect_as_subtree' method and to leverage some
11 * of the bitfield display operations: Keith Scott
12 * <kscott@mitre.org>.
14 * SPDX-License-Identifier: GPL-2.0-or-later
16 #include "config.h"
18 #include <epan/packet.h>
19 #include <epan/expert.h>
20 #include "packet-cfdp.h"
22 /* The CFDP standard can be found here:
23 * https://public.ccsds.org/Pubs/727x0b4s.pdf
25 * The Store and Forward Overlay Operations are not included.
28 void proto_register_cfdp(void);
29 void proto_reg_handoff_cfdp(void);
31 /* Initialize the protocol and registered fields */
32 static int proto_cfdp;
33 static int hf_cfdp_flags;
34 static int hf_cfdp_byte2;
35 static int hf_cfdp_proxy_fault_hdl_overr;
36 static int hf_cfdp_proxy_trans_mode;
37 static int hf_cfdp_proxy_segment_control_byte;
38 static int hf_cfdp_proxy_put_resp;
39 static int hf_cfdp_orig_trans_id;
40 static int hf_cfdp_remote_stat_rep_req;
41 static int hf_cfdp_remote_stat_rep_resp;
42 static int hf_cfdp_finish_pdu_flags;
43 static int hf_cfdp_remote_suspend_resume_req;
44 static int hf_cfdp_remote_suspend_resume_resp;
45 static int hf_cfdp_version;
46 static int hf_cfdp_pdu_type;
47 static int hf_cfdp_direction;
48 static int hf_cfdp_trans_mode;
49 static int hf_cfdp_trans_mode_2;
50 static int hf_cfdp_crc_flag;
51 static int hf_cfdp_res1;
52 static int hf_cfdp_data_length;
53 static int hf_cfdp_file_data_pdu;
54 static int hf_cfdp_res2;
55 static int hf_cfdp_entid_length;
56 static int hf_cfdp_res3;
57 static int hf_cfdp_transeqnum_length;
58 static int hf_cfdp_srcid;
59 static int hf_cfdp_transeqnum;
60 static int hf_cfdp_dstid;
61 static int hf_cfdp_file_directive_type;
62 static int hf_cfdp_file_data_offset;
63 static int hf_cfdp_progress;
64 static int hf_cfdp_dir_code_ack;
65 static int hf_cfdp_dir_subtype_ack;
66 static int hf_cfdp_condition_code;
67 static int hf_cfdp_spare_one;
68 static int hf_cfdp_spare_one_2;
69 static int hf_cfdp_spare_two;
70 static int hf_cfdp_spare_four;
71 static int hf_cfdp_spare_five;
72 static int hf_cfdp_spare_five_2;
73 static int hf_cfdp_spare_seven;
74 static int hf_cfdp_spare_seven_2;
75 static int hf_cfdp_trans_stat_ack;
76 static int hf_cfdp_file_checksum;
77 static int hf_cfdp_file_size;
78 static int hf_cfdp_end_system_stat;
79 static int hf_cfdp_delivery_code;
80 static int hf_cfdp_file_stat;
81 static int hf_cfdp_segment_control;
82 static int hf_cfdp_src_file_name_len;
83 static int hf_cfdp_src_file_name;
84 static int hf_cfdp_dst_file_name_len;
85 static int hf_cfdp_dst_file_name;
86 static int hf_cfdp_first_file_name_len;
87 static int hf_cfdp_first_file_name;
88 static int hf_cfdp_second_file_name_len;
89 static int hf_cfdp_second_file_name;
90 static int hf_cfdp_nak_st_scope;
91 static int hf_cfdp_nak_sp_scope;
92 static int hf_cfdp_crc;
93 static int hf_cfdp_action_code;
94 static int hf_cfdp_status_code_1;
95 static int hf_cfdp_status_code_2;
96 static int hf_cfdp_status_code_3;
97 static int hf_cfdp_status_code_4;
98 static int hf_cfdp_status_code_5;
99 static int hf_cfdp_status_code_6;
100 static int hf_cfdp_status_code_7;
101 static int hf_cfdp_status_code_8;
102 static int hf_cfdp_handler_code;
103 static int hf_cfdp_proxy_msg_type;
104 static int hf_cfdp_proxy_segment_control;
105 static int hf_cfdp_proxy_delivery_code;
106 static int hf_cfdp_response_req;
107 static int hf_cfdp_directory_name;
108 static int hf_cfdp_directory_file_name;
109 static int hf_cfdp_listing_resp_code;
110 static int hf_cfdp_report_file_name;
111 static int hf_cfdp_trans_stat;
112 static int hf_cfdp_trans_stat_2;
113 static int hf_cfdp_rep_resp_code;
114 static int hf_cfdp_suspension_ind;
115 static int hf_cfdp_tlv_len;
117 /* Generated from convert_proto_tree_add_text.pl */
118 static int hf_cfdp_filestore_message_len;
119 static int hf_cfdp_filestore_message;
120 static int hf_cfdp_entity;
121 static int hf_cfdp_message_to_user;
122 static int hf_cfdp_flow_label;
123 static int hf_cfdp_segment_requests;
124 static int hf_cfdp_user_data;
126 /* Initialize the subtree pointers */
127 static int ett_cfdp;
128 static int ett_cfdp_header;
129 static int ett_cfdp_flags;
130 static int ett_cfdp_byte2;
131 static int ett_cfdp_proxy_fault_hdl_overr;
132 static int ett_cfdp_proxy_trans_mode;
133 static int ett_cfdp_proxy_segment_control_byte;
134 static int ett_cfdp_proxy_put_resp;
135 static int ett_cfdp_orig_trans_id;
136 static int ett_cfdp_remote_stat_rep_req;
137 static int ett_cfdp_remote_stat_rep_resp;
138 static int ett_cfdp_file_directive_header;
139 static int ett_cfdp_file_data_header;
140 static int ett_cfdp_finish_pdu_flags;
141 static int ett_cfdp_remote_suspend_resume_req;
142 static int ett_cfdp_remote_suspend_resume_resp;
143 static int ett_cfdp_fault_location;
144 static int ett_cfdp_crc;
145 static int ett_cfdp_filestore_req;
146 static int ett_cfdp_filestore_resp;
147 static int ett_cfdp_msg_to_user;
148 static int ett_cfdp_fault_hdl_overr;
149 static int ett_cfdp_flow_label;
150 static int ett_cfdp_proto;
152 static expert_field ei_cfdp_bad_length;
155 static dissector_handle_t cfdp_handle;
157 /* Some parameters */
158 #define CFDP_HEADER_FIXED_FIELDS_LEN 4
159 #define CFDP_APID 2045
161 /* Bitmask for the first byte of the Header */
162 #define HDR_VERSION_CFDP 0xe0
163 #define HDR_TYPE_CFDP 0x10
164 #define HDR_DIR 0x08
165 #define HDR_TMODE 0x04
166 #define HDR_CRCF 0x02
167 #define HDR_RES1 0x01
169 /* Bitmask for the second byte of the Header */
170 #define HDR_RES2 0x80
171 #define HDR_LEN_ENT_ID 0x70
172 #define HDR_RES3 0x08
173 #define HDR_LEN_TSEQ_NUM 0x07
175 /* File Directive Codes */
176 #define EOF_PDU 4
177 #define FINISHED_PDU 5
178 #define ACK_PDU 6
179 #define METADATA_PDU 7
180 #define NAK_PDU 8
181 #define PROMPT_PDU 9
182 #define KEEP_ALIVE_PDU 12
184 /* TLV Types */
185 #define FILESTORE_REQ 0
186 #define FILESTORE_RESP 1
187 #define MSG_TO_USER 2
188 #define FAULT_HDL_OVERR 4
189 #define FLOW_LABEL 5
190 #define FAULT_LOCATION 6
192 /* ID for reserved CFDP Messages */
193 #define CFDP_MSG_TO_USER 0x63666470
195 /* Proxy Operations Message Types */
196 #define PROXY_PUT_REQ 0x00
197 #define PROXY_MSG_TO_USER 0x01
198 #define PROXY_FILESTORE_REQ 0x02
199 #define PROXY_FAULT_HDL_OVERR 0x03
200 #define PROXY_TRANS_MODE 0x04
201 #define PROXY_FLOW_LABEL 0x05
202 #define PROXY_SEGMENT_CONTROL 0x06
203 #define PROXY_PUT_RESP 0x07
204 #define PROXY_FILESTORE_RESP 0x08
205 #define PROXY_PUT_CANCEL 0x09
206 #define ORIG_TRANS_ID 0x0A
207 #define DIRECTORY_LIST_REQ 0x10
208 #define DIRECTORY_LIST_RESP 0x11
209 #define REMOTE_STAT_REP_REQ 0x20
210 #define REMOTE_STAT_REP_RESP 0x21
211 #define REMOTE_SUSPEND_REQ 0x30
212 #define REMOTE_SUSPEND_RESP 0x31
213 #define REMOTE_RESUME_REQ 0x38
214 #define REMOTE_RESUME_RESP 0x39
216 /* PDU Type */
217 static const value_string cfdp_pdu_type[] = {
218 { 0, "File Directive" },
219 { 1, "File Data" },
220 { 0, NULL }
223 /* PDU Direction */
224 static const value_string cfdp_direction[] = {
225 { 0, "Toward file receiver" },
226 { 1, "Toward file sender" },
227 { 0, NULL }
230 /* Transmission mode */
231 static const value_string cfdp_trans_mode[] = {
232 { 0, "Acknowledged" },
233 { 1, "Unacknowledged" },
234 { 0, NULL }
237 /* CRC */
238 static const value_string cfdp_crc_flag[] = {
239 { 0, "CRC not present" },
240 { 1, "CRC present" },
241 { 0, NULL }
244 /* File Directive PDU Type */
245 static const value_string cfdp_file_directive_type[] = {
246 { 4, "EOF PDU"},
247 { 5, "Finished PDU"},
248 { 6, "ACK PDU"},
249 { 7, "Metadata PDU"},
250 { 8, "NACK PDU"},
251 { 9, "Prompt PDU"},
252 { 12, "Keep Alive PDU"},
253 { 0, NULL}
256 /* Condition codes */
257 static const value_string cfdp_condition_codes[] = {
258 { 0, "No error"},
259 { 1, "Positive ACK limit reached"},
260 { 2, "Keep alive limit reached"},
261 { 3, "Invalid transmission mode"},
262 { 4, "Filestore rejection"},
263 { 5, "File checksum failure"},
264 { 6, "File size error"},
265 { 7, "NAK limit reached"},
266 { 8, "Inactivity detected"},
267 { 9, "Check limit reached"},
268 { 14, "Suspend.request received"},
269 { 15, "Cancel.request received"},
270 { 0, NULL }
273 /* Transaction status */
274 static const value_string cfdp_trans_stat_ack[] = {
275 { 0, "Undefined" },
276 { 1, "Active" },
277 { 2, "Terminated" },
278 { 3, "Unrecognized" },
279 { 0, NULL }
282 /* End system status */
283 static const value_string cfdp_end_system_stat[] = {
284 { 0, "Generated by Waypoint" },
285 { 1, "Generated by End System" },
286 { 0, NULL }
289 /* Delivery code */
290 static const value_string cfdp_delivery_code[] = {
291 { 0, "Data Complete" },
292 { 1, "Data incomplete" },
293 { 0, NULL }
296 /* Filestore operations action code */
297 static const value_string cfdp_action_code[] = {
298 { 0, "Create File" },
299 { 1, "Delete File" },
300 { 2, "Rename File" },
301 { 3, "Append File" },
302 { 4, "Replace File" },
303 { 5, "Create Directory" },
304 { 6, "Remove Directory" },
305 { 7, "Deny File (delete if present)" },
306 { 8, "Deny Directory (remove if present)" },
307 { 0, NULL }
310 /* Filestore operations status codes */
311 static const value_string cfdp_status_code_1[] = {
312 { 0, "Successful" },
313 { 1, "Create not allowed" },
314 { 8, "Not performed" },
315 { 0, NULL }
318 static const value_string cfdp_status_code_2[] = {
319 { 0, "Successful" },
320 { 1, "File does not exist" },
321 { 2, "Delete not allowed" },
322 { 8, "Not performed" },
323 { 0, NULL }
326 static const value_string cfdp_status_code_3[] = {
327 { 0, "Successful" },
328 { 1, "Old File Name does not exist" },
329 { 2, "New File Name already exists" },
330 { 3, "Rename not allowed" },
331 { 8, "Not performed" },
332 { 0, NULL }
335 static const value_string cfdp_status_code_4[] = {
336 { 0, "Successful" },
337 { 1, "File Name 1 does not exist" },
338 { 2, "File Name 2 does not exist" },
339 { 3, "Append not allowed" },
340 { 8, "Not performed" },
341 { 0, NULL }
344 static const value_string cfdp_status_code_5[] = {
345 { 0, "Successful" },
346 { 1, "File Name 1 does not exist" },
347 { 2, "File Name 2 does not exist" },
348 { 3, "Replace not allowed" },
349 { 8, "Not performed" },
350 { 0, NULL }
353 static const value_string cfdp_status_code_6[] = {
354 { 0, "Successful" },
355 { 1, "Directory cannot be created" },
356 { 8, "Not performed" },
357 { 0, NULL }
360 static const value_string cfdp_status_code_7[] = {
361 { 0, "Successful" },
362 { 1, "Directory does not exist" },
363 { 2, "Delete not allowed" },
364 { 8, "Not performed" },
365 { 0, NULL }
368 static const value_string cfdp_status_code_8[] = {
369 { 0, "Successful" },
370 { 1, "Delete not allowed" },
371 { 8, "Not performed" },
372 { 0, NULL }
375 /* Finished PDU File Status */
376 static const value_string cfdp_file_stat[] = {
377 { 0, "Delivery file discarded deliberately" },
378 { 1, "Delivery file discarded due to filestore rejection" },
379 { 2, "Delivery file retained in filestore successfully" },
380 { 3, "Delivery file status unreported" },
381 { 0, NULL }
384 /* Segmentation control */
385 static const value_string cfdp_segment_control[] = {
386 { 0, "Record boundaries respected" },
387 { 1, "Record boundaries not respected" },
388 { 0, NULL }
391 /* Fault handler override Handler code*/
392 static const value_string cfdp_handler_codes[] = {
393 { 1, "issue Notice of Cancellation" },
394 { 2, "issue Notice of Suspension" },
395 { 3, "Ignore error" },
396 { 4, "Abandon transaction" },
397 { 0, NULL }
400 /* Type of Proxy message */
401 static const value_string cfdp_proxy_msg_type[] = {
402 { 0x00, "Proxy Put Request"},
403 { 0x01, "Proxy Message To User"},
404 { 0x02, "Proxy Filestore Request"},
405 { 0x03, "Proxy Fault Handler Override"},
406 { 0x04, "Proxy Transmission Mode"},
407 { 0x05, "Proxy Flow Label"},
408 { 0x06, "Proxy Segmentation Control"},
409 { 0x07, "Proxy Put Response"},
410 { 0x08, "Proxy Filestore Response"},
411 { 0x09, "Proxy Put Cancel"},
412 { 0x0A, "Originating Transaction ID"},
413 { 0x10, "Directory Listing Request"},
414 { 0x11, "Directory Listing Response"},
415 { 0x20, "Remote Status Report Request"},
416 { 0x21, "Remote Status Report Response"},
417 { 0x30, "Remote Suspend Request"},
418 { 0x31, "Remote Suspend Response"},
419 { 0x38, "Remote Resume Request"},
420 { 0x39, "Remote Resume Response"},
421 { 0, NULL }
423 static value_string_ext cfdp_proxy_msg_type_ext = VALUE_STRING_EXT_INIT(cfdp_proxy_msg_type);
425 /* Prompt PDU Response required */
426 static const value_string cfdp_response_req[] = {
427 { 0, "NAK" },
428 { 1, "Keep Alive" },
429 { 0, NULL }
432 /* Listing response code */
433 static const value_string cfdp_listing_resp_code[] = {
434 { 0, "Successful" },
435 { 1, "Unsuccessful" },
436 { 0, NULL }
439 /* Report response code */
440 static const value_string cfdp_rep_resp_code[] = {
441 { 0, "Unsuccessful" },
442 { 1, "Successful" },
443 { 0, NULL }
446 /* Suspension indication */
447 static const value_string cfdp_suspension_ind[] = {
448 { 0, "Not Suspended" },
449 { 1, "Suspended" },
450 { 0, NULL }
453 /* File Directive codes */
454 static const value_string cfdp_directive_codes[] = {
455 { 0x04, "EOF" },
456 { 0x05, "Finished" },
457 { 0x06, "ACK" },
458 { 0x07, "Metadata" },
459 { 0x08, "NAK" },
460 { 0x09, "Prompt" },
461 { 0x0C, "Keep Alive" },
462 { 0, NULL }
465 static int * const cfdp_flags[] = {
466 &hf_cfdp_version,
467 &hf_cfdp_pdu_type,
468 &hf_cfdp_direction,
469 &hf_cfdp_trans_mode,
470 &hf_cfdp_crc_flag,
471 &hf_cfdp_res1,
472 NULL
475 static int * const cfdp_byte2[] = {
476 &hf_cfdp_res2,
477 &hf_cfdp_entid_length,
478 &hf_cfdp_res3,
479 &hf_cfdp_transeqnum_length,
480 NULL
483 static int * const cfdp_proxy_fault_hdl_overr[] = {
484 &hf_cfdp_condition_code,
485 &hf_cfdp_handler_code,
486 NULL
489 static int * const cfdp_proxy_trans_mode [] = {
490 &hf_cfdp_spare_seven_2,
491 &hf_cfdp_trans_mode_2,
492 NULL
495 static int * const cfdp_proxy_segment_control_byte [] = {
496 &hf_cfdp_spare_seven_2,
497 &hf_cfdp_proxy_segment_control,
498 NULL
501 static int * const cfdp_proxy_put_resp [] = {
502 &hf_cfdp_condition_code,
503 &hf_cfdp_spare_one,
504 &hf_cfdp_proxy_delivery_code,
505 &hf_cfdp_file_stat,
506 NULL
509 static int * const cfdp_orig_trans_id[] = {
510 &hf_cfdp_res2,
511 &hf_cfdp_entid_length,
512 &hf_cfdp_res3,
513 &hf_cfdp_transeqnum_length,
514 NULL
517 static int * const cfdp_remote_stat_rep_req[] = {
518 &hf_cfdp_res2,
519 &hf_cfdp_entid_length,
520 &hf_cfdp_res3,
521 &hf_cfdp_transeqnum_length,
522 NULL
525 static int * const cfdp_remote_stat_rep_resp[] = {
526 &hf_cfdp_trans_stat,
527 &hf_cfdp_spare_five,
528 &hf_cfdp_rep_resp_code,
529 &hf_cfdp_spare_one_2,
530 &hf_cfdp_entid_length,
531 &hf_cfdp_spare_one,
532 &hf_cfdp_transeqnum_length,
533 NULL
536 static int * const cfdp_finish_pdu_flags [] = {
537 &hf_cfdp_condition_code,
538 &hf_cfdp_end_system_stat,
539 &hf_cfdp_delivery_code,
540 &hf_cfdp_file_stat,
541 NULL
544 /* 6.6.3.2 (1 byte) */
545 static int * const cfdp_remote_suspend_resume_req [] = {
546 &hf_cfdp_spare_one_2,
547 &hf_cfdp_entid_length,
548 &hf_cfdp_spare_one,
549 &hf_cfdp_transeqnum_length,
550 NULL
554 /* 6.6.4.2 (2 bytes) */
555 static int * const cfdp_remote_suspend_resume_resp [] = {
556 &hf_cfdp_suspension_ind,
557 &hf_cfdp_trans_stat_2,
558 &hf_cfdp_spare_five_2,
559 &hf_cfdp_spare_one_2,
560 &hf_cfdp_entid_length,
561 &hf_cfdp_spare_one,
562 &hf_cfdp_transeqnum_length,
563 NULL
568 /* Dissect the Source Entity ID field */
569 static void
570 dissect_cfdp_src_entity_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint8_t len_ent_id)
572 if(len_ent_id > 0 && len_ent_id <= 8){
573 proto_tree_add_item(tree, hf_cfdp_srcid, tvb, offset, len_ent_id, ENC_BIG_ENDIAN);
575 else{
576 proto_tree_add_expert_format(tree, pinfo, &ei_cfdp_bad_length, tvb, offset, 0, "Wrong length for the entity ID");
580 /* Dissect the Destination Entity ID field */
581 static void
582 dissect_cfdp_dst_entity_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint8_t len_ent_id)
584 if(len_ent_id > 0 && len_ent_id <= 8){
585 proto_tree_add_item(tree, hf_cfdp_dstid, tvb, offset, len_ent_id, ENC_BIG_ENDIAN);
587 else{
588 proto_tree_add_expert_format(tree, pinfo, &ei_cfdp_bad_length, tvb, offset, 0, "Wrong length for the entity ID");
592 /* Dissect the Transaction Sequence Number field */
593 static void
594 dissect_cfdp_tseq_num(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t offset, uint8_t len_tseq_num)
596 if(len_tseq_num > 0 && len_tseq_num <= 8){
597 proto_tree_add_item(tree, hf_cfdp_transeqnum, tvb, offset, len_tseq_num, ENC_BIG_ENDIAN);
599 else{
600 proto_tree_add_expert_format(tree, pinfo, &ei_cfdp_bad_length, tvb, offset, 0, "Wrong length for transaction sequence number");
604 /* Dissect the Filestore Request TLV */
605 static uint32_t dissect_cfdp_filestore_req_tlv(tvbuff_t *tvb, proto_tree *tree, uint32_t ext_offset){
607 uint8_t tlv_len;
609 uint32_t offset = ext_offset;
610 uint32_t length;
612 /* Get field length */
613 tlv_len = tvb_get_uint8(tvb, offset);
614 offset += 1;
615 if(tlv_len > 0){
616 proto_tree *cfdp_filestore_req_tree;
617 uint8_t aux_byte;
619 /* Create a TLV subtree */
620 cfdp_filestore_req_tree = proto_tree_add_subtree(tree, tvb, offset-2, tlv_len+2,
621 ett_cfdp_filestore_req, NULL, "Filestore Request TLV");
623 proto_tree_add_uint(cfdp_filestore_req_tree, hf_cfdp_tlv_len, tvb, offset-1, 1, tlv_len);
625 aux_byte = tvb_get_uint8(tvb, offset);
626 proto_tree_add_uint(cfdp_filestore_req_tree, hf_cfdp_action_code, tvb, offset, 1, aux_byte);
627 proto_tree_add_uint(cfdp_filestore_req_tree, hf_cfdp_spare_four, tvb, offset, 1, aux_byte);
628 offset += 1;
630 proto_tree_add_item_ret_uint(cfdp_filestore_req_tree, hf_cfdp_first_file_name_len, tvb, offset, 1, ENC_NA, &length);
631 offset += 1;
632 if(length > 0){
633 proto_tree_add_item(cfdp_filestore_req_tree, hf_cfdp_first_file_name, tvb, offset, length, ENC_ASCII);
635 offset += length;
637 proto_tree_add_item_ret_uint(cfdp_filestore_req_tree, hf_cfdp_second_file_name_len, tvb, offset, 1, ENC_NA, &length);
638 offset += 1;
639 if(length > 0){
640 proto_tree_add_item(cfdp_filestore_req_tree, hf_cfdp_second_file_name, tvb, offset, length, ENC_ASCII);
642 offset += length;
645 return offset;
648 /* Dissect the Filestore Response TLV */
649 static uint32_t dissect_cfdp_filestore_resp_tlv(tvbuff_t *tvb, proto_tree *tree, uint32_t ext_offset){
651 uint8_t tlv_len;
653 uint32_t offset = ext_offset;
655 /* Get field length */
656 tlv_len = tvb_get_uint8(tvb, offset);
657 offset += 1;
658 if(tlv_len > 0){
659 proto_tree *cfdp_filestore_resp_tree;
660 uint8_t aux_byte;
661 uint32_t length;
663 /* Create a subtree */
664 cfdp_filestore_resp_tree = proto_tree_add_subtree(tree, tvb, offset-2, tlv_len+2,
665 ett_cfdp_filestore_resp, NULL, "Filestore Response TLV");
667 proto_tree_add_uint(cfdp_filestore_resp_tree, hf_cfdp_tlv_len, tvb, offset-1, 1, tlv_len);
669 aux_byte = tvb_get_uint8(tvb, offset);
670 proto_tree_add_uint(cfdp_filestore_resp_tree, hf_cfdp_action_code, tvb, offset, 1, aux_byte);
671 switch((aux_byte & 0xF0) >> 4){
672 case 0:
673 proto_tree_add_uint(cfdp_filestore_resp_tree, hf_cfdp_status_code_1, tvb, offset, 1, aux_byte);
674 break;
675 case 1:
676 proto_tree_add_uint(cfdp_filestore_resp_tree, hf_cfdp_status_code_2, tvb, offset, 1, aux_byte);
677 break;
678 case 2:
679 proto_tree_add_uint(cfdp_filestore_resp_tree, hf_cfdp_status_code_3, tvb, offset, 1, aux_byte);
680 break;
681 case 3:
682 proto_tree_add_uint(cfdp_filestore_resp_tree, hf_cfdp_status_code_4, tvb, offset, 1, aux_byte);
683 break;
684 case 4:
685 proto_tree_add_uint(cfdp_filestore_resp_tree, hf_cfdp_status_code_5, tvb, offset, 1, aux_byte);
686 break;
687 case 5:
688 proto_tree_add_uint(cfdp_filestore_resp_tree, hf_cfdp_status_code_6, tvb, offset, 1, aux_byte);
689 break;
690 case 6:
691 proto_tree_add_uint(cfdp_filestore_resp_tree, hf_cfdp_status_code_7, tvb, offset, 1, aux_byte);
692 break;
693 case 7: case 8:
694 proto_tree_add_uint(cfdp_filestore_resp_tree, hf_cfdp_status_code_8, tvb, offset, 1, aux_byte);
695 break;
697 default:
698 break;
700 offset += 1;
702 proto_tree_add_item_ret_uint(cfdp_filestore_resp_tree, hf_cfdp_first_file_name_len, tvb, offset, 1, ENC_NA, &length);
703 offset += 1;
704 if(length > 0){
705 proto_tree_add_item(cfdp_filestore_resp_tree, hf_cfdp_first_file_name, tvb, offset, length, ENC_ASCII);
707 offset += length;
709 proto_tree_add_item_ret_uint(cfdp_filestore_resp_tree, hf_cfdp_second_file_name_len, tvb, offset, 1, ENC_NA, &length);
710 offset += 1;
711 if(length > 0){
712 proto_tree_add_item(cfdp_filestore_resp_tree, hf_cfdp_second_file_name, tvb, offset, length, ENC_ASCII);
714 offset += length;
716 /* Filestore Message */
717 proto_tree_add_item_ret_uint(cfdp_filestore_resp_tree, hf_cfdp_filestore_message_len, tvb, offset, 1, ENC_NA, &length);
718 offset += 1;
719 if(length > 0){
720 proto_tree_add_item(cfdp_filestore_resp_tree, hf_cfdp_filestore_message, tvb, offset, length, ENC_NA);
722 offset += length;
725 return offset+1;
728 /* Dissect the Fault Location TLV */
729 static uint32_t dissect_cfdp_fault_location_tlv(tvbuff_t *tvb, proto_tree *tree, uint32_t ext_offset){
731 uint8_t tlv_len;
733 uint32_t offset = ext_offset;
735 /* Get field length */
736 tlv_len = tvb_get_uint8(tvb, offset);
737 offset += 1;
738 if(tlv_len > 0){
739 proto_tree *cfdp_fault_location_tree;
741 /* Create a subtree */
742 cfdp_fault_location_tree = proto_tree_add_subtree(tree, tvb, offset-2, tlv_len+2,
743 ett_cfdp_fault_location, NULL, "Fault location TLV");
745 proto_tree_add_uint(cfdp_fault_location_tree, hf_cfdp_tlv_len, tvb, offset-1, 1, tlv_len);
747 proto_tree_add_item(cfdp_fault_location_tree, hf_cfdp_entity, tvb, offset, tlv_len, ENC_NA);
748 offset += tlv_len;
751 return offset;
754 /* Dissect the Message to User TLV */
755 static uint32_t dissect_cfdp_msg_to_user_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t ext_offset){
757 uint8_t tlv_type;
758 uint8_t tlv_len;
759 proto_tree *cfdp_msg_to_user_tree;
761 uint32_t offset = ext_offset;
762 uint32_t msg_to_user_id;
764 uint64_t retval;
766 int len_ent_id;
767 int len_tseq_num;
769 /* Get tlv len */
770 tlv_len = tvb_get_uint8(tvb, offset);
771 offset += 1;
773 /* Create a subtree */
774 cfdp_msg_to_user_tree = proto_tree_add_subtree(tree, tvb, offset-2, tlv_len+2,
775 ett_cfdp_filestore_resp, NULL, "Message To User TLV");
777 proto_tree_add_uint(cfdp_msg_to_user_tree, hf_cfdp_tlv_len, tvb, offset-1, 1, tlv_len);
779 msg_to_user_id = tvb_get_ntohl(tvb, offset);
780 /* Proxy operations */
781 if(msg_to_user_id == CFDP_MSG_TO_USER){
782 offset += 4;
783 tlv_type = tvb_get_uint8(tvb, offset);
784 proto_tree_add_uint(cfdp_msg_to_user_tree, hf_cfdp_proxy_msg_type, tvb, offset, 1, tlv_type);
785 offset += 1;
786 switch(tlv_type){
788 case PROXY_PUT_REQ:
789 tlv_len = tvb_get_uint8(tvb, offset);
790 offset += 1;
791 dissect_cfdp_dst_entity_id(tvb, pinfo, cfdp_msg_to_user_tree, offset, tlv_len);
792 offset += tlv_len;
794 tlv_len = tvb_get_uint8(tvb, offset);
795 offset += 1;
796 proto_tree_add_item(cfdp_msg_to_user_tree, hf_cfdp_src_file_name, tvb, offset, tlv_len, ENC_ASCII);
797 offset += tlv_len;
799 tlv_len = tvb_get_uint8(tvb, offset);
800 offset += 1;
801 proto_tree_add_item(cfdp_msg_to_user_tree, hf_cfdp_dst_file_name, tvb, offset, tlv_len, ENC_ASCII);
802 offset += tlv_len;
804 break;
806 case PROXY_MSG_TO_USER:
807 tlv_len = tvb_get_uint8(tvb, offset);
808 offset += 1;
809 proto_tree_add_item(cfdp_msg_to_user_tree, hf_cfdp_message_to_user, tvb, offset, tlv_len, ENC_NA);
810 offset += tlv_len;
811 break;
813 case PROXY_FILESTORE_REQ:
814 offset = dissect_cfdp_filestore_req_tlv(tvb, cfdp_msg_to_user_tree, offset);
815 break;
817 case PROXY_FAULT_HDL_OVERR:
818 proto_tree_add_bitmask(cfdp_msg_to_user_tree, tvb, offset,
819 hf_cfdp_proxy_fault_hdl_overr,
820 ett_cfdp_proxy_fault_hdl_overr,
821 cfdp_proxy_fault_hdl_overr,
822 ENC_BIG_ENDIAN);
823 offset += 1;
824 break;
826 case PROXY_TRANS_MODE:
827 proto_tree_add_bitmask(cfdp_msg_to_user_tree, tvb, offset,
828 hf_cfdp_proxy_trans_mode,
829 ett_cfdp_proxy_trans_mode,
830 cfdp_proxy_trans_mode,
831 ENC_BIG_ENDIAN);
832 offset += 1;
833 break;
835 case PROXY_FLOW_LABEL:
836 proto_tree_add_item(cfdp_msg_to_user_tree, hf_cfdp_flow_label, tvb, offset, tlv_len, ENC_NA);
837 break;
839 case PROXY_SEGMENT_CONTROL:
840 proto_tree_add_bitmask(cfdp_msg_to_user_tree, tvb, offset,
841 hf_cfdp_proxy_segment_control_byte,
842 ett_cfdp_proxy_segment_control_byte,
843 cfdp_proxy_segment_control_byte,
844 ENC_BIG_ENDIAN);
845 offset += 1;
846 break;
848 case PROXY_PUT_RESP:
849 proto_tree_add_bitmask(cfdp_msg_to_user_tree, tvb, offset,
850 hf_cfdp_proxy_put_resp,
851 ett_cfdp_proxy_put_resp,
852 cfdp_proxy_put_resp,
853 ENC_BIG_ENDIAN);
854 offset += 1;
855 break;
857 case PROXY_FILESTORE_RESP:
858 offset = dissect_cfdp_filestore_req_tlv(tvb, cfdp_msg_to_user_tree, offset);
859 break;
861 case PROXY_PUT_CANCEL:
862 break;
864 case ORIG_TRANS_ID:
865 proto_tree_add_bitmask_ret_uint64(cfdp_msg_to_user_tree, tvb, offset,
866 hf_cfdp_orig_trans_id,
867 ett_cfdp_orig_trans_id,
868 cfdp_orig_trans_id,
869 ENC_BIG_ENDIAN,
870 &retval);
871 offset += 1;
873 len_ent_id = ((retval & HDR_LEN_ENT_ID) >> 4) + 1;
874 dissect_cfdp_src_entity_id(tvb, pinfo, cfdp_msg_to_user_tree, offset, len_ent_id);
875 offset += len_ent_id;
877 len_tseq_num = (retval & HDR_LEN_TSEQ_NUM) +1;
878 dissect_cfdp_tseq_num(tvb, pinfo, cfdp_msg_to_user_tree, offset, len_tseq_num);
879 offset += len_tseq_num;
881 break;
883 case DIRECTORY_LIST_REQ:
884 /* Directory Name */
885 tlv_len = tvb_get_uint8(tvb, offset);
886 offset += 1;
887 proto_tree_add_item(cfdp_msg_to_user_tree, hf_cfdp_directory_name, tvb, offset, tlv_len, ENC_ASCII);
888 offset += tlv_len;
889 /* Directory File Name */
890 tlv_len = tvb_get_uint8(tvb, offset);
891 offset += 1;
892 proto_tree_add_item(cfdp_msg_to_user_tree, hf_cfdp_directory_file_name, tvb, offset, tlv_len, ENC_ASCII);
893 offset += tlv_len;
894 break;
896 case DIRECTORY_LIST_RESP:
897 /* Listing Response Code */
898 proto_tree_add_item(cfdp_msg_to_user_tree, hf_cfdp_listing_resp_code, tvb, offset, 1, ENC_NA);
899 offset += 1;
900 /* Directory Name */
901 tlv_len = tvb_get_uint8(tvb, offset);
902 offset += 1;
903 proto_tree_add_item(cfdp_msg_to_user_tree, hf_cfdp_directory_name, tvb, offset, tlv_len, ENC_ASCII);
904 offset += tlv_len;
905 /* Directory File Name */
906 tlv_len = tvb_get_uint8(tvb, offset);
907 offset += 1;
908 proto_tree_add_item(cfdp_msg_to_user_tree, hf_cfdp_directory_file_name, tvb, offset, tlv_len, ENC_ASCII);
909 offset += tlv_len;
910 break;
912 case REMOTE_STAT_REP_REQ:
913 proto_tree_add_bitmask_ret_uint64(cfdp_msg_to_user_tree, tvb, offset,
914 hf_cfdp_remote_stat_rep_req,
915 ett_cfdp_remote_stat_rep_req,
916 cfdp_remote_stat_rep_req,
917 ENC_BIG_ENDIAN,
918 &retval);
919 offset += 1;
921 len_ent_id = ((retval & HDR_LEN_ENT_ID) >> 4) + 1;
922 dissect_cfdp_src_entity_id(tvb, pinfo, cfdp_msg_to_user_tree, offset, len_ent_id);
923 offset += len_ent_id;
925 len_tseq_num = (retval & HDR_LEN_TSEQ_NUM) +1;
926 dissect_cfdp_tseq_num(tvb, pinfo, cfdp_msg_to_user_tree, offset, len_tseq_num);
927 offset += len_tseq_num;
929 /* Report File Name */
930 tlv_len = tvb_get_uint8(tvb, offset);
931 offset += 1;
932 proto_tree_add_item(cfdp_msg_to_user_tree, hf_cfdp_report_file_name, tvb, offset, tlv_len, ENC_ASCII);
933 offset += tlv_len;
934 break;
936 case REMOTE_STAT_REP_RESP:
937 proto_tree_add_bitmask_ret_uint64(cfdp_msg_to_user_tree, tvb, offset,
938 hf_cfdp_remote_stat_rep_resp,
939 ett_cfdp_remote_stat_rep_resp,
940 cfdp_remote_stat_rep_resp,
941 ENC_BIG_ENDIAN,
942 &retval);
944 len_ent_id = ((retval & (HDR_LEN_ENT_ID<<8)) >> 12) + 1;
945 dissect_cfdp_src_entity_id(tvb, pinfo, cfdp_msg_to_user_tree, offset, len_ent_id);
946 offset += len_ent_id;
948 len_tseq_num = (retval & HDR_LEN_TSEQ_NUM) +1;
949 dissect_cfdp_tseq_num(tvb, pinfo, cfdp_msg_to_user_tree, offset, len_tseq_num);
950 offset += len_tseq_num;
951 break;
953 case REMOTE_SUSPEND_REQ:
954 case REMOTE_RESUME_REQ:
955 proto_tree_add_bitmask_ret_uint64(cfdp_msg_to_user_tree, tvb, offset,
956 hf_cfdp_remote_suspend_resume_req,
957 ett_cfdp_remote_suspend_resume_req,
958 cfdp_remote_suspend_resume_req,
959 ENC_BIG_ENDIAN,
960 &retval);
962 offset += 1;
964 len_ent_id = ((retval & HDR_LEN_ENT_ID) >> 4) + 1;
965 dissect_cfdp_src_entity_id(tvb, pinfo, cfdp_msg_to_user_tree, offset, len_ent_id);
966 offset += len_ent_id;
968 len_tseq_num = (retval & HDR_LEN_TSEQ_NUM) +1;
969 dissect_cfdp_tseq_num(tvb, pinfo, cfdp_msg_to_user_tree, offset, len_tseq_num);
970 offset += len_tseq_num;
971 break;
973 case REMOTE_SUSPEND_RESP:
974 case REMOTE_RESUME_RESP:
975 proto_tree_add_bitmask_ret_uint64(cfdp_msg_to_user_tree, tvb, offset,
976 hf_cfdp_remote_suspend_resume_resp,
977 ett_cfdp_remote_suspend_resume_resp,
978 cfdp_remote_suspend_resume_resp,
979 ENC_BIG_ENDIAN,
980 &retval);
981 offset += 2;
983 len_ent_id = ((retval & HDR_LEN_ENT_ID) >> 4) + 1;
984 dissect_cfdp_src_entity_id(tvb, pinfo, cfdp_msg_to_user_tree, offset, len_ent_id);
985 offset += len_ent_id;
987 len_tseq_num = (retval & HDR_LEN_TSEQ_NUM) +1;
988 dissect_cfdp_tseq_num(tvb, pinfo, cfdp_msg_to_user_tree, offset, len_tseq_num);
989 offset += len_tseq_num;
990 break;
992 default:
993 break;
995 }else{
996 proto_tree_add_item(cfdp_msg_to_user_tree, hf_cfdp_message_to_user, tvb, offset, tlv_len, ENC_NA);
997 offset += tlv_len;
1000 return offset;
1003 /* Dissect the Fault Handler Override TLV */
1004 static uint32_t dissect_cfdp_fault_handler_overr_tlv(tvbuff_t *tvb, proto_tree *tree, uint32_t ext_offset){
1006 uint8_t aux_byte, tlv_len;
1007 proto_tree *cfdp_fault_hdl_overr_tree;
1009 uint32_t offset = ext_offset;
1011 /* Get tlv len */
1012 tlv_len = tvb_get_uint8(tvb, offset);
1013 offset += 1;
1015 /* Create a subtree */
1016 cfdp_fault_hdl_overr_tree = proto_tree_add_subtree(tree, tvb, offset-2, tlv_len+2,
1017 ett_cfdp_fault_hdl_overr, NULL, "Fault Handler Override TLV");
1019 proto_tree_add_uint(cfdp_fault_hdl_overr_tree, hf_cfdp_tlv_len, tvb, offset-1, 1, tlv_len);
1021 aux_byte = tvb_get_uint8(tvb, offset);
1022 proto_tree_add_uint(cfdp_fault_hdl_overr_tree, hf_cfdp_condition_code, tvb, offset, 1, aux_byte);
1023 proto_tree_add_uint(cfdp_fault_hdl_overr_tree, hf_cfdp_handler_code, tvb, offset, 1, aux_byte);
1024 offset += 1;
1026 return offset;
1029 /* Dissect the Flow Label TLV */
1030 static uint32_t dissect_cfdp_flow_label_tlv(tvbuff_t *tvb, proto_tree *tree, uint32_t ext_offset){
1032 uint8_t tlv_len;
1033 proto_tree *cfdp_flow_label_tree;
1035 uint32_t offset = ext_offset;
1037 /* Get tlv len */
1038 tlv_len = tvb_get_uint8(tvb, offset);
1039 offset += 1;
1041 /* Create a subtree */
1042 cfdp_flow_label_tree = proto_tree_add_subtree(tree, tvb, offset-2, tlv_len+2,
1043 ett_cfdp_flow_label, NULL, "Flow Label TLV");
1045 /* It is undefined, so no specific encoding */
1046 proto_tree_add_item(cfdp_flow_label_tree, hf_cfdp_flow_label, tvb, offset, tlv_len, ENC_NA);
1048 return offset;
1051 /* Dissect the End of File PDU */
1052 static uint32_t dissect_cfdp_eof_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t ext_offset, unsigned ext_packet_len){
1054 uint8_t aux_byte, tlv_type, tlv_len;
1055 proto_tree *cfdp_fault_location_tree;
1057 uint32_t offset = ext_offset;
1058 unsigned cfdp_packet_data_length = ext_packet_len;
1060 aux_byte = tvb_get_uint8(tvb, offset);
1061 proto_tree_add_uint(tree, hf_cfdp_condition_code, tvb, offset, 1, aux_byte);
1062 proto_tree_add_uint(tree, hf_cfdp_spare_four, tvb, offset, 1, aux_byte);
1063 offset += 1;
1065 col_add_fstr(pinfo->cinfo, COL_INFO, "EOF (%s)", val_to_str_const((aux_byte & 0xF0) >> 4, cfdp_condition_codes, "Reserved Code"));
1067 proto_tree_add_checksum(tree, tvb, offset, hf_cfdp_file_checksum, -1, NULL, pinfo, 0, ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
1068 offset += 4;
1070 proto_tree_add_item(tree, hf_cfdp_file_size, tvb, offset, 4, ENC_BIG_ENDIAN);
1071 offset += 4;
1073 if(offset < cfdp_packet_data_length){
1074 tlv_type = tvb_get_uint8(tvb, offset);
1075 offset += 1;
1076 if(tlv_type == FAULT_LOCATION){
1077 tlv_len = tvb_get_uint8(tvb, offset);
1078 offset += 1;
1079 cfdp_fault_location_tree = proto_tree_add_subtree(tree, tvb, offset-2, tlv_len+2,
1080 ett_cfdp_fault_location, NULL, "Fault location TLV");
1082 proto_tree_add_item(cfdp_fault_location_tree, hf_cfdp_entity, tvb, offset, tlv_len, ENC_NA);
1083 offset += tlv_len;
1087 return offset;
1090 /* Dissect the Finished PDU */
1091 static uint32_t dissect_cfdp_finished_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t ext_offset, unsigned ext_packet_len){
1093 uint32_t offset = ext_offset;
1094 uint8_t tlv_type;
1095 uint64_t aux_byte;
1097 unsigned cfdp_packet_data_length = offset+ext_packet_len;
1099 proto_tree_add_bitmask_ret_uint64(tree, tvb, offset,
1100 hf_cfdp_finish_pdu_flags,
1101 ett_cfdp_finish_pdu_flags,
1102 cfdp_finish_pdu_flags,
1103 ENC_BIG_ENDIAN,
1104 &aux_byte);
1105 offset += 1;
1107 col_add_fstr(pinfo->cinfo, COL_INFO, "Finished PDU (%s)", val_to_str_const((aux_byte & 0xF0) >> 4, cfdp_condition_codes, "Reserved Code"));
1109 /* Add TLV fields */
1110 while(offset < cfdp_packet_data_length-1){
1111 tlv_type = tvb_get_uint8(tvb, offset);
1112 offset += 1;
1113 switch(tlv_type){
1114 case 0x00:
1115 offset += 2;
1116 break;
1117 case FILESTORE_RESP:
1118 offset = dissect_cfdp_filestore_resp_tlv(tvb, tree, offset);
1119 break;
1121 case FAULT_LOCATION:
1122 offset = dissect_cfdp_fault_location_tlv(tvb, tree, offset);
1123 break;
1125 default:
1126 break;
1130 return offset;
1133 /* Dissect the ACK PDU */
1134 static uint32_t dissect_cfdp_ack_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t ext_offset){
1136 uint8_t aux_byte;
1137 uint32_t offset = ext_offset;
1139 aux_byte = tvb_get_uint8(tvb, offset);
1140 proto_tree_add_uint(tree, hf_cfdp_dir_code_ack, tvb, offset, 1, aux_byte);
1141 proto_tree_add_uint(tree, hf_cfdp_dir_subtype_ack, tvb, offset, 1, aux_byte);
1142 offset += 1;
1144 col_add_fstr(pinfo->cinfo, COL_INFO, "ACK PDU (%s)", val_to_str_const((aux_byte & 0xF0) >> 4, cfdp_directive_codes, "Unknown PDU"));
1146 aux_byte = tvb_get_uint8(tvb, offset);
1147 proto_tree_add_uint(tree, hf_cfdp_condition_code, tvb, offset, 1, aux_byte);
1148 proto_tree_add_uint(tree, hf_cfdp_spare_two, tvb, offset, 1, aux_byte);
1149 proto_tree_add_uint(tree, hf_cfdp_trans_stat_ack, tvb, offset, 1, aux_byte);
1150 offset += 1;
1152 return offset;
1155 /* Dissect the Metadata PDU */
1156 static uint32_t dissect_cfdp_metadata_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t ext_offset, unsigned ext_packet_len){
1158 uint8_t aux_byte, tlv_type;
1159 unsigned cfdp_packet_data_length = ext_packet_len;
1160 uint32_t length;
1162 uint32_t offset = ext_offset;
1164 aux_byte = tvb_get_uint8(tvb, offset);
1165 proto_tree_add_uint(tree, hf_cfdp_segment_control, tvb, offset, 1, aux_byte);
1166 proto_tree_add_uint(tree, hf_cfdp_spare_seven, tvb, offset, 1, aux_byte);
1167 offset += 1;
1168 proto_tree_add_item(tree, hf_cfdp_file_size, tvb, offset, 4, ENC_BIG_ENDIAN);
1169 offset += 4;
1170 proto_tree_add_item_ret_uint(tree, hf_cfdp_src_file_name_len, tvb, offset, 1, ENC_NA, &length);
1171 offset += 1;
1172 if(length >0){
1173 proto_tree_add_item(tree, hf_cfdp_src_file_name, tvb, offset, length, ENC_ASCII);
1175 offset += length;
1176 proto_tree_add_item_ret_uint(tree, hf_cfdp_dst_file_name_len, tvb, offset, 1, ENC_NA, &length);
1177 offset += 1;
1178 if(length >0){
1179 proto_tree_add_item(tree, hf_cfdp_dst_file_name, tvb, offset, length, ENC_ASCII);
1181 offset += length;
1182 /* Add TLV fields */
1183 while(offset < cfdp_packet_data_length){
1184 tlv_type = tvb_get_uint8(tvb, offset);
1185 offset += 1;
1186 switch(tlv_type){
1187 case FILESTORE_REQ:
1188 offset = dissect_cfdp_filestore_req_tlv(tvb, tree, offset);
1189 break;
1191 case MSG_TO_USER:
1192 offset = dissect_cfdp_msg_to_user_tlv(tvb, pinfo, tree, offset);
1193 break;
1195 case FAULT_HDL_OVERR:
1196 offset = dissect_cfdp_fault_handler_overr_tlv(tvb, tree, offset);
1197 break;
1199 case FLOW_LABEL:
1200 offset = dissect_cfdp_flow_label_tlv(tvb, tree, offset);
1201 break;
1203 default:
1204 break;
1208 return offset;
1211 /* Dissect the NAK PDU */
1212 static uint32_t dissect_cfdp_nak_pdu(tvbuff_t *tvb, proto_tree *tree, uint32_t ext_offset, unsigned ext_packet_len){
1214 uint32_t offset = ext_offset;
1215 unsigned cfdp_packet_data_length = ext_packet_len;
1217 proto_tree_add_item(tree, hf_cfdp_nak_st_scope, tvb, offset, 4, ENC_BIG_ENDIAN);
1218 offset += 4;
1219 proto_tree_add_item(tree, hf_cfdp_nak_sp_scope, tvb, offset, 4, ENC_BIG_ENDIAN);
1220 offset += 4;
1221 proto_tree_add_item(tree, hf_cfdp_segment_requests, tvb, offset, cfdp_packet_data_length-9, ENC_NA);
1222 offset += cfdp_packet_data_length-9;
1224 return offset;
1227 /* Dissect the Prompt PDU */
1228 static uint32_t dissect_cfdp_prompt_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, uint32_t ext_offset){
1230 uint8_t aux_byte;
1231 uint32_t offset = ext_offset;
1233 aux_byte = tvb_get_uint8(tvb, offset);
1234 proto_tree_add_uint(tree, hf_cfdp_response_req, tvb, offset, 1, aux_byte);
1235 proto_tree_add_uint(tree, hf_cfdp_spare_seven, tvb, offset, 1, aux_byte);
1236 offset += 1;
1238 col_add_fstr(pinfo->cinfo, COL_INFO, "Prompt PDU (%s)", val_to_str_const((aux_byte & 0x80) >> 7, cfdp_response_req, "Unknown"));
1240 return offset;
1243 /* Dissect the Keep Alive PDU */
1244 static uint32_t dissect_cfdp_keep_alive_pdu(tvbuff_t *tvb, proto_tree *tree, uint32_t ext_offset){
1246 uint32_t offset = ext_offset;
1248 proto_tree_add_item(tree, hf_cfdp_progress, tvb, offset, 4, ENC_BIG_ENDIAN);
1249 offset += 4;
1251 return offset;
1254 /* Code to actually dissect the packets */
1255 static int
1256 dissect_cfdp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1258 int offset = 0;
1259 proto_item *cfdp_packet;
1260 proto_item *cfdp_tree;
1261 proto_item *cfdp_header;
1262 proto_tree *cfdp_header_tree;
1263 int cfdp_packet_length;
1264 int cfdp_packet_reported_length;
1265 int cfdp_packet_header_length;
1266 int cfdp_packet_data_length;
1267 int length;
1268 uint8_t first_byte;
1269 uint64_t retval;
1270 int len_ent_id;
1271 int len_tseq_num;
1273 col_set_str(pinfo->cinfo, COL_PROTOCOL, "CFDP");
1274 col_clear(pinfo->cinfo, COL_INFO);
1276 cfdp_packet_reported_length = tvb_reported_length_remaining(tvb, 0);
1277 cfdp_packet_header_length = (tvb_get_uint8(tvb, 3) & HDR_LEN_TSEQ_NUM) + 1 + 2*(((tvb_get_uint8(tvb, 3) & HDR_LEN_ENT_ID) >>4) +1) + CFDP_HEADER_FIXED_FIELDS_LEN;
1278 cfdp_packet_length = tvb_get_ntohs(tvb, 1) + cfdp_packet_header_length;
1280 /* Min length is size of header plus 2 octets, whereas max length is reported length.
1281 * If the length field in the CFDP header is outside of these bounds,
1282 * use the value it violates. Otherwise, use the length field value.
1284 if(cfdp_packet_length > cfdp_packet_reported_length)
1285 length = cfdp_packet_reported_length;
1286 else if(cfdp_packet_length < cfdp_packet_header_length + 2)
1287 length = cfdp_packet_header_length + 2;
1288 else
1289 length = cfdp_packet_length;
1291 /* Build the cfdp tree */
1292 cfdp_packet = proto_tree_add_item(tree, proto_cfdp, tvb, 0, length, ENC_NA);
1293 cfdp_tree = proto_item_add_subtree(cfdp_packet, ett_cfdp);
1295 cfdp_header_tree = proto_tree_add_subtree(cfdp_tree, tvb, offset, cfdp_packet_header_length,
1296 ett_cfdp_header, &cfdp_header, "CFDP Header");
1298 first_byte = tvb_get_uint8(tvb, offset);
1300 /* CRC code is not included in the packet data length */
1301 cfdp_packet_data_length = tvb_get_ntohs(tvb, 1)-2*((first_byte & HDR_CRCF) >>1);
1303 proto_tree_add_bitmask(cfdp_header_tree, tvb, offset,
1304 hf_cfdp_flags,
1305 ett_cfdp_flags,
1306 cfdp_flags,
1307 ENC_BIG_ENDIAN);
1308 offset += 1;
1310 proto_tree_add_item(cfdp_header_tree, hf_cfdp_data_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1311 offset += 2;
1313 proto_tree_add_bitmask_ret_uint64(cfdp_header_tree, tvb, offset,
1314 hf_cfdp_byte2,
1315 ett_cfdp_byte2,
1316 cfdp_byte2,
1317 ENC_BIG_ENDIAN,
1318 &retval);
1319 offset += 1;
1321 len_ent_id = ((retval & HDR_LEN_ENT_ID) >> 4) + 1;
1322 dissect_cfdp_src_entity_id(tvb, pinfo, cfdp_header_tree, offset, len_ent_id);
1323 offset += len_ent_id;
1325 len_tseq_num = (retval & HDR_LEN_TSEQ_NUM) +1;
1326 dissect_cfdp_tseq_num(tvb, pinfo, cfdp_header_tree, offset, len_tseq_num);
1327 offset += len_tseq_num;
1329 dissect_cfdp_dst_entity_id(tvb, pinfo, cfdp_header_tree, offset, len_ent_id);
1330 offset += len_ent_id;
1332 proto_item_set_end(cfdp_header, tvb, offset);
1334 /* Build the File Directive or the File Data tree */
1335 if(!(first_byte & HDR_TYPE_CFDP))
1337 proto_item *cfdp_file_directive_header;
1338 proto_tree *cfdp_file_directive_header_tree;
1339 uint8_t directive_code;
1341 cfdp_file_directive_header_tree = proto_tree_add_subtree(cfdp_tree, tvb, offset, cfdp_packet_data_length,
1342 ett_cfdp_file_directive_header, &cfdp_file_directive_header, "CFDP File Directive");
1344 directive_code = tvb_get_uint8(tvb, offset);
1345 proto_tree_add_uint(cfdp_file_directive_header_tree, hf_cfdp_file_directive_type, tvb, offset, 1, directive_code);
1346 offset += 1;
1348 col_add_fstr(pinfo->cinfo, COL_INFO, "%s PDU", val_to_str(directive_code, cfdp_directive_codes, "Reserved (%d)"));
1350 switch(directive_code)
1352 case EOF_PDU:
1353 offset = dissect_cfdp_eof_pdu(tvb, pinfo, cfdp_file_directive_header_tree, offset, cfdp_packet_data_length);
1354 break;
1356 case FINISHED_PDU:
1357 offset = dissect_cfdp_finished_pdu(tvb, pinfo, cfdp_file_directive_header_tree, offset, cfdp_packet_data_length);
1358 break;
1360 case ACK_PDU:
1361 offset = dissect_cfdp_ack_pdu(tvb, pinfo, cfdp_file_directive_header_tree, offset);
1362 break;
1364 case METADATA_PDU:
1365 offset = dissect_cfdp_metadata_pdu(tvb, pinfo, cfdp_file_directive_header_tree, offset, cfdp_packet_data_length);
1366 break;
1368 case NAK_PDU:
1369 offset = dissect_cfdp_nak_pdu(tvb, cfdp_file_directive_header_tree, offset, cfdp_packet_data_length);
1370 break;
1372 case PROMPT_PDU:
1373 offset = dissect_cfdp_prompt_pdu(tvb, pinfo, cfdp_file_directive_header_tree, offset);
1374 break;
1376 case KEEP_ALIVE_PDU:
1377 offset = dissect_cfdp_keep_alive_pdu(tvb, cfdp_file_directive_header_tree, offset);
1378 break;
1380 default:
1381 break;
1384 proto_item_set_end(cfdp_file_directive_header, tvb, offset);
1386 }else{
1387 proto_tree *cfdp_file_data_header_tree;
1389 col_set_str(pinfo->cinfo, COL_INFO, "File Data PDU");
1391 cfdp_file_data_header_tree = proto_tree_add_subtree(cfdp_tree, tvb, offset, cfdp_packet_data_length,
1392 ett_cfdp_file_data_header, NULL, "CFDP File Data");
1394 proto_tree_add_item(cfdp_file_data_header_tree, hf_cfdp_file_data_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
1396 offset += 4;
1398 proto_tree_add_item(cfdp_file_data_header_tree, hf_cfdp_user_data, tvb, offset, cfdp_packet_data_length-4, ENC_NA);
1399 offset += cfdp_packet_data_length-4;
1402 if(first_byte & HDR_CRCF){
1403 proto_item *cfdp_crc;
1404 proto_tree *cfdp_crc_tree;
1406 cfdp_crc_tree = proto_tree_add_subtree(cfdp_tree, tvb, offset, 2, ett_cfdp_crc, &cfdp_crc, "CRC");
1408 proto_tree_add_item(cfdp_crc_tree, hf_cfdp_crc, tvb, offset, 2, ENC_BIG_ENDIAN);
1409 offset += 2;
1411 proto_item_set_end(cfdp_crc, tvb, offset);
1413 /* Give the data dissector any bytes past the CFDP packet length */
1414 call_data_dissector(tvb_new_subset_remaining(tvb, offset), pinfo, tree);
1415 return tvb_captured_length(tvb);
1418 void
1419 dissect_cfdp_as_subtree(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset)
1421 proto_tree *cfdp_header_tree = NULL;
1422 proto_tree *cfdp_sub_tree = NULL;
1423 proto_item *payload_item = NULL;
1424 proto_tree *cfdp_tree = NULL;
1425 proto_item *cfdp_header;
1426 int cfdp_data_len;
1427 int len_ent_id;
1428 int len_tseq_num;
1429 uint64_t first_byte;
1430 uint64_t retval;
1432 cfdp_tree = proto_tree_add_subtree(tree, tvb, offset, -1, ett_cfdp_proto,
1433 &payload_item, "Payload Data: CFDP Protocol");
1435 cfdp_sub_tree = proto_item_add_subtree(cfdp_tree, ett_cfdp);
1436 cfdp_header_tree = proto_tree_add_subtree(cfdp_sub_tree, tvb, offset, -1,
1437 ett_cfdp_header, &cfdp_header, "CFDP Header");
1439 proto_tree_add_bitmask_ret_uint64(cfdp_header_tree, tvb, offset,
1440 hf_cfdp_flags,
1441 ett_cfdp_flags,
1442 cfdp_flags,
1443 ENC_BIG_ENDIAN,
1444 &first_byte);
1445 offset += 1;
1447 unsigned cfdp_data_end;
1448 cfdp_data_len = tvb_get_uint16 (tvb, offset, ENC_BIG_ENDIAN);
1449 proto_tree_add_item(cfdp_header_tree, hf_cfdp_data_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1450 offset += 2;
1452 proto_tree_add_bitmask_ret_uint64(cfdp_header_tree, tvb, offset,
1453 hf_cfdp_byte2,
1454 ett_cfdp_byte2,
1455 cfdp_byte2,
1456 ENC_BIG_ENDIAN,
1457 &retval);
1458 offset += 1;
1460 len_ent_id = ((retval & HDR_LEN_ENT_ID) >> 4) + 1;
1461 dissect_cfdp_src_entity_id(tvb, pinfo, cfdp_header_tree, offset, len_ent_id);
1462 offset += len_ent_id;
1464 len_tseq_num = (retval & HDR_LEN_TSEQ_NUM) +1;
1465 dissect_cfdp_tseq_num(tvb, pinfo, cfdp_header_tree, offset, len_tseq_num);
1466 offset += len_tseq_num;
1468 dissect_cfdp_dst_entity_id(tvb, pinfo, cfdp_header_tree, offset, len_ent_id);
1469 offset += len_ent_id;
1471 cfdp_data_end = offset+cfdp_data_len;
1473 /* Build the File Directive or the File Data tree */
1474 if(!(first_byte & HDR_TYPE_CFDP))
1476 proto_item *cfdp_file_directive_header;
1477 proto_tree *cfdp_file_directive_header_tree;
1478 uint8_t directive_code;
1480 cfdp_file_directive_header_tree = proto_tree_add_subtree(cfdp_tree, tvb, offset, cfdp_data_len,
1481 ett_cfdp_file_directive_header, &cfdp_file_directive_header,
1482 "CFDP File Directive");
1484 directive_code = tvb_get_uint8(tvb, offset);
1485 proto_tree_add_uint(cfdp_file_directive_header_tree, hf_cfdp_file_directive_type, tvb, offset, 1, directive_code);
1486 offset += 1;
1488 col_add_fstr(pinfo->cinfo, COL_INFO, "%s PDU", val_to_str(directive_code, cfdp_directive_codes, "Reserved (%d)"));
1490 switch(directive_code)
1492 case EOF_PDU:
1493 offset = dissect_cfdp_eof_pdu(tvb, pinfo, cfdp_file_directive_header_tree, offset, cfdp_data_len);
1494 break;
1496 case FINISHED_PDU:
1497 offset = dissect_cfdp_finished_pdu(tvb, pinfo, cfdp_file_directive_header_tree, offset, cfdp_data_len);
1498 break;
1500 case ACK_PDU:
1501 offset = dissect_cfdp_ack_pdu(tvb, pinfo, cfdp_file_directive_header_tree, offset);
1502 break;
1504 case METADATA_PDU:
1505 offset = dissect_cfdp_metadata_pdu(tvb, pinfo, cfdp_file_directive_header_tree, offset, cfdp_data_len);
1506 break;
1508 case PROMPT_PDU:
1509 offset = dissect_cfdp_prompt_pdu(tvb, pinfo, cfdp_file_directive_header_tree, offset);
1510 break;
1512 case KEEP_ALIVE_PDU:
1513 offset = dissect_cfdp_keep_alive_pdu(tvb, cfdp_file_directive_header_tree, offset);
1514 break;
1516 default:
1517 break;
1520 }else{
1521 proto_tree *cfdp_file_data_header_tree;
1523 col_set_str(pinfo->cinfo, COL_INFO, "File Data PDU");
1525 cfdp_file_data_header_tree = proto_tree_add_subtree(cfdp_tree, tvb, offset, cfdp_data_len,
1526 ett_cfdp_file_data_header, NULL, "CFDP File Data");
1528 proto_tree_add_item(cfdp_file_data_header_tree, hf_cfdp_file_data_offset, tvb, offset, 4, ENC_BIG_ENDIAN);
1530 offset += 4;
1532 proto_tree_add_item(cfdp_file_data_header_tree, hf_cfdp_user_data, tvb, offset, cfdp_data_len-4, ENC_NA);
1533 offset += cfdp_data_len-4;
1536 if(first_byte & HDR_CRCF){
1537 proto_item *cfdp_crc;
1538 proto_tree *cfdp_crc_tree;
1540 cfdp_crc_tree = proto_tree_add_subtree(cfdp_tree, tvb, offset, 2, ett_cfdp_crc, &cfdp_crc, "CRC");
1542 proto_tree_add_item(cfdp_crc_tree, hf_cfdp_crc, tvb, offset, 2, ENC_BIG_ENDIAN);
1543 offset += 2;
1545 proto_item_set_end(cfdp_crc, tvb, offset);
1548 if ( cfdp_data_end>(unsigned)offset ) {
1549 proto_tree_add_string(cfdp_header_tree, hf_cfdp_file_data_pdu, tvb, offset, cfdp_data_len,
1550 wmem_strdup_printf(pinfo->pool, "<%d bytes>", cfdp_data_len));
1552 return;
1555 void
1556 proto_register_cfdp(void)
1558 static hf_register_info hf[] = {
1560 { &hf_cfdp_flags,
1561 { "Flags", "cfdp.flags",
1562 FT_UINT8, BASE_HEX, NULL, 0x0,
1563 NULL, HFILL }
1565 { &hf_cfdp_byte2,
1566 { "Byte2", "cfdp.byte2",
1567 FT_UINT8, BASE_HEX, NULL, 0x0,
1568 NULL, HFILL }
1570 { &hf_cfdp_proxy_fault_hdl_overr,
1571 { "Proxy Fault HDL Overr", "cfdp.proxy_fault_hdl_overr",
1572 FT_UINT8, BASE_HEX, NULL, 0x0,
1573 NULL, HFILL }
1575 { &hf_cfdp_proxy_trans_mode,
1576 { "Proxy Transmission Mode", "cfdp.proxy_trans_mode",
1577 FT_UINT8, BASE_HEX, NULL, 0x0,
1578 NULL, HFILL }
1580 { &hf_cfdp_proxy_segment_control_byte,
1581 { "Proxy Segment Control", "cfdp.proxy_segment_control",
1582 FT_UINT8, BASE_HEX, NULL, 0x0,
1583 NULL, HFILL }
1585 { &hf_cfdp_proxy_put_resp,
1586 { "Proxy Put Response", "cfdp.proxy_put_response",
1587 FT_UINT8, BASE_HEX, NULL, 0x0,
1588 NULL, HFILL }
1590 { &hf_cfdp_orig_trans_id,
1591 { "Originating Transaction ID", "cfdp.orig_trans_id",
1592 FT_UINT8, BASE_HEX, NULL, 0x0,
1593 NULL, HFILL }
1595 { &hf_cfdp_remote_stat_rep_req,
1596 { "Remote Status Report Request", "cfdp.remote_status_rep_req",
1597 FT_UINT8, BASE_HEX, NULL, 0x0,
1598 NULL, HFILL }
1600 { &hf_cfdp_remote_stat_rep_resp,
1601 { "Remote Status Report Response", "cfdp.remote_status_rep_resp",
1602 FT_UINT16, BASE_HEX, NULL, 0x0,
1603 NULL, HFILL }
1605 { &hf_cfdp_finish_pdu_flags,
1606 { "Finish PDU flags", "cfdp.finish_pdu_flags",
1607 FT_UINT8, BASE_HEX, NULL, 0x0,
1608 NULL, HFILL }
1610 { &hf_cfdp_remote_suspend_resume_req,
1611 { "Remote Suspend/Resume Request", "cfdp.remote_suspend_resume_req",
1612 FT_UINT8, BASE_HEX, NULL, 0x0,
1613 NULL, HFILL }
1615 { &hf_cfdp_remote_suspend_resume_resp,
1616 { "Remote Suspend/Resume Response", "cfdp.remote_suspend_resume_resp",
1617 FT_UINT16, BASE_HEX, NULL, 0x0,
1618 NULL, HFILL }
1620 { &hf_cfdp_version,
1621 { "Version", "cfdp.version",
1622 FT_UINT8, BASE_DEC, NULL, HDR_VERSION_CFDP,
1623 NULL, HFILL }
1625 { &hf_cfdp_pdu_type,
1626 { "PDU Type", "cfdp.pdu_type",
1627 FT_UINT8, BASE_DEC, VALS(cfdp_pdu_type), HDR_TYPE_CFDP,
1628 NULL, HFILL }
1630 { &hf_cfdp_direction,
1631 { "Direction", "cfdp.direction",
1632 FT_UINT8, BASE_DEC, VALS(cfdp_direction), HDR_DIR,
1633 NULL, HFILL }
1635 { &hf_cfdp_trans_mode,
1636 { "Trans. Mode", "cfdp.trans_mode",
1637 FT_UINT8, BASE_DEC, VALS(cfdp_trans_mode), HDR_TMODE,
1638 NULL, HFILL }
1640 { &hf_cfdp_trans_mode_2,
1641 { "Trans. Mode", "cfdp.trans_mode",
1642 FT_UINT8, BASE_DEC, VALS(cfdp_trans_mode), 0x01,
1643 NULL, HFILL }
1645 { &hf_cfdp_crc_flag,
1646 { "CRC Flag", "cfdp.crc_flag",
1647 FT_UINT8, BASE_DEC, VALS(cfdp_crc_flag), HDR_CRCF,
1648 NULL, HFILL }
1650 { &hf_cfdp_res1,
1651 { "Bit reserved 1", "cfdp.res1",
1652 FT_UINT8, BASE_DEC, NULL, HDR_RES1,
1653 NULL, HFILL }
1655 { &hf_cfdp_data_length,
1656 { "PDU Data length", "cfdp.data_length",
1657 FT_UINT16, BASE_DEC, NULL, 0x0,
1658 NULL, HFILL }
1660 {&hf_cfdp_file_data_pdu,
1661 {"CFDP File PDU Data", "cfdp.file_data_pdu",
1662 FT_STRINGZPAD, BASE_NONE, NULL, 0x0, NULL, HFILL}
1664 { &hf_cfdp_res2,
1665 { "Bit reserved 2", "cfdp.res2",
1666 FT_UINT8, BASE_DEC, NULL, 0x80,
1667 NULL, HFILL }
1669 { &hf_cfdp_entid_length,
1670 { "Length of entity IDs", "cfdp.entid_length",
1671 FT_UINT8, BASE_DEC, NULL, 0x70,
1672 NULL, HFILL }
1674 { &hf_cfdp_res3,
1675 { "Bit reserved 3", "cfdp.res3",
1676 FT_UINT8, BASE_DEC, NULL, 0x08,
1677 NULL, HFILL }
1679 { &hf_cfdp_transeqnum_length,
1680 { "Length of Transaction sequence number", "cfdp.transeqnum_length",
1681 FT_UINT8, BASE_DEC, NULL, 0x07,
1682 NULL, HFILL }
1684 { &hf_cfdp_srcid,
1685 { "Source entity ID", "cfdp.srcid",
1686 FT_UINT64, BASE_DEC, NULL, 0x0,
1687 NULL, HFILL }
1689 { &hf_cfdp_transeqnum,
1690 { "Transaction sequence number", "cfdp.transeqnum",
1691 FT_UINT64, BASE_DEC, NULL, 0x0,
1692 NULL, HFILL }
1694 { &hf_cfdp_dstid,
1695 { "Destination entity ID", "cfdp.dstid",
1696 FT_UINT64, BASE_DEC, NULL, 0x0,
1697 NULL, HFILL }
1699 { &hf_cfdp_file_directive_type,
1700 { "File Directive type", "cfdp.fdtype",
1701 FT_UINT8, BASE_DEC, VALS(cfdp_file_directive_type), 0x0,
1702 NULL, HFILL }
1704 { &hf_cfdp_file_data_offset,
1705 { "Offset", "cfdp.offset",
1706 FT_UINT32, BASE_DEC, NULL, 0x0,
1707 NULL, HFILL }
1709 { &hf_cfdp_progress,
1710 { "Progress", "cfdp.progress",
1711 FT_UINT32, BASE_DEC, NULL, 0x0,
1712 NULL, HFILL }
1714 { &hf_cfdp_dir_code_ack,
1715 { "PDU acknowledged", "cfdp.dir_code_ack",
1716 FT_UINT8, BASE_DEC, VALS(cfdp_file_directive_type), 0xf0,
1717 NULL, HFILL }
1719 { &hf_cfdp_dir_subtype_ack,
1720 { "Directive subtype code", "cfdp.dir_subtype_ack",
1721 FT_UINT8, BASE_DEC, NULL, 0x0f,
1722 NULL, HFILL }
1724 { &hf_cfdp_condition_code,
1725 { "Condition Code", "cfdp.condition_code",
1726 FT_UINT8, BASE_DEC, VALS(cfdp_condition_codes), 0xf0,
1727 NULL, HFILL }
1729 { &hf_cfdp_spare_one,
1730 { "Spare", "cfdp.spare_one",
1731 FT_UINT8, BASE_DEC, NULL, 0x08,
1732 NULL, HFILL }
1734 { &hf_cfdp_spare_one_2,
1735 { "Spare", "cfdp.spare_one_2",
1736 FT_UINT16, BASE_DEC, NULL, 0x0080,
1737 NULL, HFILL }
1739 { &hf_cfdp_spare_two,
1740 { "Spare", "cfdp.spare_two",
1741 FT_UINT8, BASE_DEC, NULL, 0x0c,
1742 NULL, HFILL }
1744 { &hf_cfdp_spare_four,
1745 { "Spare", "cfdp.spare_four",
1746 FT_UINT8, BASE_DEC, NULL, 0x0f,
1747 NULL, HFILL }
1749 { &hf_cfdp_spare_five,
1750 { "Spare", "cfdp.spare_five_b",
1751 FT_UINT16, BASE_DEC, NULL, 0x3E00,
1752 NULL, HFILL }
1754 { &hf_cfdp_spare_five_2,
1755 { "Spare", "cfdp.spare_five_b",
1756 FT_UINT16, BASE_DEC, NULL, 0x1F00,
1757 NULL, HFILL }
1759 { &hf_cfdp_spare_seven,
1760 { "Spare", "cfdp.spare_seven",
1761 FT_UINT8, BASE_DEC, NULL, 0x7f,
1762 NULL, HFILL }
1764 { &hf_cfdp_spare_seven_2,
1765 { "Spare", "cfdp.spare_seven_2",
1766 FT_UINT8, BASE_DEC, NULL, 0xfe,
1767 NULL, HFILL }
1769 { &hf_cfdp_trans_stat_ack,
1770 { "Transaction status", "cfdp.trans_stat_ack",
1771 FT_UINT8, BASE_DEC, VALS(cfdp_trans_stat_ack), 0x03,
1772 NULL, HFILL }
1774 { &hf_cfdp_trans_stat,
1775 { "Transaction status B", "cfdp.trans_stat_b",
1776 FT_UINT16, BASE_DEC, VALS(cfdp_trans_stat_ack), 0xC000,
1777 NULL, HFILL }
1779 { &hf_cfdp_trans_stat_2,
1780 { "Transaction status", "cfdp.trans_stat_2_b",
1781 FT_UINT16, BASE_DEC, VALS(cfdp_trans_stat_ack), 0x6000,
1782 NULL, HFILL }
1784 { &hf_cfdp_file_checksum,
1785 { "Checksum", "cfdp.checksum",
1786 FT_UINT32, BASE_HEX, NULL, 0x0,
1787 NULL, HFILL }
1789 { &hf_cfdp_file_size,
1790 { "File size", "cfdp.file_size",
1791 FT_UINT32, BASE_DEC, NULL, 0x0,
1792 NULL, HFILL }
1794 { &hf_cfdp_end_system_stat,
1795 { "End system status", "cfdp.end_system_stat",
1796 FT_UINT8, BASE_DEC, VALS(cfdp_end_system_stat), 0x08,
1797 NULL, HFILL }
1799 { &hf_cfdp_delivery_code,
1800 { "Delivery code", "cfdp.delivery_code",
1801 FT_UINT8, BASE_DEC, VALS(cfdp_delivery_code), 0x04,
1802 NULL, HFILL }
1804 { &hf_cfdp_file_stat,
1805 { "File status", "cfdp.file_status",
1806 FT_UINT8, BASE_DEC, VALS(cfdp_file_stat), 0x03,
1807 NULL, HFILL }
1809 { &hf_cfdp_segment_control,
1810 { "Segmentation control", "cfdp.segment_control",
1811 FT_UINT8, BASE_DEC, VALS(cfdp_segment_control), 0x80,
1812 NULL, HFILL }
1814 { &hf_cfdp_tlv_len,
1815 { "Length", "cfdp.tlv_length",
1816 FT_UINT8, BASE_DEC, NULL, 0x0,
1817 NULL, HFILL }
1819 { &hf_cfdp_src_file_name_len,
1820 {"Length of source file name", "cfdp.src_file_name_len", FT_UINT32, BASE_DEC, NULL, 0x0,
1821 NULL, HFILL}
1823 { &hf_cfdp_src_file_name,
1824 {"Source file name", "cfdp.src_file_name", FT_STRING, BASE_NONE, NULL, 0x0,
1825 NULL, HFILL}
1827 { &hf_cfdp_dst_file_name_len,
1828 {"Length of destination file name", "cfdp.dst_file_name_len", FT_UINT32, BASE_DEC, NULL, 0x0,
1829 NULL, HFILL}
1831 { &hf_cfdp_dst_file_name,
1832 {"Destination file name", "cfdp.dst_file_name", FT_STRING, BASE_NONE, NULL, 0x0,
1833 NULL, HFILL}
1835 { &hf_cfdp_first_file_name_len,
1836 {"Length of first file name", "cfdp.first_file_name_len", FT_UINT32, BASE_DEC, NULL, 0x0,
1837 NULL, HFILL}
1839 { &hf_cfdp_first_file_name,
1840 {"First file name", "cfdp.first_file_name", FT_STRING, BASE_NONE, NULL, 0x0,
1841 NULL, HFILL}
1843 { &hf_cfdp_second_file_name_len,
1844 {"Length of second file name", "cfdp.second_file_name_len", FT_UINT32, BASE_DEC, NULL, 0x0,
1845 NULL, HFILL}
1847 { &hf_cfdp_second_file_name,
1848 {"Second file name", "cfdp.second_file_name", FT_STRING, BASE_NONE, NULL, 0x0,
1849 NULL, HFILL}
1851 { &hf_cfdp_nak_st_scope,
1852 {"Start of scope", "cfdp.nak_st_scope", FT_UINT32, BASE_DEC, NULL, 0x0,
1853 NULL, HFILL}
1855 { &hf_cfdp_nak_sp_scope,
1856 {"End of scope", "cfdp.nak_sp_scope", FT_UINT32, BASE_DEC, NULL, 0x0,
1857 NULL, HFILL}
1859 { &hf_cfdp_crc,
1860 {"CRC", "cfdp.crc", FT_UINT16, BASE_HEX, NULL, 0x0,
1861 NULL, HFILL}
1863 { &hf_cfdp_action_code,
1864 {"Action code", "cfdp.action_code", FT_UINT8, BASE_DEC, VALS(cfdp_action_code), 0xF0,
1865 NULL, HFILL}
1867 { &hf_cfdp_status_code_1,
1868 {"Status code", "cfdp.status_code_1", FT_UINT8, BASE_DEC, VALS(cfdp_status_code_1), 0x0F,
1869 NULL, HFILL}
1871 { &hf_cfdp_status_code_2,
1872 {"Status code", "cfdp.status_code_2", FT_UINT8, BASE_DEC, VALS(cfdp_status_code_2), 0x0F,
1873 NULL, HFILL}
1875 { &hf_cfdp_status_code_3,
1876 {"Status code", "cfdp.status_code_3", FT_UINT8, BASE_DEC, VALS(cfdp_status_code_3), 0x0F,
1877 NULL, HFILL}
1879 { &hf_cfdp_status_code_4,
1880 {"Status code", "cfdp.status_code_4", FT_UINT8, BASE_DEC, VALS(cfdp_status_code_4), 0x0F,
1881 NULL, HFILL}
1883 { &hf_cfdp_status_code_5,
1884 {"Status code", "cfdp.status_code_5", FT_UINT8, BASE_DEC, VALS(cfdp_status_code_5), 0x0F,
1885 NULL, HFILL}
1887 { &hf_cfdp_status_code_6,
1888 {"Status code", "cfdp.status_code_6", FT_UINT8, BASE_DEC, VALS(cfdp_status_code_6), 0x0F,
1889 NULL, HFILL}
1891 { &hf_cfdp_status_code_7,
1892 {"Status code", "cfdp.status_code_7", FT_UINT8, BASE_DEC, VALS(cfdp_status_code_7), 0x0F,
1893 NULL, HFILL}
1895 { &hf_cfdp_status_code_8,
1896 {"Status code", "cfdp.status_code_8", FT_UINT8, BASE_DEC, VALS(cfdp_status_code_8), 0x0F,
1897 NULL, HFILL}
1899 { &hf_cfdp_handler_code,
1900 { "Handler Code", "cfdp.handler_code",
1901 FT_UINT8, BASE_DEC, VALS(cfdp_handler_codes), 0x0F,
1902 NULL, HFILL }
1904 { &hf_cfdp_proxy_msg_type,
1905 { "Proxy Message Type", "cfdp.proxy_msg_type",
1906 FT_UINT8, BASE_DEC | BASE_EXT_STRING, &cfdp_proxy_msg_type_ext, 0x0,
1907 NULL, HFILL }
1909 { &hf_cfdp_proxy_segment_control,
1910 { "Segmentation control", "cfdp.proxy_segment_control",
1911 FT_UINT8, BASE_DEC, VALS(cfdp_segment_control), 0x01,
1912 NULL, HFILL }
1914 { &hf_cfdp_proxy_delivery_code,
1915 { "Delivery code", "cfdp.proxy_delivery_code",
1916 FT_UINT8, BASE_DEC, VALS(cfdp_delivery_code), 0x04,
1917 NULL, HFILL }
1919 { &hf_cfdp_response_req,
1920 { "Response required", "cfdp.response_req",
1921 FT_UINT8, BASE_DEC, VALS(cfdp_response_req), 0x80,
1922 NULL, HFILL }
1924 { &hf_cfdp_directory_name,
1925 {"Directory Name", "cfdp.directory_name", FT_STRING, BASE_NONE, NULL, 0x0,
1926 NULL, HFILL}
1928 { &hf_cfdp_directory_file_name,
1929 {"Directory File Name", "cfdp.directory_file_name", FT_STRING, BASE_NONE, NULL, 0x0,
1930 NULL, HFILL}
1932 { &hf_cfdp_listing_resp_code,
1933 {"Listing Response Code", "cfdp.listing_resp_code",
1934 FT_UINT8, BASE_DEC, VALS(cfdp_listing_resp_code), 0x80,
1935 NULL, HFILL}
1937 { &hf_cfdp_report_file_name,
1938 {"Report File Name", "cfdp.report_file_name", FT_STRING, BASE_NONE, NULL, 0x0,
1939 NULL, HFILL}
1941 { &hf_cfdp_rep_resp_code,
1942 {"Report Response Code", "cfdp.rep_resp_code_b",
1943 FT_UINT16, BASE_DEC, VALS(cfdp_rep_resp_code), 0x0100,
1944 NULL, HFILL}
1946 { &hf_cfdp_suspension_ind,
1947 {"Suspension indicator", "cfdp.suspension_ind_b",
1948 FT_UINT16, BASE_DEC, VALS(cfdp_suspension_ind), 0x8000,
1949 NULL, HFILL}
1951 { &hf_cfdp_filestore_message_len,
1952 {"Length of filestore message", "cfdp.filestore_message_len", FT_UINT32, BASE_DEC, NULL, 0x0,
1953 NULL, HFILL}
1956 /* Generated from convert_proto_tree_add_text.pl */
1957 { &hf_cfdp_filestore_message, { "Filestore Message", "cfdp.filestore_message", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1958 { &hf_cfdp_entity, { "Entity", "cfdp.entity", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1959 { &hf_cfdp_message_to_user, { "Message to User", "cfdp.message_to_user", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1960 { &hf_cfdp_flow_label, { "Flow label", "cfdp.flow_label", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1961 { &hf_cfdp_segment_requests, { "Segment requests", "cfdp.segment_requests", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1962 { &hf_cfdp_user_data, { "User Data", "cfdp.user_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1966 /* Setup protocol subtree array */
1967 static int *ett[] = {
1968 &ett_cfdp,
1969 &ett_cfdp_flags,
1970 &ett_cfdp_byte2,
1971 &ett_cfdp_proxy_fault_hdl_overr,
1972 &ett_cfdp_proxy_trans_mode,
1973 &ett_cfdp_proxy_segment_control_byte,
1974 &ett_cfdp_proxy_put_resp,
1975 &ett_cfdp_orig_trans_id,
1976 &ett_cfdp_remote_suspend_resume_req,
1977 &ett_cfdp_remote_suspend_resume_resp,
1978 &ett_cfdp_remote_stat_rep_req,
1979 &ett_cfdp_remote_stat_rep_resp,
1980 &ett_cfdp_finish_pdu_flags,
1981 &ett_cfdp_header,
1982 &ett_cfdp_file_directive_header,
1983 &ett_cfdp_file_data_header,
1984 &ett_cfdp_fault_location,
1985 &ett_cfdp_crc,
1986 &ett_cfdp_filestore_req,
1987 &ett_cfdp_filestore_resp,
1988 &ett_cfdp_msg_to_user,
1989 &ett_cfdp_fault_hdl_overr,
1990 &ett_cfdp_flow_label,
1991 &ett_cfdp_proto
1994 static ei_register_info ei[] = {
1995 { &ei_cfdp_bad_length, { "cfdp.bad_length", PI_MALFORMED, PI_ERROR, "Bad length field", EXPFILL }},
1998 expert_module_t* expert_cfdp;
2000 /* Register the protocol name and description */
2001 proto_cfdp = proto_register_protocol("CFDP", "CFDP", "cfdp");
2003 /* Required function calls to register the header fields and subtrees used */
2004 proto_register_field_array(proto_cfdp, hf, array_length(hf));
2005 proto_register_subtree_array(ett, array_length(ett));
2006 expert_cfdp = expert_register_protocol(proto_cfdp);
2007 expert_register_field_array(expert_cfdp, ei, array_length(ei));
2009 cfdp_handle = register_dissector("cfdp", dissect_cfdp, proto_cfdp);
2012 void
2013 proto_reg_handoff_cfdp(void)
2015 dissector_add_uint("ccsds.apid", CFDP_APID, cfdp_handle);
2016 dissector_add_for_decode_as_with_preference("udp.port", cfdp_handle);
2020 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2022 * Local variables:
2023 * c-basic-offset: 4
2024 * tab-width: 8
2025 * indent-tabs-mode: nil
2026 * End:
2028 * vi: set shiftwidth=4 tabstop=8 expandtab:
2029 * :indentSize=4:tabSize=8:noTabs=true: