Removed trailing whitespaces from .h and .c files using the
[obnox/wireshark/wip.git] / packet-qllc.c
1 /* packet-qllc.c
2  * Routines for QLLC protocol - Qualified? LLC
3  * Gilbert Ramirez <gram@alumni.rice.edu>
4  *
5  * $Id: packet-qllc.c,v 1.6 2002/08/02 23:35:56 jmayer Exp $
6  *
7  * Ethereal - Network traffic analyzer
8  * By Gerald Combs <gerald@ethereal.com>
9  * Copyright 2001 Gerald Combs
10  * 
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.
15  * 
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.
20  * 
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
29
30 #include <glib.h>
31 #include <epan/packet.h>
32
33
34 static int proto_qllc = -1;
35 static int hf_qllc_address = -1;
36 static int hf_qllc_control = -1;
37
38 static gint ett_qllc = -1;
39
40 #define QSM                 0x93
41 #define QDISC               0x53
42 #define QXID                0xbf
43 #define QTEST               0xf3
44 #define QRR                 0xf1
45 #define QRD                 0x53
46 #define QUA                 0x73
47 #define QDM                 0x1f
48 #define QFRMR               0x97
49 #define QUI                 0x03
50 #define QUI_NO_REPLY        0x13
51 #define QSIM                0x17
52
53 #define QRD_QDISC_VALUE     0x53
54 #define QDISC_TEXT          "QDISC"
55 #define QRD_TEXT            "QRD"
56
57 /* Control Field */
58 static const value_string qllc_control_vals[] = {
59     { QUI,          "QUI" },
60     { QUI_NO_REPLY, "QUI - reply required" },
61     { QSIM,         "QSIM" },
62     { QDM,          "QDM" },
63     { QUA,          "QUA" },
64     { QSM,          "QSM" },
65     { QFRMR,        "QFRMR" },
66     { QXID,         "QXID" },
67     { QRR,          "QRR" },
68     { QTEST,        "QTEST" },
69     { QDISC,        QDISC_TEXT },
70     { QRD,          QRD_TEXT },
71     { 0x00, NULL },
72 };
73
74
75 static void
76 dissect_qllc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
77 {
78         proto_tree      *qllc_tree = NULL;
79         proto_item      *qllc_ti = NULL;
80     guint8      address, ctrl;
81     gboolean    command = FALSE;
82
83         /* Summary information */
84         if (check_col(pinfo->cinfo, COL_PROTOCOL))
85                 col_set_str(pinfo->cinfo, COL_PROTOCOL, "QLLC");
86         if (check_col(pinfo->cinfo, COL_INFO))
87                 col_clear(pinfo->cinfo, COL_INFO);
88
89         if (tree) {
90                 qllc_ti = proto_tree_add_item(tree, proto_qllc, tvb, 0, -1,
91                     FALSE);
92                 qllc_tree = proto_item_add_subtree(qllc_ti, ett_qllc);
93
94     }
95
96     /* Get the address; we need it to determine if this is a
97      * COMMAND or a RESPONSE */
98     address = tvb_get_guint8(tvb, 0);
99     if (tree) {
100                 proto_tree_add_item(qllc_tree, hf_qllc_address, tvb, 0, 1, FALSE);
101     }
102
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 && address == 0xff) {
107         command = TRUE;
108     }
109
110
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             if (check_col(pinfo->cinfo, COL_INFO)) {
116                 col_set_str(pinfo->cinfo, COL_INFO, QDISC_TEXT);
117             }
118             if (tree) {
119                 proto_tree_add_text(qllc_tree, tvb,
120                         1, 1, "Control Field: %s (0x%02x)", QDISC_TEXT, ctrl);
121             }
122         }
123         else {
124             if (check_col(pinfo->cinfo, COL_INFO)) {
125                 col_set_str(pinfo->cinfo, COL_INFO, QRD_TEXT);
126             }
127             if (tree) {
128                 proto_tree_add_text(qllc_tree, tvb,
129                         1, 1, "Control Field: %s (0x%02x)", QRD_TEXT, ctrl);
130             }
131         }
132
133         /* Add the field for filtering purposes */
134         if (tree) {
135             proto_tree_add_uint_hidden(qllc_tree, hf_qllc_control, tvb,
136                     1, 1, ctrl);
137         }
138     }
139     else {
140         /* Non-ambiguous control field value */
141         if (check_col(pinfo->cinfo, COL_INFO)) {
142             col_set_str(pinfo->cinfo, COL_INFO, 
143                     val_to_str(ctrl, qllc_control_vals,
144                         "Control Field: 0x%02x (unknown)"));
145         }
146         if (tree) {
147             proto_tree_add_uint(qllc_tree, hf_qllc_control, tvb,
148                     1, 1, ctrl);
149         }
150     }
151
152     /* Do we have an I field ? */
153     /* XXX - I field exists for QUI too, but only for subarea nodes. 
154      * Need to test for this. */
155     if (ctrl == QXID || ctrl == QTEST || ctrl == QFRMR) {
156         /* yes */
157     }
158
159 }
160
161
162 void
163 proto_register_qllc(void)
164 {
165         static hf_register_info hf[] = {
166                 { &hf_qllc_address,
167                 { "Address Field",      "qllc.address", FT_UINT8, BASE_HEX, NULL, 0x0,
168                         "", HFILL }},
169
170                 { &hf_qllc_control,
171                 { "Control Field",      "qllc.control", FT_UINT8, BASE_HEX, 
172             VALS(qllc_control_vals), 0x0, "", HFILL }},
173
174         };
175
176         static gint *ett[] = {
177                 &ett_qllc,
178         };
179
180         proto_qllc = proto_register_protocol("Qualified Logical Link Control",
181             "QLLC", "qllc");
182         proto_register_field_array(proto_qllc, hf, array_length(hf));
183         proto_register_subtree_array(ett, array_length(ett));
184         register_dissector("qllc", dissect_qllc, proto_qllc);
185 }
186