2 * Routines for docsis dissection
3 * Copyright 2002, Anand V. Narwani <anand[AT]narwani.org>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
13 /* This code is based on the DOCSIS 1.1 specification available at:
14 * http://www.cablelabs.com/wp-content/uploads/specdocs/CM-SP-RFIv1.1-C01-050907.pdf
16 * This code was updated to include DOCSIS 3.1 specification details available at:
17 * http://www.cablelabs.com/wp-content/uploads/specdocs/CM-SP-MULPIv3.1-I09-160602.pdf
19 * Updates are backward compatible with previous DOCSIS spcifications.
21 * DOCSIS Captures can be facilitated using the Cable Monitor Feature
22 * available on Cisco Cable Modem Termination Systems:
23 * https://www.cisco.com/c/en/us/td/docs/cable/cmts/config_guide/b_cmts_security_and_cable_monitoring_features/b_cmts_security_and_cable_monitoring_features_chapter_010.html
25 * This dissector depends on the presence of a DOCSIS enapsulation type.
26 * There is no simple way to distinguish DOCSIS Frames from Ethernet frames,
27 * since the frames are copied from the RF interface on the CMTS to
28 * a Fast Ethernet interface; thus a preference was needed to enable
29 * the DOCSIS encapsulation type.
31 * Libpcap 0.7 and later allow a link-layer header type to be specified for
32 * some interfaces on some platforms; for Ethernet interfaces, they allow
33 * DOCSIS to be specified. If an Ethernet capture is done with a link-layer
34 * type of DOCSIS, the file will have a link-layer header type of DLT_DOCSIS;
35 * Wireshark will treat the frames in that capture as DOCSIS frames, even
36 * if the preference mentioned above isn't enabled.
41 #include <epan/etypes.h>
42 #include <epan/expert.h>
43 #include <epan/packet.h>
44 #include <epan/prefs.h>
45 #include <epan/reassemble.h>
46 #include <epan/addr_resolv.h>
48 #include <epan/crc16-tvb.h>
49 #include <epan/crc32-tvb.h>
51 void proto_register_docsis(void);
52 void proto_reg_handoff_docsis(void);
54 /* Assume all packets have an FCS */
55 static bool docsis_check_fcs
= true;
56 static bool docsis_dissect_encrypted_frames
;
58 #define DOCSIS_MIN_HEADER_LEN 6
60 #define FCTYPE_PACKET 0x00
61 #define FCTYPE_SPECIAL 0x01
62 #define FCTYPE_ISOLAT 0x02
63 #define FCTYPE_MACSPC 0x03
65 #define FCPARM_TIMING_HDR 0x00
66 #define FCPARM_MAC_MGMT_HDR 0x01
67 #define FCPARM_RQST_FRM 0x02
68 #define FCPARM_FRAG_HDR 0x03
69 #define FCPARM_QUEUE_DEPTH_REQ_FRM 0x04
70 #define FCPARM_CONCAT_HDR 0x1C
72 #define EXT_HDR_OFF 0x00
73 #define EXT_HDR_ON 0x01
75 #define FRAG_FCS_LEN 4
76 #define FRAG_FIRST 0x20
77 #define FRAG_MIDDLE 0x00
78 #define FRAG_LAST 0x10
80 #define EH_NULL_CONFIG 0
85 #define EH_SFLOW_HDR_DOWN 5
86 #define EH_SFLOW_HDR_UP 6
88 #define EH_DS_SERVICE 8
89 #define EH_PATH_VERIFY 9
90 #define EH_RESERVED_10 10
91 #define EH_RESERVED_11 11
92 #define EH_RESERVED_12 12
93 #define EH_RESERVED_13 13
94 #define EH_RESERVED_14 14
95 #define EH_EXTENDED 15
97 /* Initialize the protocol and registered fields */
98 static int proto_docsis
;
99 static int hf_docsis_fctype
;
100 static int hf_docsis_machdr_fcparm
;
101 static int hf_docsis_fcparm
;
102 static int hf_docsis_exthdr
;
103 static int hf_docsis_concat_cnt
;
104 static int hf_docsis_macparm
;
105 static int hf_docsis_ehdrlen
;
106 static int hf_docsis_len
;
107 static int hf_docsis_eh_type
;
108 static int hf_docsis_eh_len
;
109 static int hf_docsis_eh_val
;
110 static int hf_docsis_ehx_type
;
111 static int hf_docsis_ehx_len
;
112 static int hf_docsis_frag_rsvd
;
113 static int hf_docsis_frag_first
;
114 static int hf_docsis_frag_last
;
115 static int hf_docsis_frag_seq
;
116 static int hf_docsis_sid
;
117 static int hf_docsis_mini_slots
;
118 static int hf_docsis_requested_size
;
119 static int hf_docsis_hcs
;
120 static int hf_docsis_hcs_status
;
121 static int hf_docsis_bpi_en
;
122 static int hf_docsis_toggle_bit
;
123 static int hf_docsis_key_seq
;
124 static int hf_docsis_ehdr_ver
;
125 static int hf_docsis_said
;
126 static int hf_docsis_ehdr_phsi
;
127 static int hf_docsis_ehdr_qind
;
128 static int hf_docsis_ehdr_grants
;
129 static int hf_docsis_reserved
;
130 static int hf_docsis_ehdr_ds_traffic_pri
;
131 static int hf_docsis_ehdr_ds_seq_chg_cnt
;
132 static int hf_docsis_ehdr_ds_dsid
;
133 static int hf_docsis_ehdr_ds_pkt_seq_num
;
134 static int hf_docsis_ehdr_bpup2_bpi_en
;
135 static int hf_docsis_ehdr_bpup2_toggle_bit
;
136 static int hf_docsis_ehdr_bpup2_key_seq
;
137 static int hf_docsis_ehdr_bpup2_ver
;
138 static int hf_docsis_ehdr_bpup2_sid
;
139 static int hf_docsis_ehdr_pv_st_refpt
;
140 static int hf_docsis_ehdr_pv_timestamp
;
142 static int hf_docsis_fragments
;
143 static int hf_docsis_fragment
;
144 static int hf_docsis_fragment_overlap
;
145 static int hf_docsis_fragment_overlap_conflict
;
146 static int hf_docsis_fragment_multiple_tails
;
147 static int hf_docsis_fragment_too_long_fragment
;
148 static int hf_docsis_fragment_error
;
149 static int hf_docsis_fragment_count
;
150 static int hf_docsis_reassembled_in
;
151 static int hf_docsis_reassembled_length
;
152 static int hf_docsis_reassembled_data
;
153 static int hf_docsis_frag_fcs
;
154 static int hf_docsis_frag_fcs_status
;
156 static int hf_docsis_dst
;
157 static int hf_docsis_dst_resolved
;
158 static int hf_docsis_src
;
159 static int hf_docsis_src_resolved
;
160 static int hf_docsis_lg
;
161 static int hf_docsis_ig
;
162 static int hf_docsis_encrypted_payload
;
164 static dissector_handle_t docsis_handle
;
165 static dissector_handle_t eth_withoutfcs_handle
;
166 static dissector_handle_t docsis_mgmt_handle
;
168 static dissector_table_t docsis_dissector_table
;
171 static expert_field ei_docsis_hcs_bad
;
172 static expert_field ei_docsis_len
;
173 static expert_field ei_docsis_frag_fcs_bad
;
174 static expert_field ei_docsis_eh_len
;
176 /* Initialize the subtree pointers */
177 static int ett_docsis
;
179 static int ett_docsis_fragments
;
180 static int ett_docsis_fragment
;
183 static const value_string fctype_vals
[] = {
184 {FCTYPE_PACKET
, "Packet PDU"},
185 {FCTYPE_SPECIAL
, "Special Use"},
186 {FCTYPE_ISOLAT
, "Isolation PDU"},
187 {FCTYPE_MACSPC
, "MAC Specific"},
191 static const value_string eh_type_vals
[] = {
192 {0, "NULL Configuration Parameter"},
193 {EH_REQUEST
, "Request"},
194 {EH_ACK_REQ
, "Acknowledgement Requested"},
195 {EH_BP_UP
, "Upstream Privacy Element"},
196 {EH_BP_DOWN
, "Downstream Privacy Element"},
197 {EH_SFLOW_HDR_UP
, "Service Flow EH; PHS Header Upstream"},
198 {EH_SFLOW_HDR_DOWN
, "Service Flow EH; PHS Header Downstream"},
199 {EH_BP_UP2
, "Upstream Privacy with Multi Channel"},
200 {EH_DS_SERVICE
, "Downstream Service"},
201 {EH_PATH_VERIFY
, "Path Verify"},
202 {EH_RESERVED_10
, "Reserved"},
203 {EH_RESERVED_11
, "Reserved"},
204 {EH_RESERVED_12
, "Reserved"},
205 {EH_RESERVED_13
, "Reserved"},
206 {EH_RESERVED_14
, "Reserved"},
207 {EH_EXTENDED
, "Extended"},
211 static const value_string ms_fcparm_vals
[] = {
212 {FCPARM_TIMING_HDR
, "Timing Header"},
213 {FCPARM_MAC_MGMT_HDR
, "MAC Management Message"},
214 {FCPARM_RQST_FRM
, "Request Frame"},
215 {FCPARM_FRAG_HDR
, "Fragmentation Header"},
216 {FCPARM_QUEUE_DEPTH_REQ_FRM
, "Queue Depth-based Request Frame"},
217 {FCPARM_CONCAT_HDR
, "Concatenation Header"},
221 static const value_string pkt_fcparm_vals
[] = {
223 {0x01, "DELAY/DUPLICATE/MULTICAST/BROADCAST"},
227 static const true_false_string exthdr_tfs
= {
228 "Extended Header Present",
229 "Extended Header Absent"
233 static const value_string local_proto_checksum_vals
[] = {
234 { PROTO_CHECKSUM_E_BAD
, "Bad" },
235 { PROTO_CHECKSUM_E_GOOD
, "Good" },
236 { PROTO_CHECKSUM_E_UNVERIFIED
, "Unverified" },
237 { PROTO_CHECKSUM_E_NOT_PRESENT
, "Not present" },
242 static const true_false_string qind_tfs
= {
247 static const true_false_string odd_even_tfs
= {
252 static const value_string unique_no_phs
[] = {
253 { 0, "No PHS on current packet" },
257 /* Fragmentation Flags / Sequence */
258 static uint8_t frag_flags
;
259 static uint8_t frag_seq
;
260 static uint16_t frag_sid
;
263 * Defragmentation of DOCSIS
265 static reassembly_table docsis_reassembly_table
;
268 static const fragment_items docsis_frag_items
= {
269 &ett_docsis_fragment
,
270 &ett_docsis_fragments
,
271 &hf_docsis_fragments
,
273 &hf_docsis_fragment_overlap
,
274 &hf_docsis_fragment_overlap_conflict
,
275 &hf_docsis_fragment_multiple_tails
,
276 &hf_docsis_fragment_too_long_fragment
,
277 &hf_docsis_fragment_error
,
278 &hf_docsis_fragment_count
,
279 &hf_docsis_reassembled_in
,
280 &hf_docsis_reassembled_length
,
281 &hf_docsis_reassembled_data
,
286 /* Code to Dissect the extended header; TLV Formatted headers */
288 dissect_ehdr (tvbuff_t
* tvb
, proto_tree
* tree
, packet_info
* pinfo
, bool *is_encrypted
)
290 proto_tree
*ehdr_tree
;
291 proto_item
*eh_length_item
;
297 ehdrlen
= tvb_get_uint8 (tvb
, 1);
300 ehdr_tree
= proto_tree_add_subtree(tree
, tvb
, pos
, ehdrlen
, ett_ehdr
, NULL
, "Extended Header");
302 while (pos
< ehdrlen
+ 4)
304 type
= (tvb_get_uint8 (tvb
, pos
) & 0xF0);
305 len
= (tvb_get_uint8 (tvb
, pos
) & 0x0F);
306 if ((((type
>> 4) & 0x0F)== 6) && (len
== 2))
308 proto_tree_add_uint_format_value(ehdr_tree
, hf_docsis_eh_type
, tvb
, pos
, 1, 0x60, "Unsolicited Grant Sync EHDR Sub-Element");
312 proto_tree_add_item (ehdr_tree
, hf_docsis_eh_type
, tvb
, pos
, 1, ENC_BIG_ENDIAN
);
315 eh_length_item
= proto_tree_add_item (ehdr_tree
, hf_docsis_eh_len
, tvb
, pos
, 1, ENC_BIG_ENDIAN
);
318 switch ((type
>> 4) & 0x0F)
321 /* Request: Minislots Requested */
324 proto_tree_add_item(ehdr_tree
, hf_docsis_mini_slots
, tvb
, pos
, 1, ENC_NA
);
325 proto_tree_add_item(ehdr_tree
, hf_docsis_sid
, tvb
, pos
+ 1, 2, ENC_BIG_ENDIAN
);
329 expert_add_info(pinfo
, eh_length_item
, &ei_docsis_eh_len
);
334 /* Deprecated in DOCSIS 3.1 */
337 proto_tree_add_item(ehdr_tree
, hf_docsis_sid
, tvb
, pos
, 2, ENC_BIG_ENDIAN
);
341 expert_add_info(pinfo
, eh_length_item
, &ei_docsis_eh_len
);
346 /* Upstream Privacy EH Element or Upstream Privacy with fragmentation */
347 proto_tree_add_item (ehdr_tree
, hf_docsis_key_seq
, tvb
, pos
, 1,
349 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_ver
, tvb
, pos
, 1,
351 proto_tree_add_item_ret_boolean (ehdr_tree
, hf_docsis_bpi_en
, tvb
, pos
+ 1, 1,
352 ENC_BIG_ENDIAN
, is_encrypted
);
353 proto_tree_add_item (ehdr_tree
, hf_docsis_toggle_bit
, tvb
, pos
+ 1,
355 proto_tree_add_item (ehdr_tree
, hf_docsis_sid
, tvb
, pos
+ 1, 2,
357 frag_sid
= tvb_get_uint8 (tvb
, pos
+1) & 0xCFFF;
358 proto_tree_add_item (ehdr_tree
, hf_docsis_mini_slots
, tvb
, pos
+ 3,
360 if (pinfo
->fragmented
)
362 proto_tree_add_item (ehdr_tree
, hf_docsis_frag_rsvd
, tvb
, pos
+4,
364 frag_flags
= tvb_get_uint8 (tvb
, pos
+4) & 0x30;
365 proto_tree_add_item (ehdr_tree
, hf_docsis_frag_first
, tvb
, pos
+4,
367 proto_tree_add_item (ehdr_tree
, hf_docsis_frag_last
, tvb
, pos
+4,
369 frag_seq
= tvb_get_uint8 (tvb
, pos
+4) & 0x0F;
370 proto_tree_add_item (ehdr_tree
, hf_docsis_frag_seq
, tvb
, pos
+4,
375 /* Downstream Privacy EH Element */
376 proto_tree_add_item (ehdr_tree
, hf_docsis_key_seq
, tvb
, pos
, 1,
378 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_ver
, tvb
, pos
, 1,
380 proto_tree_add_item_ret_boolean (ehdr_tree
, hf_docsis_bpi_en
, tvb
, pos
+ 1, 1,
381 ENC_BIG_ENDIAN
, is_encrypted
);
382 proto_tree_add_item (ehdr_tree
, hf_docsis_toggle_bit
, tvb
, pos
+ 1,
384 proto_tree_add_item (ehdr_tree
, hf_docsis_said
, tvb
, pos
+ 1, 2,
386 proto_tree_add_item (ehdr_tree
, hf_docsis_reserved
, tvb
, pos
+ 3, 1,
389 case EH_SFLOW_HDR_DOWN
:
390 /* Deprecated in DOCSIS 3.1, was Downstream Service Flow EH Element in earlier revisions */
391 case EH_SFLOW_HDR_UP
:
392 /* Deprecated in DOCSIS 3.1, was Upstream Service Flow EH Element in earlier revisions */
393 proto_tree_add_item(ehdr_tree
, hf_docsis_ehdr_phsi
, tvb
, pos
, 1, ENC_BIG_ENDIAN
);
397 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_qind
, tvb
, pos
+1, 1, ENC_BIG_ENDIAN
);
398 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_grants
, tvb
, pos
+1, 1, ENC_BIG_ENDIAN
);
402 /* Upstream Privacy EH Element, version 2, with no piggyback request */
403 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_bpup2_key_seq
, tvb
, pos
, 1,
405 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_bpup2_ver
, tvb
, pos
, 1,
407 proto_tree_add_item_ret_boolean (ehdr_tree
, hf_docsis_ehdr_bpup2_bpi_en
, tvb
, pos
+ 1, 1,
408 ENC_BIG_ENDIAN
, is_encrypted
);
409 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_bpup2_toggle_bit
, tvb
, pos
+ 1,
411 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_bpup2_sid
, tvb
, pos
+ 1, 2,
415 /* Downstream Service EH Element */
416 proto_tree_add_item(ehdr_tree
, hf_docsis_ehdr_ds_traffic_pri
, tvb
, pos
, 1, ENC_BIG_ENDIAN
);
420 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_ds_dsid
, tvb
, pos
, 3, ENC_BIG_ENDIAN
);
425 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_ds_seq_chg_cnt
, tvb
, pos
, 1, ENC_BIG_ENDIAN
);
426 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_ds_dsid
, tvb
, pos
, 3, ENC_BIG_ENDIAN
);
427 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_ds_pkt_seq_num
, tvb
, pos
+3, 2, ENC_BIG_ENDIAN
);
431 /* Path Verify EH Element */
434 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_pv_st_refpt
, tvb
, pos
, 1, ENC_BIG_ENDIAN
);
435 proto_tree_add_item (ehdr_tree
, hf_docsis_ehdr_pv_timestamp
, tvb
, pos
+1, 4, ENC_BIG_ENDIAN
);
439 /* Extended EH Element, ignore eh_len */
440 proto_tree_add_item(ehdr_tree
, hf_docsis_ehx_type
, tvb
, pos
, 1, ENC_NA
);
442 proto_tree_add_item(ehdr_tree
, hf_docsis_ehx_len
, tvb
, pos
, 1, ENC_NA
);
443 len
= tvb_get_uint8(tvb
, pos
);
448 proto_tree_add_item (ehdr_tree
, hf_docsis_eh_val
, tvb
, pos
,
457 /* Code to Dissect the Header Check Sequence field */
458 /* Return false in case FCS validation is enabled, but FCS is incorrect */
459 /* Return true in all other cases */
461 dissect_hcs_field (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* docsis_tree
, int hdrlen
)
463 /* dissect the header check sequence */
464 if(docsis_check_fcs
){
465 /* CRC-CCITT(16+12+5+1) */
466 uint16_t fcs
= g_ntohs(crc16_ccitt_tvb(tvb
, (hdrlen
- 2)));
467 proto_tree_add_checksum(docsis_tree
, tvb
, (hdrlen
- 2), hf_docsis_hcs
, hf_docsis_hcs_status
, &ei_docsis_hcs_bad
, pinfo
, fcs
, ENC_BIG_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
469 return (tvb_get_ntohs(tvb
, (hdrlen
- 2)) == fcs
) ? true : false;
473 proto_tree_add_checksum(docsis_tree
, tvb
, (hdrlen
- 2), hf_docsis_hcs
, hf_docsis_hcs_status
, &ei_docsis_hcs_bad
, pinfo
, 0, ENC_BIG_ENDIAN
, PROTO_CHECKSUM_NO_FLAGS
);
478 /* Code to Dissect the extended header length / MAC Param field and Length field */
479 /* The length field may condain a SID, but this logic is not handled here */
481 dissect_exthdr_length_field (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* docsis_tree
,
482 uint8_t exthdr
, uint16_t mac_parm
, uint16_t len_sid
, uint16_t *payload_length
, bool *is_encrypted
)
484 proto_item
*length_item
;
485 if (exthdr
== EXT_HDR_ON
)
487 /* Add in Extended Header Length */
488 proto_tree_add_item (docsis_tree
, hf_docsis_ehdrlen
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
489 length_item
= proto_tree_add_item (docsis_tree
, hf_docsis_len
, tvb
, 2, 2, ENC_BIG_ENDIAN
);
490 /* Validate PDU length */
491 if ((len_sid
- mac_parm
) > *payload_length
)
493 *payload_length
= len_sid
;
494 expert_add_info(pinfo
, length_item
, &ei_docsis_len
);
496 /* Pass off to the Extended Header dissection */
497 dissect_ehdr (tvb
, docsis_tree
, pinfo
, is_encrypted
);
501 /* Add in MAC Parm field only */
502 proto_tree_add_item (docsis_tree
, hf_docsis_macparm
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
503 length_item
= proto_tree_add_item (docsis_tree
, hf_docsis_len
, tvb
, 2, 2, ENC_BIG_ENDIAN
);
504 /* Validate PDU length */
505 if (len_sid
> *payload_length
)
507 *payload_length
= len_sid
;
508 expert_add_info(pinfo
, length_item
, &ei_docsis_len
);
514 /* Code to Dissect Encrypted DOCSIS Frames */
515 /* Print DST and SRC MACs and do not dissect the payload */
516 /* Implementation inferred from packet-eth.c */
518 dissect_encrypted_frame (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, const uint8_t fctype
, const uint8_t fcparm
)
520 uint32_t offset
, frame_len
;
521 const uint8_t *src_addr
, *dst_addr
;
522 const char *src_addr_name
, *dst_addr_name
;
523 proto_item
*addr_item
;
524 proto_tree
*addr_tree
=NULL
;
525 // tvbuff_t *next_tvb;
527 /* According to CM-SP-SEC-v3.1, PDU regions of the following
528 * frames must be encrypted when security is enabled:
529 * - Variable-length PDU MAC Frames;
530 * - Fragmentation MAC Frames;
531 * - Registration Request (REG-REQ-MP) MAC Management Message Frames;
532 * - Isolation PDU MAC Frames.
533 * There are also other corner cases when MAC Management frames might be encrypted
534 * (e.g. EH_TYPE=7 as described in CM-SP-MULPIv3.1-I15-180509 Table 17 and Table 20)
536 if (fctype
== FCTYPE_MACSPC
) {
537 if (fcparm
== FCPARM_MAC_MGMT_HDR
) {
538 col_append_str (pinfo
->cinfo
, COL_INFO
, " (Encrypted MMM)");
539 } else if (fcparm
== FCPARM_FRAG_HDR
) {
540 col_append_str (pinfo
->cinfo
, COL_INFO
, " (Encrypted Fragmentation MAC Frame)");
542 col_append_str (pinfo
->cinfo
, COL_INFO
, " (Encrypted)");
545 col_append_str (pinfo
->cinfo
, COL_INFO
, " (Encrypted)");
549 frame_len
= tvb_captured_length_remaining (tvb
, offset
);
555 dst_addr
= tvb_get_ptr(tvb
, 0, 6);
556 dst_addr_name
= get_ether_name(dst_addr
);
557 src_addr
= tvb_get_ptr(tvb
, 6, 6);
558 src_addr_name
= get_ether_name(src_addr
);
560 addr_item
= proto_tree_add_ether(tree
, hf_docsis_dst
, tvb
, 0, 6, dst_addr
);
561 addr_tree
= proto_item_add_subtree(addr_item
, ett_addr
);
562 addr_item
=proto_tree_add_string(addr_tree
, hf_docsis_dst_resolved
, tvb
, 0, 6,
564 proto_item_set_generated(addr_item
);
565 proto_tree_add_item(addr_tree
, hf_docsis_lg
, tvb
, 0, 3, ENC_BIG_ENDIAN
);
566 proto_tree_add_item(addr_tree
, hf_docsis_ig
, tvb
, 0, 3, ENC_BIG_ENDIAN
);
568 addr_item
= proto_tree_add_ether(tree
, hf_docsis_src
, tvb
, 6, 6, src_addr
);
569 addr_tree
= proto_item_add_subtree(addr_item
, ett_addr
);
570 addr_item
=proto_tree_add_string(addr_tree
, hf_docsis_src_resolved
, tvb
, 6, 6,
572 proto_item_set_generated(addr_item
);
573 proto_tree_add_item(addr_tree
, hf_docsis_lg
, tvb
, 6, 3, ENC_BIG_ENDIAN
);
574 proto_tree_add_item(addr_tree
, hf_docsis_ig
, tvb
, 6, 3, ENC_BIG_ENDIAN
);
579 proto_tree_add_item(tree
, hf_docsis_encrypted_payload
, tvb
, offset
, frame_len
- offset
, ENC_NA
);
584 /* Main DOCSIS Dissection Entry Point */
585 /* Code to Dissect the DOCSIS Frames */
587 dissect_docsis (tvbuff_t
* tvb
, packet_info
* pinfo
, proto_tree
* tree
, void* data _U_
)
593 uint16_t mac_parm
= 0;
594 uint8_t hdrlen
= DOCSIS_MIN_HEADER_LEN
;
595 uint16_t len_sid
= 0;
596 tvbuff_t
*next_tvb
= NULL
;
597 tvbuff_t
*mgt_tvb
= NULL
;
599 uint16_t payload_length
= 0;
600 /* uint16_t framelen = 0; */
601 bool save_fragmented
;
602 bool is_encrypted
= false;
605 proto_tree
*docsis_tree
;
607 /* Extract Frame Control parts */
608 fc
= tvb_get_uint8 (tvb
, 0); /* Frame Control Byte */
609 fctype
= (fc
>> 6) & 0x03; /* Frame Control Type: 2 MSB Bits */
610 fcparm
= (fc
>> 1) & 0x1F; /* Frame Control Parameter: Next 5 Bits */
611 exthdr
= (fc
& 0x01); /* Extended Header Bit: LSB */
613 /* Extract the MAC Parm; MAC Parm and SID offsets; change for a Queue Depth Request */
614 if (fcparm
== FCPARM_QUEUE_DEPTH_REQ_FRM
) {
615 mac_parm
= tvb_get_ntohs (tvb
, 1);
616 len_sid
= tvb_get_ntohs (tvb
, 3);
617 hdrlen
= DOCSIS_MIN_HEADER_LEN
+ 1; // 7-byte header for this message type
619 mac_parm
= tvb_get_uint8 (tvb
, 1);
620 len_sid
= tvb_get_ntohs (tvb
, 2);
623 /* Set Header Length based on presence of Extended header */
624 if (exthdr
== EXT_HDR_ON
) {
628 /* Captured Payload Length is based on the length of the header */
629 payload_length
= tvb_reported_length_remaining (tvb
, hdrlen
);
631 /* If this is a Request Frame, then pdulen is 0 and framelen is 6 */
632 if ((fctype
== FCTYPE_MACSPC
) && (fcparm
== FCPARM_RQST_FRM
|| fcparm
== FCPARM_QUEUE_DEPTH_REQ_FRM
))
636 if (fcparm == FCPARM_QUEUE_DEPTH_REQ_FRM)
637 framelen = DOCSIS_MIN_HEADER_LEN + 1;
639 framelen = DOCSIS_MIN_HEADER_LEN;
642 /* framelen = DOCSIS_MIN_HEADER_LEN + len_sid; */
643 pdulen
= len_sid
- (mac_parm
+ 2);
646 /* Make entries in Protocol column and Info column on summary display */
647 col_set_str (pinfo
->cinfo
, COL_PROTOCOL
, "DOCSIS");
652 col_set_str (pinfo
->cinfo
, COL_INFO
, "Packet PDU");
655 col_set_str (pinfo
->cinfo
, COL_INFO
, "Special Use");
658 col_set_str (pinfo
->cinfo
, COL_INFO
, "Isolation PDU");
661 if (fcparm
== FCPARM_RQST_FRM
)
662 col_add_fstr (pinfo
->cinfo
, COL_INFO
,
663 "Request Frame SID=%u Mini Slots=%u", len_sid
,
665 else if (fcparm
== FCPARM_QUEUE_DEPTH_REQ_FRM
)
666 col_add_fstr (pinfo
->cinfo
, COL_INFO
,
667 "Request Frame SID=%u, Requested Size=%uxN bytes", len_sid
,
669 else if (fcparm
== FCPARM_FRAG_HDR
)
670 col_set_str (pinfo
->cinfo
, COL_INFO
, "Fragmented Frame");
672 col_set_str (pinfo
->cinfo
, COL_INFO
, "MAC Specific");
674 } /* switch fctype */
676 ti
= proto_tree_add_item(tree
, proto_docsis
, tvb
, 0, hdrlen
, ENC_NA
);
677 docsis_tree
= proto_item_add_subtree (ti
, ett_docsis
);
679 /* add an item to the subtree, see section 1.6 for more information */
681 /* Add in FC Byte fields */
682 proto_tree_add_item (docsis_tree
, hf_docsis_fctype
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
688 proto_item_append_text (ti
, " Packet PDU");
689 proto_tree_add_item (docsis_tree
, hf_docsis_fcparm
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
690 proto_tree_add_item (docsis_tree
, hf_docsis_exthdr
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
691 /* Dissect Length field for a PDU */
692 dissect_exthdr_length_field (tvb
, pinfo
, docsis_tree
, exthdr
, mac_parm
, len_sid
, &payload_length
, &is_encrypted
);
693 /* Dissect Header Check Sequence field for a PDU */
694 fcs_correct
= dissect_hcs_field (tvb
, pinfo
, docsis_tree
, hdrlen
);
695 if (fcs_correct
&& pdulen
> 0)
697 next_tvb
= tvb_new_subset_remaining(tvb
, hdrlen
);
698 if(is_encrypted
&& !docsis_dissect_encrypted_frames
)
699 dissect_encrypted_frame (next_tvb
, pinfo
, docsis_tree
, fctype
, fcparm
);
701 call_dissector (eth_withoutfcs_handle
, next_tvb
, pinfo
, docsis_tree
);
707 proto_item_append_text (ti
, " Special Use PDU");
708 proto_tree_add_item (docsis_tree
, hf_docsis_machdr_fcparm
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
709 proto_tree_add_item (docsis_tree
, hf_docsis_exthdr
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
710 /* Dissect Length field for a PDU */
711 dissect_exthdr_length_field (tvb
, pinfo
, docsis_tree
, exthdr
, mac_parm
, len_sid
, &payload_length
, &is_encrypted
);
712 /* Dissect Header Check Sequence field for a PDU */
713 fcs_correct
= dissect_hcs_field (tvb
, pinfo
, docsis_tree
, hdrlen
);
715 if (fcparm
== FCPARM_MAC_MGMT_HDR
&& exthdr
== EXT_HDR_OFF
) {
716 /* Pass off to the DOCSIS Management dissector/s */
717 mgt_tvb
= tvb_new_subset_remaining(tvb
, hdrlen
);
718 if (is_encrypted
&& !docsis_dissect_encrypted_frames
)
719 dissect_encrypted_frame (mgt_tvb
, pinfo
, docsis_tree
, fctype
, fcparm
);
721 call_dissector (docsis_mgmt_handle
, mgt_tvb
, pinfo
, docsis_tree
);
723 /* Don't do anything for a Reserved Frame */
724 next_tvb
= tvb_new_subset_remaining(tvb
, hdrlen
);
725 call_data_dissector(next_tvb
, pinfo
, tree
);
732 proto_item_append_text (ti
, " Isolation PDU");
733 proto_tree_add_item (docsis_tree
, hf_docsis_fcparm
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
734 proto_tree_add_item (docsis_tree
, hf_docsis_exthdr
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
735 /* Dissect Length field for a PDU */
736 dissect_exthdr_length_field (tvb
, pinfo
, docsis_tree
, exthdr
, mac_parm
, len_sid
, &payload_length
, &is_encrypted
);
737 /* Dissect Header Check Sequence field for a PDU */
738 fcs_correct
= dissect_hcs_field (tvb
, pinfo
, docsis_tree
, hdrlen
);
739 if (fcs_correct
&& pdulen
> 0)
741 next_tvb
= tvb_new_subset_remaining(tvb
, hdrlen
);
742 if(is_encrypted
&& !docsis_dissect_encrypted_frames
)
743 dissect_encrypted_frame (next_tvb
, pinfo
, docsis_tree
, fctype
, fcparm
);
745 call_dissector (eth_withoutfcs_handle
, next_tvb
, pinfo
, docsis_tree
);
751 proto_item_append_text (ti
, " MAC-Specific PDU");
752 proto_tree_add_item (docsis_tree
, hf_docsis_machdr_fcparm
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
753 proto_tree_add_item (docsis_tree
, hf_docsis_exthdr
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
756 case FCPARM_TIMING_HDR
:
758 case FCPARM_MAC_MGMT_HDR
:
760 /* Dissect Length field for a PDU */
761 dissect_exthdr_length_field (tvb
, pinfo
, docsis_tree
, exthdr
, mac_parm
, len_sid
, &payload_length
, &is_encrypted
);
762 /* Dissect Header Check Sequence field for a PDU */
763 fcs_correct
= dissect_hcs_field (tvb
, pinfo
, docsis_tree
, hdrlen
);
766 /* Pass off to the DOCSIS Management dissector/s */
767 mgt_tvb
= tvb_new_subset_remaining(tvb
, hdrlen
);
768 if(is_encrypted
&& !docsis_dissect_encrypted_frames
)
769 dissect_encrypted_frame (mgt_tvb
, pinfo
, docsis_tree
, fctype
, fcparm
);
771 call_dissector (docsis_mgmt_handle
, mgt_tvb
, pinfo
, docsis_tree
);
775 case FCPARM_RQST_FRM
:
777 /* Decode for a Request Frame. No extended header */
778 proto_tree_add_uint (docsis_tree
, hf_docsis_mini_slots
, tvb
, 1, 1, mac_parm
);
779 proto_tree_add_uint (docsis_tree
, hf_docsis_sid
, tvb
, 2, 2, len_sid
);
780 /* Dissect Header Check Sequence field for a PDU */
781 fcs_correct
= dissect_hcs_field (tvb
, pinfo
, docsis_tree
, hdrlen
);
784 /* Don't do anything for a Request Frame, there is no data following it */
788 case FCPARM_FRAG_HDR
:
790 /* Check if this is a fragmentation header */
791 save_fragmented
= pinfo
->fragmented
;
792 pinfo
->fragmented
= true;
794 /* Dissect Length field for a PDU */
795 dissect_exthdr_length_field (tvb
, pinfo
, docsis_tree
, exthdr
, mac_parm
, len_sid
, &payload_length
, &is_encrypted
);
796 /* Dissect Header Check Sequence field for a PDU */
797 fcs_correct
= dissect_hcs_field (tvb
, pinfo
, docsis_tree
, hdrlen
);
800 /* Grab the Fragment FCS */
801 uint32_t sent_fcs
= tvb_get_ntohl(tvb
, (hdrlen
+ len_sid
- 4));
802 uint32_t fcs
= crc32_802_tvb(tvb
, tvb_captured_length(tvb
) - 4);
804 /* Only defragment valid frames with a good FCS */
807 fragment_head
*frag_msg
= NULL
;
808 frag_msg
= fragment_add_seq_check(&docsis_reassembly_table
,
810 frag_sid
, NULL
, /* ID for fragments belonging together */
811 frag_seq
, /* Fragment Sequence Number */
812 (len_sid
- 4), /* fragment length - to the end */
813 !(frag_flags
& FRAG_LAST
)); /* More fragments? */
815 next_tvb
= process_reassembled_data(tvb
, hdrlen
, pinfo
,
816 "Reassembled Message", frag_msg
, &docsis_frag_items
,
819 if (frag_flags
== FRAG_LAST
)
820 pinfo
->fragmented
= false;
822 pinfo
->fragmented
= true;
824 if (frag_msg
) { /* Reassembled */
825 proto_item_append_text (ti
, " (Message Reassembled)");
826 } else { /* Not last packet of reassembled Short Message */
827 proto_item_append_text (ti
, " (Message fragment %u)", frag_seq
);
833 /* By default assume an Ethernet payload */
834 if(is_encrypted
&& !docsis_dissect_encrypted_frames
)
835 dissect_encrypted_frame (next_tvb
, pinfo
, docsis_tree
, fctype
, fcparm
);
837 call_dissector (eth_withoutfcs_handle
, next_tvb
, pinfo
, docsis_tree
);
839 /* Otherwise treat as Data */
840 tvbuff_t
*payload_tvb
= tvb_new_subset_length_caplen(tvb
, hdrlen
, (len_sid
- 4), -1);
841 call_data_dissector(payload_tvb
, pinfo
, docsis_tree
);
844 /* Report frames with a bad FCS */
845 expert_add_info(pinfo
, ti
, &ei_docsis_frag_fcs_bad
);
847 /* Add the Fragment FCS to the end of the parent tree */
848 proto_tree_add_checksum(docsis_tree
, tvb
, (hdrlen
+ len_sid
- 4), hf_docsis_frag_fcs
, hf_docsis_frag_fcs_status
, &ei_docsis_frag_fcs_bad
, pinfo
, fcs
, ENC_BIG_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
850 pinfo
->fragmented
= save_fragmented
;
854 case FCPARM_QUEUE_DEPTH_REQ_FRM
:
856 /* Decode for a Queue-depth Based Request */
857 proto_tree_add_uint (docsis_tree
, hf_docsis_requested_size
, tvb
, 1, 2, mac_parm
);
858 proto_tree_add_uint (docsis_tree
, hf_docsis_sid
, tvb
, 3, 2, len_sid
);
859 /* Dissect Header Check Sequence field for a PDU */
860 fcs_correct
= dissect_hcs_field (tvb
, pinfo
, docsis_tree
, hdrlen
);
863 /* No PDU Payload for this frame */
867 case FCPARM_CONCAT_HDR
:
869 /* Decode for a Concatenated Header; ONLY for DOCSIS versions < 3.1. No Extended Header */
870 proto_item_append_text (ti
, " (Concatenated Header)");
871 proto_tree_add_item (docsis_tree
, hf_docsis_concat_cnt
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
872 proto_tree_add_item (docsis_tree
, hf_docsis_len
, tvb
, 2, 2, ENC_BIG_ENDIAN
);
873 /* Dissect Header Check Sequence field for a PDU */
874 fcs_correct
= dissect_hcs_field (tvb
, pinfo
, docsis_tree
, hdrlen
);
877 // There used to be a section of code here that recursively
878 // called dissect_docsis. It has been removed. If you plan on
879 // adding concatenated PDU support back you should consider
880 // doing something like the following:
881 // dissect_docsis(...) {
882 // while(we_have_pdus_remaining) {
883 // int pdu_len = dissect_docsis_pdu(...)
884 // if (pdu_len < 1) {
890 // Adding back this functionality using recursion might result
891 // in this dissector being disabled by default or removed entirely.
896 /* Unknown parameter, stop dissection */
898 } /* switch fcparm */
901 } /* switch fctype */
903 return tvb_captured_length(tvb
);
906 /* Register the protocol with Wireshark */
908 proto_register_docsis (void)
910 static hf_register_info hf
[] = {
912 {"FCType", "docsis.fctype",
913 FT_UINT8
, BASE_HEX
, VALS (fctype_vals
), 0xC0,
914 "Frame Control Type", HFILL
}
917 {"FCParm", "docsis.fcparm",
918 FT_UINT8
, BASE_DEC
, VALS (pkt_fcparm_vals
), 0x3E,
919 "Parameter Field", HFILL
}
921 {&hf_docsis_machdr_fcparm
,
922 {"FCParm", "docsis.fcparm",
923 FT_UINT8
, BASE_DEC
, VALS (ms_fcparm_vals
), 0x3E,
924 "Parameter Field", HFILL
}
927 {"EXTHDR", "docsis.exthdr",
928 FT_BOOLEAN
, 8, TFS (&exthdr_tfs
), 0x01,
929 "Extended Header Presence", HFILL
}
932 {"MACParm", "docsis.macparm",
933 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
934 "MAC Parameter Field", HFILL
}
936 {&hf_docsis_concat_cnt
,
937 {"Number of Concatenated Frames", "docsis.concat_cnt",
938 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
942 {"Extended Header Length (bytes)", "docsis.ehdrlen",
943 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
947 {"Length of the MAC frame (bytes)", "docsis.len",
948 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
949 "Length of the MAC frame, not counting the fixed-length MAC header", HFILL
}
952 {"Type", "docsis.ehdr.type",
953 FT_UINT8
, BASE_DEC
, VALS (eh_type_vals
), 0xF0,
957 {"Length", "docsis.ehdr.len",
958 FT_UINT8
, BASE_DEC
, NULL
, 0x0F,
962 {"Value", "docsis.ehdr.value",
963 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
966 {&hf_docsis_ehx_type
,
967 {"Extended Type", "docsis.ehdr.ehx_type",
968 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
972 {"Extended Length", "docsis.ehdr.ehx_len",
973 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
976 {&hf_docsis_frag_rsvd
,
977 {"Reserved", "docsis.frag_rsvd",
978 FT_UINT8
, BASE_DEC
, NULL
, 0xC0,
981 {&hf_docsis_frag_first
,
982 {"First Frame", "docsis.frag_first",
983 FT_BOOLEAN
, 8, NULL
, 0x20,
986 {&hf_docsis_frag_last
,
987 {"Last Frame", "docsis.frag_last",
988 FT_BOOLEAN
, 8, NULL
, 0x10,
991 {&hf_docsis_frag_seq
,
992 {"Fragmentation Sequence #", "docsis.frag_seq",
993 FT_UINT8
, BASE_DEC
, NULL
, 0x0F,
994 "Fragmentation Sequence Number", HFILL
}
997 {"SID", "docsis.ehdr.sid",
998 FT_UINT16
, BASE_DEC_HEX
, NULL
, 0x3FFF,
999 "Service Identifier", HFILL
}
1002 {"SAID", "docsis.ehdr.said",
1003 FT_UINT16
, BASE_DEC
, NULL
, 0x3FFF,
1004 "Security Association Identifier", HFILL
}
1006 {&hf_docsis_reserved
,
1007 {"Reserved", "docsis.ehdr.rsvd",
1008 FT_UINT8
, BASE_HEX
, NULL
, 0x0,
1009 "Reserved Byte", HFILL
}
1011 {&hf_docsis_mini_slots
,
1012 {"MiniSlots", "docsis.ehdr.minislots",
1013 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1014 "Mini Slots Requested", HFILL
}
1016 {&hf_docsis_requested_size
,
1017 {"Requested bytes in units of N bytes, N a parameter of the service flow for which this request is being made", "docsis.ehdr.reqsize",
1018 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1021 {&hf_docsis_key_seq
,
1022 {"Key Sequence", "docsis.ehdr.keyseq",
1023 FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
1026 {&hf_docsis_ehdr_ver
,
1027 {"Version", "docsis.ehdr.ver",
1028 FT_UINT8
, BASE_DEC
, NULL
, 0x0F,
1031 {&hf_docsis_ehdr_phsi
,
1032 {"Payload Header Suppression Index", "docsis.ehdr.phsi",
1033 FT_UINT8
, BASE_DEC
|BASE_SPECIAL_VALS
, VALS(unique_no_phs
), 0x0,
1036 {&hf_docsis_ehdr_qind
,
1037 {"Queue Indicator", "docsis.ehdr.qind",
1038 FT_BOOLEAN
, 8, TFS(&qind_tfs
), 0x80,
1041 {&hf_docsis_ehdr_grants
,
1042 {"Active Grants", "docsis.ehdr.act_grants",
1043 FT_UINT8
, BASE_DEC
, NULL
, 0x7F,
1046 {&hf_docsis_ehdr_bpup2_key_seq
,
1047 {"Key Sequence", "docsis.ehdr.bpup2_keyseq",
1048 FT_UINT8
, BASE_DEC
, NULL
, 0xF0,
1051 {&hf_docsis_ehdr_bpup2_ver
,
1052 {"Version", "docsis.ehdr.bpup2_ver",
1053 FT_UINT8
, BASE_DEC
, NULL
, 0x0F,
1056 {&hf_docsis_ehdr_bpup2_bpi_en
,
1057 {"Encryption", "docsis.ehdr.bpup2_bpi_en",
1058 FT_BOOLEAN
, 8, TFS (&tfs_enabled_disabled
), 0x80,
1059 "BPI Enable", HFILL
}
1061 {&hf_docsis_ehdr_bpup2_toggle_bit
,
1062 {"Toggle", "docsis.ehdr.bpup2_toggle_bit",
1063 FT_BOOLEAN
, 8, TFS (&odd_even_tfs
), 0x40,
1066 {&hf_docsis_ehdr_bpup2_sid
,
1067 {"SID", "docsis.ehdr.bpup2_sid",
1068 FT_UINT16
, BASE_DEC
, NULL
, 0x3FFF,
1069 "Service Identifier", HFILL
}
1071 { &hf_docsis_ehdr_pv_st_refpt
,
1072 { "Start Reference Point", "docsis.ehdr.pv_start_ref",
1073 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1076 { &hf_docsis_ehdr_pv_timestamp
,
1077 { "Timestamp", "docsis.ehdr.pv_timestamp",
1078 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1081 {&hf_docsis_ehdr_ds_traffic_pri
,
1082 {"DS Traffic Priority", "docsis.ehdr.ds_traffic_pri",
1083 FT_UINT8
, BASE_DEC
, NULL
, 0xE0,
1086 {&hf_docsis_ehdr_ds_seq_chg_cnt
,
1087 {"DS Sequence Change Count", "docsis.ehdr.ds_seq_chg_cnt",
1088 FT_UINT8
, BASE_DEC
, NULL
, 0x10,
1091 {&hf_docsis_ehdr_ds_dsid
,
1092 {"DS DSID", "docsis.ehdr.ds_dsid",
1093 FT_UINT32
, BASE_DEC
, NULL
, 0x0FFFFF,
1096 {&hf_docsis_ehdr_ds_pkt_seq_num
,
1097 {"DS Packet Sequence Number", "docsis.ehdr.ds_pkt_seq_num",
1098 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1102 {"Header check sequence", "docsis.hcs",
1103 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1106 { &hf_docsis_hcs_status
,
1107 { "HCS Status", "docsis.hcs.status",
1108 FT_UINT8
, BASE_NONE
, VALS(local_proto_checksum_vals
), 0x0,
1111 { &hf_docsis_bpi_en
,
1112 { "Encryption", "docsis.bpi_en",
1113 FT_BOOLEAN
, 8, TFS (&tfs_enabled_disabled
), 0x80,
1114 "BPI Enable", HFILL
}
1116 { &hf_docsis_toggle_bit
,
1117 { "Toggle", "docsis.toggle_bit",
1118 FT_BOOLEAN
, 8, TFS (&odd_even_tfs
), 0x40,
1121 { &hf_docsis_fragment_overlap
,
1122 { "Fragment overlap", "docsis.fragment.overlap",
1123 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1124 "Fragment overlaps with other fragments", HFILL
}
1126 { &hf_docsis_fragment_overlap_conflict
,
1127 { "Conflicting data in fragment overlap", "docsis.fragment.overlap.conflict",
1128 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1129 "Overlapping fragments contained conflicting data", HFILL
}
1131 { &hf_docsis_fragment_multiple_tails
,
1132 { "Multiple tail fragments found", "docsis.fragment.multipletails",
1133 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1134 "Several tails were found when defragmenting the packet", HFILL
}
1136 { &hf_docsis_fragment_too_long_fragment
,
1137 { "Fragment too long", "docsis.fragment.toolongfragment",
1138 FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
1139 "Fragment contained data past end of packet", HFILL
}
1141 { &hf_docsis_fragment_error
,
1142 { "Defragmentation error", "docsis.fragment.error",
1143 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
1144 "Defragmentation error due to illegal fragments", HFILL
}
1146 { &hf_docsis_fragment_count
,
1147 { "Fragment count", "docsis.fragment.count",
1148 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1151 { &hf_docsis_fragment
,
1152 { "DOCSIS Fragment", "docsis.fragment",
1153 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
1156 { &hf_docsis_fragments
,
1157 { "DOCSIS Fragments", "docsis.fragments",
1158 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1161 { &hf_docsis_reassembled_in
,
1162 { "Reassembled DOCSIS in frame", "docsis.reassembled_in",
1163 FT_FRAMENUM
, BASE_NONE
, NULL
, 0x0,
1164 "This DOCSIS packet is reassembled in this frame", HFILL
}
1166 { &hf_docsis_reassembled_length
,
1167 { "Reassembled DOCSIS length", "docsis.reassembled.length",
1168 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1169 "The total length of the reassembled payload", HFILL
}
1171 { &hf_docsis_reassembled_data
,
1172 { "Reassembled DOCSIS data", "docsis.reassembled.data",
1173 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1174 "The reassembled payload", HFILL
}
1176 { &hf_docsis_frag_fcs
,
1177 { "Fragment FCS", "docsis.frag.fcs",
1178 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1181 { &hf_docsis_frag_fcs_status
,
1182 { "Fragment FCS Status", "docsis.frag.fcs.status",
1183 FT_UINT8
, BASE_NONE
, VALS(local_proto_checksum_vals
), 0x0,
1186 { &hf_docsis_encrypted_payload
,
1187 { "Encrypted Payload", "docsis.encrypted_payload",
1188 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1189 "Encrypted data", HFILL
}
1193 static ei_register_info ei
[] = {
1194 { &ei_docsis_hcs_bad
, { "docsis.hcs_bad", PI_CHECKSUM
, PI_ERROR
, "Bad checksum", EXPFILL
}},
1195 { &ei_docsis_len
, { "docsis.len.past_end", PI_MALFORMED
, PI_ERROR
, "Length field value goes past the end of the payload", EXPFILL
}},
1196 { &ei_docsis_frag_fcs_bad
, { "docsis.frag.fcs_bad", PI_CHECKSUM
, PI_ERROR
, "Bad checksum", EXPFILL
}},
1197 { &ei_docsis_eh_len
, { "docsis.ehdr.len.past_end", PI_MALFORMED
, PI_ERROR
, "Extended Header Length Invalid!", EXPFILL
}}
1200 static int *ett
[] = {
1203 &ett_docsis_fragment
,
1204 &ett_docsis_fragments
,
1208 module_t
*docsis_module
;
1209 expert_module_t
* expert_docsis
;
1211 proto_docsis
= proto_register_protocol ("DOCSIS", "DOCSIS", "docsis");
1212 proto_register_field_array (proto_docsis
, hf
, array_length (hf
));
1213 proto_register_subtree_array (ett
, array_length (ett
));
1215 /* register expert notifications */
1216 expert_docsis
= expert_register_protocol(proto_docsis
);
1217 expert_register_field_array(expert_docsis
, ei
, array_length(ei
));
1219 /* Register configuration preferences */
1220 docsis_module
= prefs_register_protocol(proto_docsis
, NULL
);
1221 prefs_register_bool_preference(docsis_module
, "check_fcs",
1222 "Validate the DOCSIS checksum if possible",
1223 "Whether or not to validate the Header Check Sequence",
1225 prefs_register_bool_preference(docsis_module
, "dissect_encrypted_frames",
1226 "Ignore EH 'encrypted' bit",
1227 "Whether or not to attempt to dissect encrypted DOCSIS payload",
1228 &docsis_dissect_encrypted_frames
);
1231 docsis_dissector_table
= register_dissector_table ("docsis",
1232 "DOCSIS Encapsulation Type", proto_docsis
,
1233 FT_UINT8
, BASE_DEC
);
1236 docsis_handle
= register_dissector ("docsis", dissect_docsis
, proto_docsis
);
1237 reassembly_table_register(&docsis_reassembly_table
,
1238 &addresses_reassembly_table_functions
);
1242 proto_reg_handoff_docsis (void)
1244 dissector_add_uint ("wtap_encap", WTAP_ENCAP_DOCSIS
, docsis_handle
);
1246 hf_docsis_dst
= proto_registrar_get_id_byname ("eth.dst");
1247 hf_docsis_dst_resolved
= proto_registrar_get_id_byname ("eth.dst_resolved");
1248 hf_docsis_src
= proto_registrar_get_id_byname ("eth.src");
1249 hf_docsis_src_resolved
= proto_registrar_get_id_byname ("eth.src_resolved");
1250 hf_docsis_lg
= proto_registrar_get_id_byname ("eth.lg");
1251 hf_docsis_ig
= proto_registrar_get_id_byname ("eth.ig");
1253 docsis_mgmt_handle
= find_dissector ("docsis_mgmt");
1254 eth_withoutfcs_handle
= find_dissector_add_dependency("eth_withoutfcs", proto_docsis
);
1258 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1263 * indent-tabs-mode: nil
1266 * ex: set shiftwidth=2 tabstop=8 expandtab:
1267 * :indentSize=2:tabSize=8:noTabs=true: