2 * Routines for Generic Framing Procedure dissection
3 * Copyright 2015, John Thacker <johnthacker@gmail.com>
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 * Generic Framing Procedure (GFP) is used to map octet-aligned variable
14 * length payloads (e.g. Ethernet, MPLS, octet-aligned PPP, IP) into
15 * octet-synchronous signals such as SONET/SDH (ITU-T G.707) and OTN
16 * (ITU-T G.709). GFP is a telecommunications industry standard defined in
17 * ITU-T G.7041/Y.1303.
20 * https://www.itu.int/rec/T-REC-G.7041/
25 #include <epan/packet.h> /* Should be first Wireshark include (other than config.h) */
26 #include <epan/expert.h>
28 #include <epan/crc16-tvb.h>
29 #include <epan/crc32-tvb.h>
30 #include <epan/decode_as.h>
31 #include <epan/proto_data.h>
33 #include <wiretap/wtap.h>
36 /* (Required to prevent [-Wmissing-prototypes] warnings */
37 void proto_reg_handoff_gfp(void);
38 void proto_register_gfp(void);
40 /* Dissector handle */
41 static dissector_handle_t gfp_handle
;
43 /* Initialize the protocol and registered fields */
45 static int hf_gfp_pli
;
46 static int hf_gfp_chec
;
47 static int hf_gfp_chec_status
;
48 static int hf_gfp_type
;
49 static int hf_gfp_pti
;
50 static int hf_gfp_pfi
;
51 static int hf_gfp_exi
;
52 static int hf_gfp_upi_data
;
53 static int hf_gfp_upi_management
;
54 static int hf_gfp_thec
;
55 static int hf_gfp_thec_status
;
56 static int hf_gfp_cid
;
57 static int hf_gfp_ehec
;
58 static int hf_gfp_ehec_status
;
59 static int hf_gfp_fcs
;
60 static int hf_gfp_fcs_good
;
61 static int hf_gfp_fcs_bad
;
63 static expert_field ei_gfp_pli_idle_nonempty
;
64 static expert_field ei_gfp_pli_unknown
;
65 static expert_field ei_gfp_pli_invalid
;
66 static expert_field ei_gfp_chec_bad
;
67 static expert_field ei_gfp_thec_bad
;
68 static expert_field ei_gfp_ehec_bad
;
69 static expert_field ei_gfp_exi_short
;
70 static expert_field ei_gfp_pfi_short
;
71 static expert_field ei_gfp_payload_undecoded
;
72 static expert_field ei_gfp_fcs_bad
;
74 #define GFP_USER_DATA 0
75 #define GFP_CLIENT_MANAGEMENT 4
76 #define GFP_MANAGEMENT_COMMUNICATIONS 5
78 #define GFP_EXT_NULL 0
79 #define GFP_EXT_LINEAR 1
80 #define GFP_EXT_RING 2
82 /* Initialize the subtree pointers */
84 static int ett_gfp_type
;
85 static int ett_gfp_fcs
;
87 static dissector_table_t gfp_dissector_table
;
89 /* ITU-T G.7041 6.1.1, 6.2 */
90 static const range_string gfp_pli_rvals
[] = {
92 {1, 3, "Control Frame (Reserved)"},
93 {4, UINT16_MAX
, "Client Frame"},
97 static int * const gfp_type_data_fields
[] = {
105 static int * const gfp_type_management_fields
[] = {
109 &hf_gfp_upi_management
,
113 static const value_string gfp_pti_vals
[] = {
114 {GFP_USER_DATA
, "User Data"},
115 {GFP_CLIENT_MANAGEMENT
, "Client Management"},
116 {GFP_MANAGEMENT_COMMUNICATIONS
, "Management Communications"},
120 static const value_string gfp_exi_vals
[] = {
121 {GFP_EXT_NULL
, "Null Extension Header"},
122 {GFP_EXT_LINEAR
, "Linear Frame"},
123 {GFP_EXT_RING
, "Ring Frame"},
127 static const range_string gfp_upi_data_rvals
[] = {
128 {0, 0, "Reserved and not available"},
129 {1, 1, "Frame-Mapped Ethernet"},
130 {2, 2, "Frame-Mapped PPP"},
131 {3, 3, "Transparent Fibre Channel"},
132 {4, 4, "Transparent FICON"},
133 {5, 5, "Transparent ESCON"},
134 {6, 6, "Transparent Gbit Ethernet"},
136 {8, 8, "Frame-Mapped Multiple Access Protocol over SDH (MAPOS)"},
137 {9, 9, "Transparent DVB ASI"},
138 {10, 10, "Frame-Mapped IEEE 802.17 Resilient Packet Ring"},
139 {11, 11, "Frame-Mapped Fibre Channel FC-BBW"},
140 {12, 12, "Asynchronous Transparent Fibre Channel"},
141 {13, 13, "Frame-Mapped MPLS"},
142 {14, 14, "Frame-Mapped MPLS (Multicast) [Deprecated]"},
143 {15, 15, "Frame-Mapped OSI network layer protocols (IS-IS, ES-IS, CLNP)"},
144 {16, 16, "Frame-Mapped IPv4"},
145 {17, 17, "Frame-Mapped IPv6"},
146 {18, 18, "Frame-Mapped DVB-ASI"},
147 {19, 19, "Frame-Mapped 64B/66B encoded Ethernet, including frame preamble"},
148 {20, 20, "Frame-Mapped 64B/66B encoded Ethernet ordered set information"},
149 {21, 21, "Transparent transcoded FC-1200"},
150 /*UPI value 22 & 23 from Amendment 3 (01/2015)*/
151 {22, 22, "Precision Time Protocol message"},
152 {23, 23, "Synchronization status message"},
153 {24, 239, "Reserved for future standardization"},
154 {240, 252, "Reserved for proprietary use"},
155 {253, 253, "Reserved for proprietary use, formerly Frame-Mapped 64B/66B encoded Ethernet, including frame preamble"},
156 {254, 254, "Reserved for proprietary use, formerly Frame-Mapped 64B/66B encoded Ethernet ordered set information"},
157 {255, 255, "Reserved and not available"},
161 static const range_string gfp_upi_management_rvals
[] = {
162 {0, 0, "Reserved and not available"},
163 {1, 1, "Client Signal Fail (Loss of Client Signal)"},
164 {2, 2, "Client Signal Fail (Loss of Character Synchronisation)"},
165 {3, 3, "Defect Clear Indication (DCI)"},
166 {4, 4, "Forward Defect Indication (FDI)"},
167 {5, 5, "Reverse Defect Indication (RDI)"},
168 {6, 223, "Reserved for future use"},
169 {224, 254, "Reserved for proprietary use"},
170 {255, 255, "Reserved and not available"},
175 /* Even GFP idle frames must have 4 bytes for the core header.
176 * If data is received with fewer than this it is rejected. */
177 #define GFP_MIN_LENGTH 4
179 static void gfp_prompt(packet_info
*pinfo
, char* result
)
181 snprintf(result
, MAX_DECODE_AS_PROMPT_LEN
, "UPI %u as",
182 GPOINTER_TO_UINT(p_get_proto_data(pinfo
->pool
, pinfo
, proto_gfp
, 0)));
185 static void *gfp_value(packet_info
*pinfo
)
187 return p_get_proto_data(pinfo
->pool
, pinfo
, proto_gfp
, 0);
190 /* GFP has several identical 16 bit CRCs in its header (HECs). Note that
191 * this function increases the offset. */
193 gfp_add_hec_tree(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned *offset
, const unsigned len
, const int field
, const int field_status
, expert_field
*ei_bad
)
198 hec_calc
= crc16_r3_ccitt_tvb(tvb
, *offset
, len
);
201 proto_tree_add_checksum(tree
, tvb
, *offset
, field
, field_status
, ei_bad
, pinfo
, hec_calc
, ENC_BIG_ENDIAN
, PROTO_CHECKSUM_VERIFY
);
205 /* G.7041 6.1.2 GFP payload area */
207 dissect_gfp_payload(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, proto_tree
*gfp_tree
, unsigned *offset
, unsigned payload_len
)
209 tvbuff_t
*payload_tvb
;
210 proto_item
*type_ti
= NULL
;
212 proto_tree
*fcs_tree
= NULL
;
213 unsigned pti
, pfi
, exi
, upi
;
214 unsigned fcs
, fcs_calc
;
215 unsigned fcs_len
= 0;
217 /* G.7041 6.1.2.3 Payload area scrambling
218 * Note that payload when sent on the wire is scrambled as per ATM
219 * with a 1 + x^43 multiplicative scrambler. Likely already removed by
220 * the time we get a capture file (as with ATM). Could have a pref,
221 * but if it's present we have to save state over subsequent frames,
222 * always would fail to decode the first 43 payload bytes of a capture. */
224 /* G.7041 6.1.2.1 Payload Header - at least 4 bytes */
225 tvb_ensure_bytes_exist(tvb
, *offset
, 4);
228 /* G.7041 6.1.2.1.1 GFP type field - mandatory 2 bytes */
229 pti
= tvb_get_bits8(tvb
, 8*(*offset
), 3);
230 pfi
= tvb_get_bits8(tvb
, 8*(*offset
)+3, 1);
231 exi
= tvb_get_bits8(tvb
, 8*(*offset
)+4, 4);
232 upi
= tvb_get_uint8(tvb
, *offset
+1);
233 p_add_proto_data(pinfo
->pool
, pinfo
, proto_gfp
, 0, GUINT_TO_POINTER(upi
));
235 col_add_str(pinfo
->cinfo
, COL_INFO
, val_to_str(pti
, gfp_pti_vals
, "Reserved PTI (%d)"));
236 if (pti
== GFP_USER_DATA
||
237 pti
== GFP_MANAGEMENT_COMMUNICATIONS
) {
238 /* G.7041 Table 6-3 - GFP_MANAGEMENT_COMMUNICATIONS
239 * uses the same UPI table as USER_DATA, though
240 * "not all of these UPI types are applicable" in that case. */
241 type_ti
= proto_tree_add_bitmask_with_flags(gfp_tree
, tvb
, *offset
, hf_gfp_type
,
242 ett_gfp_type
, gfp_type_data_fields
, ENC_BIG_ENDIAN
, BMT_NO_FLAGS
);
243 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, ": ", rval_to_str(upi
, gfp_upi_data_rvals
, "Unknown 0x%02x"));
244 } else if (pti
== GFP_CLIENT_MANAGEMENT
) {
245 /* G.7041 Table 6-4 */
246 type_ti
= proto_tree_add_bitmask_with_flags(gfp_tree
, tvb
, *offset
, hf_gfp_type
,
247 ett_gfp_type
, gfp_type_management_fields
, ENC_BIG_ENDIAN
, BMT_NO_FLAGS
);
248 col_append_sep_str(pinfo
->cinfo
, COL_INFO
, ": ", rval_to_str(upi
, gfp_upi_management_rvals
, "Unknown 0x%02x"));
251 /* G.7041 6.1.2.1.2 Type HEC (tHEC) - mandatory 2 bytes */
252 gfp_add_hec_tree(tvb
, pinfo
, gfp_tree
, offset
, 2, hf_gfp_thec
, hf_gfp_thec_status
, &ei_gfp_thec_bad
);
256 /* G.7041 6.1.2.1.3.1 Null extension header */
260 /* G.7041 6.1.2.1.3.2 Extension header for a linear frame */
261 if (payload_len
< 4) {
262 expert_add_info(pinfo
, type_ti
, &ei_gfp_exi_short
);
268 proto_tree_add_item(gfp_tree
, hf_gfp_cid
, tvb
, *offset
, 1, ENC_BIG_ENDIAN
);
269 /* Next byte spare field, reserved */
271 /* 6.1.2.1.4 Extension HEC field */
272 gfp_add_hec_tree(tvb
, pinfo
, gfp_tree
, offset
, 2, hf_gfp_ehec
, hf_gfp_ehec_status
, &ei_gfp_ehec_bad
);
275 /* 6.1.2.1.3.3 Extension header for a ring frame */
276 /* "For further study." Undefined so fall through */
279 /* TODO: Mark as error / unhandled? */
283 proto_item_set_end(gfp_tree
, tvb
, *offset
);
285 if (pfi
== 1) { /* 6.1.2.2.1 Payload FCS field present */
286 if (payload_len
< 4) {
287 expert_add_info(pinfo
, type_ti
, &ei_gfp_pfi_short
);
288 fcs_len
= payload_len
;
295 proto_tree_set_appendix(gfp_tree
, tvb
, *offset
+ payload_len
, fcs_len
);
296 fcs
= tvb_get_ntohl(tvb
, *offset
+ payload_len
);
297 /* Same CRC32 as ATM */
298 /* As with ATM, we can either compute the CRC as it would be
299 * calculated and compare (last step involves taking the complement),
300 * or we can include the passed CRC in the input and check to see
301 * if the remainder is a known value. I like the first method
302 * only because it lets us display what we should have received. */
304 fcs_calc
= crc32_mpeg2_tvb_offset(tvb
, *offset
, payload_len
);
305 if (fcs
== ~fcs_calc
) {
306 fcs_ti
= proto_tree_add_uint_format_value(gfp_tree
, hf_gfp_fcs
, tvb
, *offset
+payload_len
, 4, fcs
, "0x%08x [correct]", fcs
);
307 fcs_tree
= proto_item_add_subtree(fcs_ti
, ett_gfp_fcs
);
308 fcs_ti
= proto_tree_add_boolean(fcs_tree
, hf_gfp_fcs_good
, tvb
, *offset
+payload_len
, 4, true);
309 proto_item_set_generated(fcs_ti
);
310 fcs_ti
= proto_tree_add_boolean(fcs_tree
, hf_gfp_fcs_bad
, tvb
, *offset
+payload_len
, 4, false);
311 proto_item_set_generated(fcs_ti
);
313 fcs_ti
= proto_tree_add_uint_format_value(gfp_tree
, hf_gfp_fcs
, tvb
, *offset
+payload_len
, 4, fcs
, "0x%08x [incorrect, should be 0x%08x]", fcs
, fcs_calc
);
314 fcs_tree
= proto_item_add_subtree(fcs_ti
, ett_gfp_fcs
);
315 fcs_ti
= proto_tree_add_boolean(fcs_tree
, hf_gfp_fcs_good
, tvb
, *offset
+payload_len
, 4, false);
316 proto_item_set_generated(fcs_ti
);
317 fcs_ti
= proto_tree_add_boolean(fcs_tree
, hf_gfp_fcs_bad
, tvb
, *offset
+payload_len
, 4, true);
318 proto_item_set_generated(fcs_ti
);
319 expert_add_info(pinfo
, fcs_ti
, &ei_gfp_fcs_bad
);
322 /* fcs_calc = crc32_mpeg2_tvb_offset(tvb, *offset, payload_len+4);
323 fcs_ti = proto_tree_add_uint(gfp_tree, hf_gfp_fcs, tvb, *offset+payload_len, 4, fcs);
324 proto_item_append_text(fcs_ti, (fcs_calc == 0xC704DD7B) ? " [correct]" : " [incorrect]"); */
327 /* Some client frames we can do. Others are not implemented yet.
328 * Transparent mode types are much trickier than frame-mapped,
329 * since they requires reassembling streams across multiple GFP packets. */
330 payload_tvb
= tvb_new_subset_length(tvb
, *offset
, payload_len
);
333 case GFP_MANAGEMENT_COMMUNICATIONS
:
334 if (!dissector_try_uint(gfp_dissector_table
, upi
, payload_tvb
, pinfo
, tree
)) {
335 expert_add_info_format(pinfo
, type_ti
, &ei_gfp_payload_undecoded
, "Payload type 0x%02x (%s) unsupported", upi
, rval_to_str_const(upi
, gfp_upi_data_rvals
, "UNKNOWN"));
336 call_data_dissector(payload_tvb
, pinfo
, tree
);
340 case GFP_CLIENT_MANAGEMENT
:
341 call_data_dissector(payload_tvb
, pinfo
, tree
);
347 *offset
+= payload_len
;
352 dissect_gfp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
355 proto_item
*ti
, *pli_ti
;
356 proto_tree
*gfp_tree
;
363 /* Check that the packet is long enough for it to belong to us. */
364 if (tvb_reported_length(tvb
) < GFP_MIN_LENGTH
)
367 /*** COLUMN DATA ***/
369 /* Set the Protocol column to the constant string of GFP */
370 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "GFP");
372 col_clear(pinfo
->cinfo
, COL_INFO
);
373 /* Avoid asserts for leaving these blank. */
374 col_set_str(pinfo
->cinfo
, COL_RES_DL_SRC
, "N/A");
375 col_set_str(pinfo
->cinfo
, COL_RES_DL_DST
, "N/A");
377 /*** PROTOCOL TREE ***/
379 /* create display subtree for the protocol */
380 ti
= proto_tree_add_item(tree
, proto_gfp
, tvb
, 0, GFP_MIN_LENGTH
, ENC_NA
);
382 gfp_tree
= proto_item_add_subtree(ti
, ett_gfp
);
384 /* ITU-T G.7041 6.1.1 GFP core header */
385 /* The core header could be scrambled (see G.7041 6.1.1.3) but isn't on
386 * the GFP level capture files I've seen as it's removed before then.
387 * If using this as a subdissector to a SDH or OTN dissector, that could
388 * be an issue. TODO: Maybe add a pref for scrambling? */
390 pli_ti
= proto_tree_add_item_ret_uint(gfp_tree
, hf_gfp_pli
, tvb
,
391 offset
, len
, ENC_BIG_ENDIAN
, &pli
);
392 if (pli
< 4) { /* Don't interpret as payload length */
393 proto_item_append_text(pli_ti
, " (%s)", rval_to_str_const(pli
, gfp_pli_rvals
, "Unknown"));
395 col_set_str(pinfo
->cinfo
, COL_INFO
, rval_to_str_const(pli
, gfp_pli_rvals
, "Unknown"));
397 /* 6.1.1.2 Core HEC field */
398 gfp_add_hec_tree(tvb
, pinfo
, gfp_tree
, &offset
, len
, hf_gfp_chec
, hf_gfp_chec_status
, &ei_gfp_chec_bad
);
400 if (pli
== 0) { /* 6.2.1 GFP idle frames */
401 if (tvb_reported_length_remaining(tvb
, offset
)) {
402 expert_add_info(pinfo
, pli_ti
, &ei_gfp_pli_idle_nonempty
);
404 } else if (pli
< 4) { /* 6.2.2 Other control frames (reserved) */
405 expert_add_info(pinfo
, pli_ti
, &ei_gfp_pli_unknown
);
407 /* G.7041 6.1.2 GFP payload area */
408 if (tvb_reported_length(tvb
) < pli
+ offset
) {
409 /* avoid signed / unsigned comparison */
410 proto_item_append_text(pli_ti
, " (invalid, reported length is %u)", tvb_reported_length_remaining(tvb
, offset
));
411 expert_add_info(pinfo
, pli_ti
, &ei_gfp_pli_invalid
);
413 dissect_gfp_payload(tvb
, pinfo
, tree
, gfp_tree
, &offset
, pli
);
416 /* Return the amount of data this dissector was able to dissect */
421 proto_register_gfp(void)
423 /* Setup list of header fields See Section 1.5 of README.dissector for
425 static hf_register_info hf
[] = {
427 { "Payload Length Indicator", "gfp.pli", FT_UINT16
, BASE_DEC
,
428 NULL
, 0x0, NULL
, HFILL
}
431 { "Core HEC", "gfp.chec", FT_UINT16
, BASE_HEX
,
432 NULL
, 0x0, NULL
, HFILL
}
434 { &hf_gfp_chec_status
,
435 { "cHEC Status", "gfp.chec.status", FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0x0,
439 { "Type Field", "gfp.type", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
443 { "PTI", "gfp.pti", FT_UINT16
, BASE_HEX
, VALS(gfp_pti_vals
),
444 0xE000, "Payload Type Identifier", HFILL
}
447 { "PFI", "gfp.pfi", FT_BOOLEAN
, 16, TFS(&tfs_present_absent
),
448 0x1000, "Payload FCS Indicator", HFILL
}
451 { "EXI", "gfp.exi", FT_UINT16
, BASE_HEX
, VALS(gfp_exi_vals
),
452 0x0F00, "Extension Header Identifier", HFILL
}
455 { "UPI", "gfp.upi", FT_UINT16
, BASE_HEX
|BASE_RANGE_STRING
,
456 RVALS(gfp_upi_data_rvals
),
457 0xFF, "User Payload Identifier for Client Data Frame (or Management Communications Frame)", HFILL
}
459 { &hf_gfp_upi_management
,
460 { "UPI", "gfp.upi", FT_UINT16
, BASE_HEX
|BASE_RANGE_STRING
,
461 RVALS(gfp_upi_management_rvals
),
462 0xFF, "User Payload Identifier for Client Management Frame", HFILL
}
465 { "Type HEC", "gfp.thec", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
468 { &hf_gfp_thec_status
,
469 { "tHEC Status", "gfp.thec.status", FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0x0,
473 { "Channel ID", "gfp.cid", FT_UINT8
, BASE_HEX
, NULL
, 0x0,
477 { "Extension HEC", "gfp.ehec", FT_UINT16
, BASE_HEX
, NULL
, 0x0,
480 { &hf_gfp_ehec_status
,
481 { "eHEC Status", "gfp.ehec.status", FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0x0,
485 { "Payload FCS", "gfp.fcs", FT_UINT32
, BASE_HEX
, NULL
, 0x0,
489 { "Good FCS", "gfp.fcs_good", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
490 "True: FCS matches payload; False: doesn't match", HFILL
}
493 { "Bad eHEC", "gfp.fcs_bad", FT_BOOLEAN
, BASE_NONE
, NULL
, 0x0,
494 "True: FCS doesn't match payload; False: matches", HFILL
}
498 /* Setup protocol subtree array */
499 static int *ett
[] = {
505 /* Setup protocol expert items */
506 static ei_register_info ei
[] = {
507 { &ei_gfp_pli_idle_nonempty
,
508 { "gfp.pli.idle.nonempty", PI_MALFORMED
, PI_ERROR
,
509 "Payload present on idle frame", EXPFILL
}
511 { &ei_gfp_pli_unknown
,
512 { "gfp.pli.unknown", PI_UNDECODED
, PI_WARN
,
513 "Unknown control frame type", EXPFILL
}
515 { &ei_gfp_pli_invalid
,
516 { "gfp.pli.invalid", PI_MALFORMED
, PI_WARN
,
517 "Bogus PLI does not match reported length", EXPFILL
}
520 { "gfp.chec.bad", PI_CHECKSUM
, PI_WARN
,
521 "Bad cHEC", EXPFILL
}
524 { "gfp.thec.bad", PI_CHECKSUM
, PI_WARN
,
525 "Bad tHEC", EXPFILL
}
528 { "gfp.ehec.bad", PI_CHECKSUM
, PI_WARN
,
529 "Bad eHEC", EXPFILL
}
532 { "gfp.exi.missing", PI_MALFORMED
, PI_ERROR
,
533 "EXI bit set but PLI too short for extension header", EXPFILL
}
536 { "gfp.pfi.missing", PI_MALFORMED
, PI_ERROR
,
537 "PFI bit set but PLI too short for payload FCS", EXPFILL
}
539 { &ei_gfp_payload_undecoded
,
540 { "gfp.payload.undecoded", PI_UNDECODED
, PI_WARN
,
541 "Payload type not supported yet by the dissector", EXPFILL
}
544 { "gfp.fcs.bad", PI_CHECKSUM
, PI_WARN
,
549 /* Decode As handling */
550 static build_valid_func gfp_da_build_value
[1] = {gfp_value
};
551 static decode_as_value_t gfp_da_values
= {gfp_prompt
, 1, gfp_da_build_value
};
552 static decode_as_t gfp_da
= {"gfp", "gfp.upi", 1, 0, &gfp_da_values
, NULL
, NULL
,
553 decode_as_default_populate_list
, decode_as_default_reset
, decode_as_default_change
, NULL
};
555 /* module_t *gfp_module; */
556 expert_module_t
*expert_gfp
;
558 /* Register the protocol name and description */
559 proto_gfp
= proto_register_protocol("Generic Framing Procedure",
561 gfp_handle
= register_dissector("gfp", dissect_gfp
,
564 /* Required function calls to register the header fields and subtrees */
565 proto_register_field_array(proto_gfp
, hf
, array_length(hf
));
566 proto_register_subtree_array(ett
, array_length(ett
));
568 /* Required function calls to register expert items */
569 expert_gfp
= expert_register_protocol(proto_gfp
);
570 expert_register_field_array(expert_gfp
, ei
, array_length(ei
));
572 /* Subdissectors for payload */
573 gfp_dissector_table
= register_dissector_table("gfp.upi", "GFP UPI (for Client Data frames)",
574 proto_gfp
, FT_UINT8
, BASE_DEC
);
576 /* Don't register a preferences module yet since there are no prefs in
577 * order to avoid a warning. (See section 2.6 of README.dissector
578 * for more details on preferences). */
579 /*gfp_module = prefs_register_protocol(proto_gfp, NULL);*/
581 register_decode_as(&gfp_da
);
585 proto_reg_handoff_gfp(void)
587 dissector_add_uint("wtap_encap", WTAP_ENCAP_GFP_T
, gfp_handle
);
588 dissector_add_uint("wtap_encap", WTAP_ENCAP_GFP_F
, gfp_handle
);
590 /* Add a few of the easiest UPIs to decode. There's more that probably
591 * would work, but are untested (frame mapped DVB, frame mapped Fibre
592 * Channel). The transparent mode ones are trickier, since without a
593 * one-to-one mapping of frames, we would have to reassemble payload
594 * packets across multiple GFP packets.
596 * Section 7.1.1 "Ethernet MAC encapsulation" of G.7041 says
597 * "The Ethernet MAC octets from destination address through
598 * "frame check sequence, inclusive, are placed in the GFP payload
599 * "information field.", so we want the dissector for Ethernet
600 * frames including the FCS. */
601 dissector_add_uint("gfp.upi", 1, find_dissector("eth_withfcs"));
602 dissector_add_uint("gfp.upi", 2, find_dissector("ppp_hdlc"));
603 dissector_add_uint("gfp.upi", 9, find_dissector("mp2t"));
604 dissector_add_uint("gfp.upi", 12, find_dissector("mpls"));
605 dissector_add_uint("gfp.upi", 13, find_dissector("mpls"));
606 dissector_add_uint("gfp.upi", 16, find_dissector("ip"));
607 dissector_add_uint("gfp.upi", 17, find_dissector("ipv6"));
611 * Editor modelines - https://www.wireshark.org/tools/modelines.html
616 * indent-tabs-mode: nil
619 * vi: set shiftwidth=4 tabstop=8 expandtab:
620 * :indentSize=4:tabSize=8:noTabs=true: