2 * Routines for Frame Relay dissection
4 * Copyright 2001, Paul Ionescu <paul@acorp.ro>
6 * $Id: packet-fr.c,v 1.48 2004/05/24 02:25:18 guy Exp $
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.frforum.com/5000/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.
252 proto_tree_add_text(fr_tree, tvb, offset, 1,
253 "Bogus 1-octet address field");
258 * The first octet contains the upper 6 bits of the DLCI, as well
261 address = (fr_octet & FRELAY_UPPER_DLCI) >> 2;
262 is_response = (fr_octet & FRELAY_CR);
264 octet_item = proto_tree_add_text(fr_tree, tvb, offset, 1,
265 "First address octet: 0x%02x", fr_octet);
266 octet_tree = proto_item_add_subtree(octet_item, ett_fr_address);
267 proto_tree_add_uint(octet_tree, hf_fr_upper_dlci, tvb, offset, 1, fr_octet);
268 proto_tree_add_boolean(octet_tree, hf_fr_cr, tvb, offset, 1, fr_octet);
269 proto_tree_add_boolean(octet_tree, hf_fr_ea, tvb, offset, 1, fr_octet);
274 * The second octet contains 4 more bits of DLCI, as well as FECN,
277 fr_octet = tvb_get_guint8(tvb, offset);
278 address = (address << 4) | ((fr_octet & FRELAY_SECOND_DLCI) >> 4);
280 octet_item = proto_tree_add_text(fr_tree, tvb, offset, 1,
281 "Second address octet: 0x%02x",
283 octet_tree = proto_item_add_subtree(octet_item, ett_fr_address);
284 proto_tree_add_uint(octet_tree, hf_fr_second_dlci, tvb, offset, 1, fr_octet);
285 proto_tree_add_boolean(octet_tree, hf_fr_fecn, tvb, 0, offset, fr_octet);
286 proto_tree_add_boolean(octet_tree, hf_fr_becn, tvb, 0, offset, fr_octet);
287 proto_tree_add_boolean(octet_tree, hf_fr_de, tvb, 0, offset, fr_octet);
288 proto_tree_add_boolean(octet_tree, hf_fr_ea, tvb, offset, 1, fr_octet);
292 if (!(fr_octet & FRELAY_EA)) {
294 * We have 3 or more address octets.
296 * The third octet contains 7 more bits of DLCI if EA isn't set,
297 * and lower DLCI or DL-CORE control plus the DLCI or DL-CORE
298 * control indicator flag if EA is set.
300 fr_octet = tvb_get_guint8(tvb, offset);
301 if (!(fr_octet & FRELAY_EA)) {
303 * 7 more bits of DLCI.
305 address = (address << 7) | ((fr_octet & FRELAY_THIRD_DLCI) >> 1);
307 octet_item = proto_tree_add_text(fr_tree, tvb, offset, 1,
308 "Third address octet: 0x%02x",
310 octet_tree = proto_item_add_subtree(octet_item, ett_fr_address);
311 proto_tree_add_uint(octet_tree, hf_fr_third_dlci, tvb, offset, 1, fr_octet);
312 proto_tree_add_boolean(octet_tree, hf_fr_ea, tvb, offset, 1, fr_octet);
315 fr_octet = tvb_get_guint8(tvb, offset);
316 while (!(fr_octet & FRELAY_EA)) {
318 * Bogus! More than 4 octets of address.
321 proto_tree_add_text(fr_tree, tvb, offset, 1,
322 "Bogus extra address octet");
325 fr_octet = tvb_get_guint8(tvb, offset);
329 octet_item = proto_tree_add_text(fr_tree, tvb, offset, 1,
330 "Final address octet: 0x%02x",
332 octet_tree = proto_item_add_subtree(octet_item, ett_fr_address);
336 * Last octet - contains lower DLCI or DL-CORE control, DLCI or
337 * DL-CORE control indicator flag.
339 if (fr_octet & FRELAY_DC) {
343 proto_tree_add_uint(octet_tree, hf_fr_dlcore_control, tvb, offset, 1, fr_octet);
346 * Last 6 bits of DLCI.
348 address = (address << 6) | ((fr_octet & FRELAY_LOWER_DLCI) >> 2);
349 proto_tree_add_uint(octet_tree, hf_fr_lower_dlci, tvb, offset, 1, fr_octet);
351 proto_tree_add_boolean(octet_tree, hf_fr_dc, tvb, offset, 1, fr_octet);
352 proto_tree_add_boolean(octet_tree, hf_fr_ea, tvb, offset, 1, fr_octet);
356 /* Put the full DLCI into the protocol tree. */
357 proto_tree_add_uint(fr_tree, hf_fr_dlci, tvb, 0, offset, address);
360 pinfo->ctype = CT_DLCI;
361 pinfo->circuit_id = address;
363 if (check_col(pinfo->cinfo, COL_INFO))
364 col_add_fstr(pinfo->cinfo, COL_INFO, "DLCI %u", address);
369 fr_ctrl = tvb_get_guint8(tvb, offset);
370 if (fr_ctrl == XDLC_U) {
371 dissect_xdlc_control(tvb, offset, pinfo, fr_tree, hf_fr_control,
372 ett_fr_control, &fr_cf_items, &fr_cf_items_ext,
373 NULL, NULL, is_response, TRUE, TRUE);
377 * XXX - treat DLCI 0 specially? On DLCI 0, an NLPID of 0x08
378 * means Q.933, but on other circuits it could be the "for
379 * protocols which do not have an NLPID assigned or do not
380 * have a SNAP encapsulation" stuff from RFC 2427.
382 dissect_fr_nlpid(tvb, offset, pinfo, tree, ti, fr_tree, fr_ctrl);
386 * This must be some sort of LAPF on DLCI 0 for SVC
387 * because DLCI 0 is reserved for LMI and SVC signaling
388 * encapsulated in LAPF, and LMI is transmitted in
389 * unnumbered information (03), so this must be LAPF
392 * XXX - but what is it? Is Q.933 carried inside UI
393 * frames or other types of frames or both?
395 dissect_xdlc_control(tvb, offset, pinfo, fr_tree,
396 hf_fr_control, ett_fr_control,
397 &fr_cf_items, &fr_cf_items_ext,
398 NULL, NULL, is_response, TRUE, TRUE);
399 dissect_lapf(tvb_new_subset(tvb,offset,-1,-1),pinfo,tree);
402 if (fr_ctrl == (XDLC_U|XDLC_XID)) {
403 dissect_xdlc_control(tvb, offset, pinfo, fr_tree,
404 hf_fr_control, ett_fr_control,
405 &fr_cf_items, &fr_cf_items_ext,
406 NULL, NULL, is_response, TRUE, TRUE);
407 dissect_fr_xid(tvb_new_subset(tvb,offset,-1,-1),pinfo,tree);
412 * If the data does not start with unnumbered information (03) and
413 * the DLCI# is not 0, then there may be Cisco Frame Relay encapsulation.
415 fr_type = tvb_get_ntohs(tvb, offset);
417 /* Include the Cisco HDLC type in the top-level protocol
419 proto_item_set_end(ti, tvb, offset+2);
421 chdlctype(fr_type, tvb, offset+2, pinfo, tree, fr_tree, hf_fr_chdlctype);
426 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
428 call_dissector(gprs_ns_handle, next_tvb, pinfo, tree);
430 dissect_lapf(next_tvb, pinfo, tree);
434 next_tvb = tvb_new_subset(tvb, offset, -1, -1);
436 call_dissector(eth_handle, next_tvb, pinfo, tree);
438 dissect_lapf(next_tvb, pinfo, tree);
444 dissect_fr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
446 dissect_fr_common(tvb, pinfo, tree, FALSE);
450 dissect_fr_phdr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
452 dissect_fr_common(tvb, pinfo, tree, TRUE);
455 static void dissect_fr_uncompressed(tvbuff_t *tvb, packet_info *pinfo,
458 proto_item *ti = NULL;
459 proto_tree *fr_tree = NULL;
461 if (check_col(pinfo->cinfo, COL_PROTOCOL))
462 col_set_str(pinfo->cinfo, COL_PROTOCOL, "FR");
463 if (check_col(pinfo->cinfo, COL_INFO))
464 col_clear(pinfo->cinfo, COL_INFO);
467 ti = proto_tree_add_protocol_format(tree, proto_fr, tvb, 0, -1, "Frame Relay");
468 fr_tree = proto_item_add_subtree(ti, ett_fr);
470 dissect_fr_nlpid(tvb, 0, pinfo, tree, ti, fr_tree, XDLC_U);
473 static void dissect_fr_nlpid(tvbuff_t *tvb, int offset, packet_info *pinfo,
474 proto_tree *tree, proto_item *ti,
475 proto_tree *fr_tree, guint8 fr_ctrl)
481 * Tentatively set the Frame Relay item not to include the NLPID,
482 * as OSI network layer protocols consider it to be part of
485 proto_item_set_end(ti, tvb, offset);
486 fr_nlpid = tvb_get_guint8 (tvb,offset);
489 proto_tree_add_text(fr_tree, tvb, offset, 1, "Padding");
492 /* Include the padding in the top-level protocol tree item. */
493 proto_item_set_end(ti, tvb, offset);
495 fr_nlpid=tvb_get_guint8( tvb,offset);
499 * OSI network layer protocols consider the NLPID to be part
500 * of the frame, so we'll pass it as part of the payload and,
501 * if the protocol is one of those, add it as a hidden item here.
502 * We check both the generic OSI NLPID dissector table and
503 * the Frame Relay OSI NLPID dissector table - the latter is for
504 * NLPID's such as 0x08, which is Q.933 in Frame Relay but
505 * other protocols (e.g., Q.931) on other network layers.
507 * "OSI network layer protocols" includes Q.933.
509 * XXX - note that an NLPID of 0x08 for Q.933 could either be a
510 * Q.933 signaling message or a message for a protocol
511 * identified by a 2-octet layer 2 protocol type and a
512 * 2-octet layer 3 protocol type, those protocol type
513 * octets having the values from octets 6, 6a, 7, and 7a
514 * of a Q.931 low layer compatibility information element
515 * (section 4.5.19 of Q.931; Q.933 says they have the values
516 * from a Q.933 low layer compatibility information element,
517 * but Q.933 low layer compatibility information elements
518 * don't have protocol values in them).
520 * Assuming that, as Q.933 seems to imply, that Q.933 messages
521 * look just like Q.931 messages except where it explicitly
522 * says they differ, then the octet after the NLPID would,
523 * in a Q.933 message, have its upper 4 bits zero (that's
524 * the length of the call reference value, in Q.931, and
525 * is limited to 15 or fewer octets). As appears to be the case,
526 * octet 6 of a Q.931 low layer compatibility element has the
527 * 0x40 bit set, so you can distinguish between a Q.933
528 * message and an encapsulated packet by checking whether
529 * the upper 4 bits of the octet after the NLPID are zero.
531 * Either that, or it's Q.933 iff the DLCI is 0.
533 next_tvb = tvb_new_subset(tvb,offset,-1,-1);
534 if (dissector_try_port(osinl_subdissector_table, fr_nlpid, next_tvb,
536 dissector_try_port(fr_osinl_subdissector_table, fr_nlpid, next_tvb,
539 * Yes, we got a match. Add the NLPID as a hidden item,
540 * so you can, at least, filter on it.
543 proto_tree_add_uint_hidden(fr_tree, hf_fr_nlpid,
544 tvb, offset, 1, fr_nlpid );
549 * All other protocols don't.
551 * XXX - what about Cisco/Gang-of-Four LMI? Is the 0x09 considered
552 * to be part of the LMI PDU?
555 proto_tree_add_uint(fr_tree, hf_fr_nlpid, tvb, offset, 1, fr_nlpid );
562 /* Include the NLPID and SNAP header in the top-level
563 protocol tree item. */
564 proto_item_set_end(ti, tvb, offset+5);
566 dissect_snap(tvb, offset, pinfo, tree, fr_tree, fr_ctrl,
567 hf_fr_oui, hf_fr_snaptype, hf_fr_pid, 0);
572 /* Include the NLPID in the top-level protocol tree item. */
573 proto_item_set_end(ti, tvb, offset);
575 next_tvb = tvb_new_subset(tvb,offset,-1,-1);
576 if (!dissector_try_port(fr_subdissector_table,fr_nlpid,
577 next_tvb, pinfo, tree))
578 call_dissector(data_handle,next_tvb, pinfo, tree);
583 static void dissect_lapf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
585 proto_tree_add_text(tree, tvb, 0, 0, "Frame relay lapf not yet implemented");
586 call_dissector(data_handle,tvb_new_subset(tvb,0,-1,-1),pinfo,tree);
588 static void dissect_fr_xid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
590 proto_tree_add_text(tree, tvb, 0, 0, "Frame relay xid not yet implemented");
591 call_dissector(data_handle,tvb_new_subset(tvb,0,-1,-1),pinfo,tree);
594 /* Register the protocol with Ethereal */
595 void proto_register_fr(void)
597 static hf_register_info hf[] = {
599 "EA", "fr.ea", FT_BOOLEAN, 8, TFS(&ea_string),
600 FRELAY_EA, "Extended Address", HFILL }},
601 { &hf_fr_upper_dlci, {
602 "Upper DLCI", "fr.upper_dlci", FT_UINT8, BASE_HEX,
603 NULL, FRELAY_UPPER_DLCI, "Upper bits of DLCI", HFILL }},
605 "CR", "fr.cr", FT_BOOLEAN, 8, TFS(&cmd_string),
606 FRELAY_CR, "Command/Response", HFILL }},
607 { &hf_fr_second_dlci, {
608 "Second DLCI", "fr.second_dlci", FT_UINT8, BASE_HEX,
609 NULL, FRELAY_SECOND_DLCI, "Bits below upper bits of DLCI", HFILL }},
611 "FECN", "fr.fecn", FT_BOOLEAN, 8,
612 NULL, FRELAY_FECN, "Forward Explicit Congestion Notification", HFILL }},
614 "BECN", "fr.becn", FT_BOOLEAN, 8,
615 NULL, FRELAY_BECN, "Backward Explicit Congestion Notification", HFILL }},
617 "DE", "fr.de", FT_BOOLEAN, 8,
618 NULL, FRELAY_DE, "Discard Eligibility", HFILL }},
619 { &hf_fr_third_dlci, {
620 "Third DLCI", "fr.third_dlci", FT_UINT8, BASE_HEX,
621 NULL, FRELAY_THIRD_DLCI, "Additional bits of DLCI", HFILL }},
622 { &hf_fr_dlcore_control, {
623 "DL-CORE Control", "fr.dlcore_control", FT_UINT8, BASE_HEX,
624 NULL, FRELAY_LOWER_DLCI, "DL-Core control bits", HFILL }},
625 { &hf_fr_lower_dlci, {
626 "Lower DLCI", "fr.lower_dlci", FT_UINT8, BASE_HEX,
627 NULL, FRELAY_LOWER_DLCI, "Lower bits of DLCI", HFILL }},
629 "DC", "fr.dc", FT_BOOLEAN, 16, TFS(&ctrl_string),
630 FRELAY_CR, "Address/Control", HFILL }},
632 "DLCI", "fr.dlci", FT_UINT32, BASE_DEC,
633 NULL, 0x0, "Data-Link Connection Identifier", HFILL }},
635 "Control Field", "fr.control", FT_UINT8, BASE_HEX,
636 NULL, 0x0, "Control field", HFILL }},
638 "N(R)", "fr.control.n_r", FT_UINT16, BASE_DEC,
639 NULL, XDLC_N_R_EXT_MASK, "", HFILL }},
641 "N(S)", "fr.control.n_s", FT_UINT16, BASE_DEC,
642 NULL, XDLC_N_S_EXT_MASK, "", HFILL }},
644 "Poll", "fr.control.p", FT_BOOLEAN, 8,
645 TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
647 "Poll", "fr.control.p", FT_BOOLEAN, 16,
648 TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
650 "Final", "fr.control.f", FT_BOOLEAN, 8,
651 TFS(&flags_set_truth), XDLC_P_F, "", HFILL }},
653 "Final", "fr.control.f", FT_BOOLEAN, 16,
654 TFS(&flags_set_truth), XDLC_P_F_EXT, "", HFILL }},
656 "Supervisory frame type", "fr.control.s_ftype", FT_UINT16, BASE_HEX,
657 VALS(stype_vals), XDLC_S_FTYPE_MASK, "", HFILL }},
658 { &hf_fr_u_modifier_cmd, {
659 "Command", "lapd.control.u_modifier_cmd", FT_UINT8, BASE_HEX,
660 VALS(modifier_vals_cmd), XDLC_U_MODIFIER_MASK, "", HFILL }},
661 { &hf_fr_u_modifier_resp, {
662 "Response", "lapd.control.u_modifier_resp", FT_UINT8, BASE_HEX,
663 VALS(modifier_vals_resp), XDLC_U_MODIFIER_MASK, "", HFILL }},
665 "Frame type", "fr.control.ftype", FT_UINT16, BASE_HEX,
666 VALS(ftype_vals), XDLC_I_MASK, "", HFILL }},
667 { &hf_fr_ftype_s_u, {
668 "Frame type", "fr.control.ftype", FT_UINT8, BASE_HEX,
669 VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
670 { &hf_fr_ftype_s_u_ext, {
671 "Frame type", "fr.control.ftype", FT_UINT16, BASE_HEX,
672 VALS(ftype_vals), XDLC_S_U_MASK, "", HFILL }},
674 "NLPID", "fr.nlpid", FT_UINT8, BASE_HEX,
675 VALS(fr_nlpid_vals), 0x0, "Frame Relay Encapsulated Protocol NLPID", HFILL }},
677 "Organization Code", "fr.snap.oui", FT_UINT24, BASE_HEX,
678 VALS(oui_vals), 0x0, "", HFILL }},
680 "Protocol ID", "fr.snap.pid", FT_UINT16, BASE_HEX,
681 NULL, 0x0, "", HFILL }},
683 "Type", "fr.snaptype", FT_UINT16, BASE_HEX,
684 VALS(etype_vals), 0x0, "Frame Relay SNAP Encapsulated Protocol", HFILL }},
685 { &hf_fr_chdlctype, {
686 "Type", "fr.chdlctype", FT_UINT16, BASE_HEX,
687 VALS(chdlc_vals), 0x0, "Frame Relay Cisco HDLC Encapsulated Protocol", HFILL }},
690 /* Setup protocol subtree array */
691 static gint *ett[] = {
696 static enum_val_t fr_encap_options[] = {
697 { "frf-3.2", "FRF 3.2/Cisco HDLC", FRF_3_2 },
698 { "gprs-ns", "GPRS Network Service", GPRS_NS },
699 { "ethernet", "Raw Ethernet", RAW_ETHER },
702 module_t *frencap_module;
704 proto_fr = proto_register_protocol("Frame Relay", "FR", "fr");
705 proto_register_field_array(proto_fr, hf, array_length(hf));
706 proto_register_subtree_array(ett, array_length(ett));
708 fr_subdissector_table = register_dissector_table("fr.ietf",
709 "Frame Relay NLPID", FT_UINT8, BASE_HEX);
710 fr_osinl_subdissector_table = register_dissector_table("fr.osinl",
711 "Frame Relay OSI NLPID", FT_UINT8, BASE_HEX);
713 register_dissector("fr_uncompressed", dissect_fr_uncompressed, proto_fr);
714 register_dissector("fr", dissect_fr, proto_fr);
716 frencap_module = prefs_register_protocol(proto_fr, NULL);
717 prefs_register_enum_preference(frencap_module, "encap", "Encapsulation",
718 "Encapsulation", &fr_encap,
719 fr_encap_options, FALSE);
722 void proto_reg_handoff_fr(void)
724 dissector_handle_t fr_handle, fr_phdr_handle;
726 fr_handle = create_dissector_handle(dissect_fr, proto_fr);
727 dissector_add("gre.proto", GRE_FR, fr_handle);
728 dissector_add("wtap_encap", WTAP_ENCAP_FRELAY, fr_handle);
730 fr_phdr_handle = create_dissector_handle(dissect_fr_phdr, proto_fr);
731 dissector_add("wtap_encap", WTAP_ENCAP_FRELAY_WITH_PHDR, fr_phdr_handle);
733 eth_handle = find_dissector("eth");
734 gprs_ns_handle = find_dissector("gprs_ns");
735 data_handle = find_dissector("data");
737 osinl_subdissector_table = find_dissector_table("osinl");