2 * Routines for Frame Relay dissection
4 * Copyright 2001, Paul Ionescu <paul@acorp.ro>
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
28 * http://www.protocols.com/pbook/frame.htm
29 * http://www.mplsforum.org/frame/Approved/FRF.3/FRF.3.2.pdf
30 * ITU Recommendations Q.922 and Q.933
34 * http://www.trillium.com/assets/legacyframe/white_paper/8771019.pdf
47 #include <epan/packet.h>
49 #include "packet-llc.h"
50 #include "packet-chdlc.h"
58 * Bits in the address field.
60 #define FRELAY_EA 0x01 /* Address field extension bit */
62 #define FRELAY_UPPER_DLCI 0xFC /* Upper DLCI */
63 #define FRELAY_CR 0x02 /* Command/response bit in first octet */
65 #define FRELAY_SECOND_DLCI 0xF0 /* DLCI bits in FECN/BECN/DE octet */
66 #define FRELAY_FECN 0x08 /* Forward Explicit Congestion Notification */
67 #define FRELAY_BECN 0x04 /* Backward Explicit Congestion Notification */
68 #define FRELAY_DE 0x02 /* Discard Eligibility */
70 #define FRELAY_THIRD_DLCI 0xFE /* DLCI bits in third octet, if any */
72 #define FRELAY_LOWER_DLCI 0xFC /* Lower DLCI */
73 #define FRELAY_DC 0x02 /* DLCI or DL-CORE control indicator in last octet */
75 #define FROM_DCE 0x80 /* for direction setting */
77 static gint proto_fr = -1;
78 static gint ett_fr = -1;
79 static gint ett_fr_address = -1;
80 static gint ett_fr_control = -1;
81 static gint hf_fr_ea = -1;
82 static gint hf_fr_upper_dlci = -1;
83 static gint hf_fr_cr = -1;
84 static gint hf_fr_second_dlci = -1;
85 static gint hf_fr_fecn = -1;
86 static gint hf_fr_becn = -1;
87 static gint hf_fr_de = -1;
88 static gint hf_fr_third_dlci = -1;
89 static gint hf_fr_dlcore_control = -1;
90 static gint hf_fr_lower_dlci = -1;
91 static gint hf_fr_dc = -1;
92 static gint hf_fr_dlci = -1;
93 static gint hf_fr_control = -1;
94 static gint hf_fr_n_r = -1;
95 static gint hf_fr_n_s = -1;
96 static gint hf_fr_p = -1;
97 static gint hf_fr_p_ext = -1;
98 static gint hf_fr_f = -1;
99 static gint hf_fr_f_ext = -1;
100 static gint hf_fr_s_ftype = -1;
101 static gint hf_fr_u_modifier_cmd = -1;
102 static gint hf_fr_u_modifier_resp = -1;
103 static gint hf_fr_ftype_i = -1;
104 static gint hf_fr_ftype_s_u = -1;
105 static gint hf_fr_ftype_s_u_ext = -1;
106 static gint hf_fr_nlpid = -1;
107 static gint hf_fr_oui = -1;
108 static gint hf_fr_pid = -1;
109 static gint hf_fr_snaptype = -1;
110 static gint hf_fr_chdlctype = -1;
112 static dissector_handle_t eth_handle;
113 static dissector_handle_t gprs_ns_handle;
114 static dissector_handle_t data_handle;
116 static dissector_table_t osinl_subdissector_table;
119 * Encapsulation type.
120 * XXX - this should be per-DLCI as well.
122 #define FRF_3_2 0 /* FRF 3.2 or Cisco HDLC */
123 #define GPRS_NS 1 /* GPRS Network Services (3GPP TS 08.16) */
124 #define RAW_ETHER 2 /* Raw Ethernet */
126 static gint fr_encap = FRF_3_2;
128 static const true_false_string cmd_string = {
132 static const true_false_string ctrl_string = {
136 static const true_false_string ea_string = {
142 * This isn't the same as "nlpid_vals[]"; 0x08 is Q.933, not Q.931,
143 * and 0x09 is LMI, not Q.2931, and we assume that it's an initial
144 * protocol identifier, so 0x01 is T.70, not X.29.
146 static const value_string fr_nlpid_vals[] = {
147 { NLPID_NULL, "NULL" },
148 { NLPID_IPI_T_70, "T.70" }, /* XXX - IPI, or SPI? */
149 { NLPID_X_633, "X.633" },
150 { NLPID_Q_931, "Q.933" },
151 { NLPID_LMI, "LMI" },
152 { NLPID_Q_2119, "Q.2119" },
153 { NLPID_SNAP, "SNAP" },
154 { NLPID_ISO8473_CLNP, "CLNP" },
155 { NLPID_ISO9542_ESIS, "ESIS" },
156 { NLPID_ISO10589_ISIS, "ISIS" },
157 { NLPID_ISO10747_IDRP, "IDRP" },
158 { NLPID_ISO9542X25_ESIS, "ESIS (X.25)" },
159 { NLPID_ISO10030, "ISO 10030" },
160 { NLPID_ISO11577, "ISO 11577" },
161 { NLPID_COMPRESSED, "Data compression protocol" },
163 { NLPID_IP6, "IPv6" },
164 { NLPID_PPP, "PPP" },
168 static dissector_table_t fr_subdissector_table;
169 static dissector_table_t fr_osinl_subdissector_table;
171 static void dissect_fr_nlpid(tvbuff_t *tvb, int offset, packet_info *pinfo,
172 proto_tree *tree, proto_item *ti,
173 proto_tree *fr_tree, guint8 fr_ctrl);
174 static void dissect_lapf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
175 static void dissect_fr_xid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
177 /* Used only for U frames */
178 static const xdlc_cf_items fr_cf_items = {
184 &hf_fr_u_modifier_cmd,
185 &hf_fr_u_modifier_resp,
190 /* Used only for I and S frames */
191 static const xdlc_cf_items fr_cf_items_ext = {
204 dissect_fr_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
205 gboolean has_direction)
208 proto_item *ti = NULL;
209 proto_tree *fr_tree = NULL;
210 proto_item *octet_item = NULL;
211 proto_tree *octet_tree = NULL;
213 int is_response = FALSE;
219 if (check_col(pinfo->cinfo, COL_PROTOCOL))
220 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FR");
221 if (check_col(pinfo->cinfo, COL_INFO))
222 col_clear(pinfo->cinfo, COL_INFO);
225 if (pinfo->pseudo_header->x25.flags & FROM_DCE) {
226 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
227 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
228 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
229 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
231 if (check_col(pinfo->cinfo, COL_RES_DL_DST))
232 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
233 if (check_col(pinfo->cinfo, COL_RES_DL_SRC))
234 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
239 * OK, fetch the address field - keep going until we get an EA bit.
241 fr_octet = tvb_get_guint8(tvb, offset);
243 ti = proto_tree_add_protocol_format(tree, proto_fr, tvb, 0, -1, "Frame Relay");
244 fr_tree = proto_item_add_subtree(ti, ett_fr);
246 if (fr_octet & FRELAY_EA) {
248 * Bogus! There should be at least 2 octets.
249 * XXX - is this FRF.12 frame relay fragmentation? If so, we
250 * should dissect it as such, if possible.
254 proto_tree_add_text(fr_tree, tvb, offset, 1,
255 "Bogus 1-octet address field");
260 * The first octet contains the upper 6 bits of the DLCI, as well
263 address = (fr_octet & FRELAY_UPPER_DLCI) >> 2;
264 is_response = (fr_octet & FRELAY_CR);
266 octet_item = proto_tree_add_text(fr_tree, tvb, offset, 1,
267 "First address octet: 0x%02x", fr_octet);
268 octet_tree = proto_item_add_subtree(octet_item, ett_fr_address);
269 proto_tree_add_uint(octet_tree, hf_fr_upper_dlci, tvb, offset, 1, fr_octet);
270 proto_tree_add_boolean(octet_tree, hf_fr_cr, tvb, offset, 1, fr_octet);
271 proto_tree_add_boolean(octet_tree, hf_fr_ea, tvb, offset, 1, fr_octet);
276 * The second octet contains 4 more bits of DLCI, as well as FECN,
279 fr_octet = tvb_get_guint8(tvb, offset);
280 address = (address << 4) | ((fr_octet & FRELAY_SECOND_DLCI) >> 4);
282 octet_item = proto_tree_add_text(fr_tree, tvb, offset, 1,
283 "Second address octet: 0x%02x",
285 octet_tree = proto_item_add_subtree(octet_item, ett_fr_address);
286 proto_tree_add_uint(octet_tree, hf_fr_second_dlci, tvb, offset, 1, fr_octet);
287 proto_tree_add_boolean(octet_tree, hf_fr_fecn, tvb, 0, offset, fr_octet);
288 proto_tree_add_boolean(octet_tree, hf_fr_becn, tvb, 0, offset, fr_octet);
289 proto_tree_add_boolean(octet_tree, hf_fr_de, tvb, 0, offset, fr_octet);
290 proto_tree_add_boolean(octet_tree, hf_fr_ea, tvb, offset, 1, fr_octet);
294 if (!(fr_octet & FRELAY_EA)) {
296 * We have 3 or more address octets.
298 * The third octet contains 7 more bits of DLCI if EA isn't set,
299 * and lower DLCI or DL-CORE control plus the DLCI or DL-CORE
300 * control indicator flag if EA is set.
302 fr_octet = tvb_get_guint8(tvb, offset);
303 if (!(fr_octet & FRELAY_EA)) {
305 * 7 more bits of DLCI.
307 address = (address << 7) | ((fr_octet & FRELAY_THIRD_DLCI) >> 1);
309 octet_item = proto_tree_add_text(fr_tree, tvb, offset, 1,
310 "Third address octet: 0x%02x",
312 octet_tree = proto_item_add_subtree(octet_item, ett_fr_address);
313 proto_tree_add_uint(octet_tree, hf_fr_third_dlci, tvb, offset, 1, fr_octet);
314 proto_tree_add_boolean(octet_tree, hf_fr_ea, tvb, offset, 1, fr_octet);
317 fr_octet = tvb_get_guint8(tvb, offset);
318 while (!(fr_octet & FRELAY_EA)) {
320 * Bogus! More than 4 octets of address.
323 proto_tree_add_text(fr_tree, tvb, offset, 1,
324 "Bogus extra address octet");
327 fr_octet = tvb_get_guint8(tvb, offset);
331 octet_item = proto_tree_add_text(fr_tree, tvb, offset, 1,
332 "Final address octet: 0x%02x",
334 octet_tree = proto_item_add_subtree(octet_item, ett_fr_address);
338 * Last octet - contains lower DLCI or DL-CORE control, DLCI or
339 * DL-CORE control indicator flag.
341 if (fr_octet & FRELAY_DC) {
345 proto_tree_add_uint(octet_tree, hf_fr_dlcore_control, tvb, offset, 1, fr_octet);
348 * Last 6 bits of DLCI.
350 address = (address << 6) | ((fr_octet & FRELAY_LOWER_DLCI) >> 2);
351 proto_tree_add_uint(octet_tree, hf_fr_lower_dlci, tvb, offset, 1, fr_octet);
353 proto_tree_add_boolean(octet_tree, hf_fr_dc, tvb, offset, 1, fr_octet);
354 proto_tree_add_boolean(octet_tree, hf_fr_ea, tvb, offset, 1, fr_octet);
358 /* Put the full DLCI into the protocol tree. */
359 proto_tree_add_uint(fr_tree, hf_fr_dlci, tvb, 0, offset, address);
362 pinfo->ctype = CT_DLCI;
363 pinfo->circuit_id = address;
365 if (check_col(pinfo->cinfo, COL_INFO))
366 col_add_fstr(pinfo->cinfo, COL_INFO, "DLCI %u", address);
371 fr_ctrl = tvb_get_guint8(tvb, offset);
372 if (fr_ctrl == XDLC_U) {
373 dissect_xdlc_control(tvb, offset, pinfo, fr_tree, hf_fr_control,
374 ett_fr_control, &fr_cf_items, &fr_cf_items_ext,
375 NULL, NULL, is_response, TRUE, TRUE);
379 * XXX - treat DLCI 0 specially? On DLCI 0, an NLPID of 0x08
380 * means Q.933, but on other circuits it could be the "for
381 * protocols which do not have an NLPID assigned or do not
382 * have a SNAP encapsulation" stuff from RFC 2427.
384 dissect_fr_nlpid(tvb, offset, pinfo, tree, ti, fr_tree, fr_ctrl);
388 * This must be some sort of LAPF on DLCI 0 for SVC
389 * because DLCI 0 is reserved for LMI and SVC signaling
390 * encapsulated in LAPF, and LMI is transmitted in
391 * unnumbered information (03), so this must be LAPF
394 * XXX - but what is it? Is Q.933 carried inside UI
395 * frames or other types of frames or both?
397 dissect_xdlc_control(tvb, offset, pinfo, fr_tree,
398 hf_fr_control, ett_fr_control,
399 &fr_cf_items, &fr_cf_items_ext,
400 NULL, NULL, is_response, TRUE, TRUE);
401 dissect_lapf(tvb_new_subset(tvb,offset,-1,-1),pinfo,tree);
404 if (fr_ctrl == (XDLC_U|XDLC_XID)) {
405 dissect_xdlc_control(tvb, offset, pinfo, fr_tree,
406 hf_fr_control, ett_fr_control,
407 &fr_cf_items, &fr_cf_items_ext,
408 NULL, NULL, is_response, TRUE, TRUE);
409 dissect_fr_xid(tvb_new_subset(tvb,offset,-1,-1),pinfo,tree);
414 * If the data does not start with unnumbered information (03) and
415 * the DLCI# is not 0, then there may be Cisco Frame Relay encapsulation.
417 fr_type = tvb_get_ntohs(tvb, offset);
419 /* Include the Cisco HDLC type in the top-level protocol
421 proto_item_set_end(ti, tvb, offset+2);
423 chdlctype(fr_type, tvb, offset+2, pinfo, tree, fr_tree, hf_fr_chdlctype);
428 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
430 call_dissector(gprs_ns_handle, next_tvb, pinfo, tree);
432 dissect_lapf(next_tvb, pinfo, tree);
436 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
438 call_dissector(eth_handle, next_tvb, pinfo, tree);
440 dissect_lapf(next_tvb, pinfo, tree);
446 dissect_fr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
448 dissect_fr_common(tvb, pinfo, tree, FALSE);
452 dissect_fr_phdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
454 dissect_fr_common(tvb, pinfo, tree, TRUE);
457 static void dissect_fr_uncompressed(tvbuff_t *tvb, packet_info *pinfo,
460 proto_item *ti = NULL;
461 proto_tree *fr_tree = NULL;
463 if (check_col(pinfo->cinfo, COL_PROTOCOL))
464 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FR");
465 if (check_col(pinfo->cinfo, COL_INFO))
466 col_clear(pinfo->cinfo, COL_INFO);
469 ti = proto_tree_add_protocol_format(tree, proto_fr, tvb, 0, -1, "Frame Relay");
470 fr_tree = proto_item_add_subtree(ti, ett_fr);
472 dissect_fr_nlpid(tvb, 0, pinfo, tree, ti, fr_tree, XDLC_U);
475 static void dissect_fr_nlpid(tvbuff_t *tvb, int offset, packet_info *pinfo,
476 proto_tree *tree, proto_item *ti,
477 proto_tree *fr_tree, guint8 fr_ctrl)
483 * Tentatively set the Frame Relay item not to include the NLPID,
484 * as OSI network layer protocols consider it to be part of
487 proto_item_set_end(ti, tvb, offset);
488 fr_nlpid = tvb_get_guint8 (tvb,offset);
491 proto_tree_add_text(fr_tree, tvb, offset, 1, "Padding");
494 /* Include the padding in the top-level protocol tree item. */
495 proto_item_set_end(ti, tvb, offset);
497 fr_nlpid=tvb_get_guint8( tvb,offset);
501 * OSI network layer protocols consider the NLPID to be part
502 * of the frame, so we'll pass it as part of the payload and,
503 * if the protocol is one of those, add it as a hidden item here.
504 * We check both the generic OSI NLPID dissector table and
505 * the Frame Relay OSI NLPID dissector table - the latter is for
506 * NLPID's such as 0x08, which is Q.933 in Frame Relay but
507 * other protocols (e.g., Q.931) on other network layers.
509 * "OSI network layer protocols" includes Q.933.
511 * XXX - note that an NLPID of 0x08 for Q.933 could either be a
512 * Q.933 signaling message or a message for a protocol
513 * identified by a 2-octet layer 2 protocol type and a
514 * 2-octet layer 3 protocol type, those protocol type
515 * octets having the values from octets 6, 6a, 7, and 7a
516 * of a Q.931 low layer compatibility information element
517 * (section 4.5.19 of Q.931; Q.933 says they have the values
518 * from a Q.933 low layer compatibility information element,
519 * but Q.933 low layer compatibility information elements
520 * don't have protocol values in them).
522 * Assuming that, as Q.933 seems to imply, that Q.933 messages
523 * look just like Q.931 messages except where it explicitly
524 * says they differ, then the octet after the NLPID would,
525 * in a Q.933 message, have its upper 4 bits zero (that's
526 * the length of the call reference value, in Q.931, and
527 * is limited to 15 or fewer octets). As appears to be the case,
528 * octet 6 of a Q.931 low layer compatibility element has the
529 * 0x40 bit set, so you can distinguish between a Q.933
530 * message and an encapsulated packet by checking whether
531 * the upper 4 bits of the octet after the NLPID are zero.
533 * Either that, or it's Q.933 iff the DLCI is 0.
535 next_tvb = tvb_new_subset(tvb,offset,-1,-1);
536 if (dissector_try_port(osinl_subdissector_table, fr_nlpid, next_tvb,
538 dissector_try_port(fr_osinl_subdissector_table, fr_nlpid, next_tvb,
541 * Yes, we got a match. Add the NLPID as a hidden item,
542 * so you can, at least, filter on it.
545 proto_tree_add_uint_hidden(fr_tree, hf_fr_nlpid,
546 tvb, offset, 1, fr_nlpid );
551 * All other protocols don't.
553 * XXX - what about Cisco/Gang-of-Four LMI? Is the 0x09 considered
554 * to be part of the LMI PDU?
557 proto_tree_add_uint(fr_tree, hf_fr_nlpid, tvb, offset, 1, fr_nlpid );
564 /* Include the NLPID and SNAP header in the top-level
565 protocol tree item. */
566 proto_item_set_end(ti, tvb, offset+5);
568 dissect_snap(tvb, offset, pinfo, tree, fr_tree, fr_ctrl,
569 hf_fr_oui, hf_fr_snaptype, hf_fr_pid, 0);
574 /* Include the NLPID in the top-level protocol tree item. */
575 proto_item_set_end(ti, tvb, offset);
577 next_tvb = tvb_new_subset(tvb,offset,-1,-1);
578 if (!dissector_try_port(fr_subdissector_table,fr_nlpid,
579 next_tvb, pinfo, tree))
580 call_dissector(data_handle,next_tvb, pinfo, tree);
585 static void dissect_lapf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
587 proto_tree_add_text(tree, tvb, 0, 0, "Frame relay lapf not yet implemented");
588 call_dissector(data_handle,tvb_new_subset(tvb,0,-1,-1),pinfo,tree);
590 static void dissect_fr_xid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
592 proto_tree_add_text(tree, tvb, 0, 0, "Frame relay xid not yet implemented");
593 call_dissector(data_handle,tvb_new_subset(tvb,0,-1,-1),pinfo,tree);
596 /* Register the protocol with Ethereal */
597 void proto_register_fr(void)
599 static hf_register_info hf[] = {
601 "EA", "fr.ea", FT_BOOLEAN, 8, TFS(&ea_string),
602 FRELAY_EA, "Extended Address", HFILL }},
603 { &hf_fr_upper_dlci, {
604 "Upper DLCI", "fr.upper_dlci", FT_UINT8, BASE_HEX,
605 NULL, FRELAY_UPPER_DLCI, "Upper bits of DLCI", HFILL }},
607 "CR", "fr.cr", FT_BOOLEAN, 8, TFS(&cmd_string),
608 FRELAY_CR, "Command/Response", HFILL }},
609 { &hf_fr_second_dlci, {
610 "Second DLCI", "fr.second_dlci", FT_UINT8, BASE_HEX,
611 NULL, FRELAY_SECOND_DLCI, "Bits below upper bits of DLCI", HFILL }},
613 "FECN", "fr.fecn", FT_BOOLEAN, 8,
614 NULL, FRELAY_FECN, "Forward Explicit Congestion Notification", HFILL }},
616 "BECN", "fr.becn", FT_BOOLEAN, 8,
617 NULL, FRELAY_BECN, "Backward Explicit Congestion Notification", HFILL }},
619 "DE", "fr.de", FT_BOOLEAN, 8,
620 NULL, FRELAY_DE, "Discard Eligibility", HFILL }},
621 { &hf_fr_third_dlci, {
622 "Third DLCI", "fr.third_dlci", FT_UINT8, BASE_HEX,
623 NULL, FRELAY_THIRD_DLCI, "Additional bits of DLCI", HFILL }},
624 { &hf_fr_dlcore_control, {
625 "DL-CORE Control", "fr.dlcore_control", FT_UINT8, BASE_HEX,
626 NULL, FRELAY_LOWER_DLCI, "DL-Core control bits", HFILL }},
627 { &hf_fr_lower_dlci, {
628 "Lower DLCI", "fr.lower_dlci", FT_UINT8, BASE_HEX,
629 NULL, FRELAY_LOWER_DLCI, "Lower bits of DLCI", HFILL }},
631 "DC", "fr.dc", FT_BOOLEAN, 16, TFS(&ctrl_string),
632 FRELAY_CR, "Address/Control", HFILL }},
634 "DLCI", "fr.dlci", FT_UINT32, BASE_DEC,
635 NULL, 0x0, "Data-Link Connection Identifier", HFILL }},
637 "Control Field", "fr.control", FT_UINT8, BASE_HEX,
638 NULL, 0x0, "Control field", HFILL }},
640 "N(R)", "fr.control.n_r", FT_UINT16, BASE_DEC,
641 NULL, XDLC_N_R_EXT_MASK, "", HFILL }},
643 "N(S)", "fr.control.n_s", FT_UINT16, BASE_DEC,
644 NULL, XDLC_N_S_EXT_MASK, "", HFILL }},
646 "Poll", "fr.control.p", FT_BOOLEAN, 8,
647 TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
649 "Poll", "fr.control.p", FT_BOOLEAN, 16,
650 TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
652 "Final", "fr.control.f", FT_BOOLEAN, 8,
653 TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
655 "Final", "fr.control.f", FT_BOOLEAN, 16,
656 TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
658 "Supervisory frame type", "fr.control.s_ftype", FT_UINT16, BASE_HEX,
659 VALS(stype_vals), XDLC_S_FTYPE_MASK, "", HFILL }},
660 { &hf_fr_u_modifier_cmd, {
661 "Command", "lapd.control.u_modifier_cmd", FT_UINT8, BASE_HEX,
662 VALS(modifier_vals_cmd), XDLC_U_MODIFIER_MASK, "", HFILL }},
663 { &hf_fr_u_modifier_resp, {
664 "Response", "lapd.control.u_modifier_resp", FT_UINT8, BASE_HEX,
665 VALS(modifier_vals_resp), XDLC_U_MODIFIER_MASK, "", HFILL }},
667 "Frame type", "fr.control.ftype", FT_UINT16, BASE_HEX,
668 VALS(ftype_vals), XDLC_I_MASK, "", HFILL }},
669 { &hf_fr_ftype_s_u, {
670 "Frame type", "fr.control.ftype", FT_UINT8, BASE_HEX,
671 VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
672 { &hf_fr_ftype_s_u_ext, {
673 "Frame type", "fr.control.ftype", FT_UINT16, BASE_HEX,
674 VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
676 "NLPID", "fr.nlpid", FT_UINT8, BASE_HEX,
677 VALS(fr_nlpid_vals), 0x0, "Frame Relay Encapsulated Protocol NLPID", HFILL }},
679 "Organization Code", "fr.snap.oui", FT_UINT24, BASE_HEX,
680 VALS(oui_vals), 0x0, "", HFILL }},
682 "Protocol ID", "fr.snap.pid", FT_UINT16, BASE_HEX,
683 NULL, 0x0, "", HFILL }},
685 "Type", "fr.snaptype", FT_UINT16, BASE_HEX,
686 VALS(etype_vals), 0x0, "Frame Relay SNAP Encapsulated Protocol", HFILL }},
687 { &hf_fr_chdlctype, {
688 "Type", "fr.chdlctype", FT_UINT16, BASE_HEX,
689 VALS(chdlc_vals), 0x0, "Frame Relay Cisco HDLC Encapsulated Protocol", HFILL }},
692 /* Setup protocol subtree array */
693 static gint *ett[] = {
698 static enum_val_t fr_encap_options[] = {
699 { "frf-3.2", "FRF 3.2/Cisco HDLC", FRF_3_2 },
700 { "gprs-ns", "GPRS Network Service", GPRS_NS },
701 { "ethernet", "Raw Ethernet", RAW_ETHER },
704 module_t *frencap_module;
706 proto_fr = proto_register_protocol("Frame Relay", "FR", "fr");
707 proto_register_field_array(proto_fr, hf, array_length(hf));
708 proto_register_subtree_array(ett, array_length(ett));
710 fr_subdissector_table = register_dissector_table("fr.ietf",
711 "Frame Relay NLPID", FT_UINT8, BASE_HEX);
712 fr_osinl_subdissector_table = register_dissector_table("fr.osinl",
713 "Frame Relay OSI NLPID", FT_UINT8, BASE_HEX);
715 register_dissector("fr_uncompressed", dissect_fr_uncompressed, proto_fr);
716 register_dissector("fr", dissect_fr, proto_fr);
718 frencap_module = prefs_register_protocol(proto_fr, NULL);
719 prefs_register_enum_preference(frencap_module, "encap", "Encapsulation",
720 "Encapsulation", &fr_encap,
721 fr_encap_options, FALSE);
724 void proto_reg_handoff_fr(void)
726 dissector_handle_t fr_handle, fr_phdr_handle;
728 fr_handle = create_dissector_handle(dissect_fr, proto_fr);
729 dissector_add("gre.proto", GRE_FR, fr_handle);
730 dissector_add("wtap_encap", WTAP_ENCAP_FRELAY, fr_handle);
732 fr_phdr_handle = create_dissector_handle(dissect_fr_phdr, proto_fr);
733 dissector_add("wtap_encap", WTAP_ENCAP_FRELAY_WITH_PHDR, fr_phdr_handle);
735 eth_handle = find_dissector("eth");
736 gprs_ns_handle = find_dissector("gprs_ns");
737 data_handle = find_dissector("data");
739 osinl_subdissector_table = find_dissector_table("osinl");