MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-qllc.c
blob183451644780107bb320e72e4f7d918380ab8749
1 /* packet-qllc.c
2 * Routines for QLLC protocol - Qualified? LLC
3 * Gilbert Ramirez <gram@alumni.rice.edu>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 2001 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "config.h"
28 #include <glib.h>
29 #include <epan/packet.h>
31 static int proto_qllc = -1;
32 static int hf_qllc_address = -1;
33 static int hf_qllc_control = -1;
35 static gint ett_qllc = -1;
37 static dissector_handle_t sna_handle;
39 #define QSM 0x93
40 #define QDISC 0x53
41 #define QXID 0xbf
42 #define QTEST 0xf3
43 #define QRR 0xf1
44 #define QRD 0x53
45 #define QUA 0x73
46 #define QDM 0x1f
47 #define QFRMR 0x97
48 #define QUI 0x03
49 #define QUI_NO_REPLY 0x13
50 #define QSIM 0x17
52 #define QRD_QDISC_VALUE 0x53
53 #define QDISC_TEXT "QDISC"
54 #define QRD_TEXT "QRD"
56 /* Control Field */
57 static const value_string qllc_control_vals[] = {
58 { QUI, "QUI" },
59 { QUI_NO_REPLY, "QUI - reply required" },
60 { QSIM, "QSIM" },
61 { QDM, "QDM" },
62 { QUA, "QUA" },
63 { QSM, "QSM" },
64 { QFRMR, "QFRMR" },
65 { QXID, "QXID" },
66 { QRR, "QRR" },
67 { QTEST, "QTEST" },
68 { QDISC, QDISC_TEXT },
69 { QRD, QRD_TEXT },
70 { 0x00, NULL },
74 static int
75 dissect_qllc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
77 proto_tree *qllc_tree;
78 proto_item *qllc_ti;
79 gboolean *q_bit_set = (gboolean *)data;
80 guint8 addr, ctrl;
81 gboolean command = FALSE;
84 * If the Q bit isn't set, this is just SNA data.
86 if (!(*q_bit_set)) {
87 call_dissector(sna_handle, tvb, pinfo, tree);
88 return tvb_length(tvb);
91 /* Summary information */
92 col_set_str(pinfo->cinfo, COL_PROTOCOL, "QLLC");
93 col_clear(pinfo->cinfo, COL_INFO);
95 qllc_ti = proto_tree_add_item(tree, proto_qllc, tvb, 0, -1, ENC_NA);
96 qllc_tree = proto_item_add_subtree(qllc_ti, ett_qllc);
98 /* Get the address; we need it to determine if this is a
99 * COMMAND or a RESPONSE */
100 addr = tvb_get_guint8(tvb, 0);
101 proto_tree_add_item(qllc_tree, hf_qllc_address, tvb, 0, 1, ENC_BIG_ENDIAN);
103 /* The address field equals X'FF' in commands (except QRR)
104 * and anything in responses. */
105 ctrl = tvb_get_guint8(tvb, 1);
106 if (ctrl != QRR && addr == 0xff) {
107 command = TRUE;
111 /* Disambiguate QRD_QDISC_VALUE, based on whether this packet is
112 * a COMMAND or RESPONSE. */
113 if (ctrl == QRD_QDISC_VALUE) {
114 if (command) {
115 col_set_str(pinfo->cinfo, COL_INFO, QDISC_TEXT);
116 if (tree) {
117 proto_tree_add_text(qllc_tree, tvb,
118 1, 1, "Control Field: %s (0x%02x)", QDISC_TEXT, ctrl);
121 else {
122 col_set_str(pinfo->cinfo, COL_INFO, QRD_TEXT);
123 if (tree) {
124 proto_tree_add_text(qllc_tree, tvb,
125 1, 1, "Control Field: %s (0x%02x)", QRD_TEXT, ctrl);
129 /* Add the field for filtering purposes */
130 if (tree) {
131 proto_item *hidden_item;
132 hidden_item = proto_tree_add_uint(qllc_tree, hf_qllc_control, tvb,
133 1, 1, ctrl);
134 PROTO_ITEM_SET_HIDDEN(hidden_item);
137 else {
138 /* Non-ambiguous control field value */
139 col_add_str(pinfo->cinfo, COL_INFO,
140 val_to_str(ctrl, qllc_control_vals,
141 "Control Field: 0x%02x (unknown)"));
143 proto_tree_add_uint(qllc_tree, hf_qllc_control, tvb,
144 1, 1, ctrl);
147 /* Do we have an I field ? */
148 /* XXX - I field exists for QUI too, but only for subarea nodes.
149 * Need to test for this. */
150 if (ctrl == QXID || ctrl == QTEST || ctrl == QFRMR) {
151 /* yes */
154 return tvb_length(tvb);
157 void
158 proto_register_qllc(void)
160 static hf_register_info hf[] = {
161 { &hf_qllc_address,
162 { "Address Field", "qllc.address", FT_UINT8, BASE_HEX, NULL, 0x0,
163 NULL, HFILL }},
165 { &hf_qllc_control,
166 { "Control Field", "qllc.control", FT_UINT8, BASE_HEX,
167 VALS(qllc_control_vals), 0x0, NULL, HFILL }},
170 static gint *ett[] = {
171 &ett_qllc,
174 proto_qllc = proto_register_protocol("Qualified Logical Link Control", "QLLC", "qllc");
175 proto_register_field_array(proto_qllc, hf, array_length(hf));
176 proto_register_subtree_array(ett, array_length(ett));
177 new_register_dissector("qllc", dissect_qllc, proto_qllc);
180 void
181 proto_reg_handoff_qllc(void)
183 sna_handle = find_dissector("sna");