HTTPS (almost) everywhere.
[metze/wireshark/wip.git] / epan / dissectors / packet-marker.c
1 /* packet-marker.c
2  * Routines for Link Aggregation Marker protocol dissection.
3  * IEEE Std 802.1AX-2014 Section 6.5
4  *
5  * Copyright 2002 Steve Housley <steve_housley@3com.com>
6  * Copyright 2005 Dominique Bastien <dbastien@accedian.com>
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * SPDX-License-Identifier: GPL-2.0-or-later
13  */
14
15 #include "config.h"
16
17 #include <epan/packet.h>
18 #include <epan/to_str.h>
19 #include <epan/expert.h>
20 #include <epan/slow_protocol_subtypes.h>
21
22 /* General declarations */
23 void proto_register_marker(void);
24 void proto_reg_handoff_marker(void);
25
26 /* MARKER TLVs subtype */
27 #define MARKER_TERMINATOR               0x0
28 #define MARKERPDU_MARKER_INFO           0x1
29 #define MARKERPDU_MARKER_RESPONSE       0x2
30
31 static const value_string marker_vals[] = {
32     { MARKER_TERMINATOR,         "Marker Terminator" },
33     { MARKERPDU_MARKER_INFO,     "Marker Information" },
34     { MARKERPDU_MARKER_RESPONSE, "Marker Response Information" },
35     { 0, NULL }
36 };
37
38 /* Initialise the protocol and registered fields */
39 static int proto_marker = -1;
40
41 static int hf_marker_version_number = -1;
42 static int hf_marker_tlv_type = -1;
43 static int hf_marker_tlv_length = -1;
44 static int hf_marker_req_port = -1;
45 static int hf_marker_req_system = -1;
46 static int hf_marker_req_trans_id = -1;
47 static int hf_marker_req_pad = -1;
48 static int hf_marker_reserved = -1;
49
50 /* Expert Items */
51 static expert_field ei_marker_wrong_tlv_type = EI_INIT;
52 static expert_field ei_marker_wrong_tlv_length = EI_INIT;
53 static expert_field ei_marker_wrong_pad_value = EI_INIT;
54
55 /* Initialise the subtree pointers */
56 static gint ett_marker = -1;
57
58 static int
59 dissect_marker(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
60 {
61     int           offset = 0;
62     guint         tlv_type, tlv_length;
63     guint         port, transactionid, pad;
64     const gchar  *sysidstr;
65
66     proto_tree *marker_tree;
67     proto_item *marker_item, *tlv_type_item, *tlv_length_item, *pad_item;
68
69     col_set_str(pinfo->cinfo, COL_PROTOCOL, "Marker");
70     col_set_str(pinfo->cinfo, COL_INFO, "Marker Protocol");
71
72     marker_item = proto_tree_add_protocol_format(tree, proto_marker, tvb,
73         0, -1, "Marker Protocol");
74     marker_tree = proto_item_add_subtree(marker_item, ett_marker);
75
76     proto_tree_add_item(marker_tree, hf_marker_version_number, tvb,
77         offset, 1, ENC_BIG_ENDIAN);
78     offset += 1;
79
80     tlv_type_item = proto_tree_add_item_ret_uint(marker_tree, hf_marker_tlv_type, tvb,
81         offset, 1, ENC_BIG_ENDIAN, &tlv_type);
82     offset += 1;
83
84     tlv_length_item = proto_tree_add_item_ret_uint(marker_tree, hf_marker_tlv_length, tvb,
85         offset, 1, ENC_BIG_ENDIAN, &tlv_length);
86     offset += 1;
87
88     if (tlv_type == MARKERPDU_MARKER_INFO) {
89         col_set_str(pinfo->cinfo, COL_INFO, "Information");
90     } else if (tlv_type == MARKERPDU_MARKER_RESPONSE) {
91         col_set_str(pinfo->cinfo, COL_INFO, "Response");
92     } else {
93         expert_add_info(pinfo, tlv_type_item, &ei_marker_wrong_tlv_type);
94     }
95     if (tlv_length != 16) {
96         expert_add_info(pinfo, tlv_length_item, &ei_marker_wrong_tlv_length);
97     }
98     proto_tree_add_item_ret_uint(marker_tree, hf_marker_req_port, tvb,
99         offset, 2, ENC_BIG_ENDIAN, &port);
100     offset += 2;
101
102     proto_tree_add_item(marker_tree, hf_marker_req_system, tvb,
103         offset, 6, ENC_NA);
104     sysidstr = tvb_ether_to_str(tvb, offset);
105     offset += 6;
106
107     proto_tree_add_item_ret_uint(marker_tree, hf_marker_req_trans_id, tvb,
108         offset, 4, ENC_BIG_ENDIAN, &transactionid);
109     offset += 4;
110
111     col_append_fstr(pinfo->cinfo, COL_INFO, " SysId=%s, P=%d, TId=%d",
112         sysidstr, port, transactionid);
113
114     pad_item = proto_tree_add_item_ret_uint(marker_tree, hf_marker_req_pad, tvb,
115         offset, 2, ENC_BIG_ENDIAN, &pad);
116     if (pad != 0) {
117         expert_add_info(pinfo, pad_item, &ei_marker_wrong_pad_value);
118     }
119     offset += 2;
120
121     proto_tree_add_item_ret_uint(marker_tree, hf_marker_tlv_type, tvb,
122         offset, 1, ENC_BIG_ENDIAN, &tlv_type);
123     offset += 1;
124
125     proto_tree_add_item_ret_uint(marker_tree, hf_marker_tlv_length, tvb,
126         offset, 1, ENC_BIG_ENDIAN, &tlv_length);
127     offset += 1;
128
129     if (tlv_type == MARKER_TERMINATOR) {
130         if (tlv_length != 0) {
131             expert_add_info(pinfo, tlv_type_item, &ei_marker_wrong_tlv_length);
132         }
133     } else {
134         expert_add_info(pinfo, tlv_type_item, &ei_marker_wrong_tlv_type);
135     }
136
137     proto_tree_add_item(marker_tree, hf_marker_reserved, tvb,
138         offset, 90, ENC_NA);
139     offset += 90;
140     return offset;
141 }
142
143 /* Register the protocol with Wireshark */
144 void
145 proto_register_marker(void)
146 {
147 /* Setup list of header fields */
148
149     static hf_register_info hf[] = {
150         { &hf_marker_version_number,
151           { "Version Number",    "marker.version",
152             FT_UINT8,    BASE_HEX,    NULL,    0x0,
153             "Marker protocol version", HFILL }},
154
155         { &hf_marker_tlv_type,
156           { "TLV Type",    "marker.tlvType",
157             FT_UINT8,    BASE_HEX,    VALS(marker_vals),    0x0,
158             NULL, HFILL }},
159
160         { &hf_marker_tlv_length,
161           { "TLV Length",            "marker.tlvLen",
162             FT_UINT8,    BASE_HEX,    NULL,    0x0,
163             "Length of the Actor TLV", HFILL }},
164
165         { &hf_marker_req_port,
166           { "Requester Port",  "marker.requesterPort",
167             FT_UINT16,    BASE_DEC,    NULL,    0x0,
168             NULL, HFILL }},
169
170         { &hf_marker_req_system,
171           { "Requester System",  "marker.requesterSystem",
172             FT_ETHER,    BASE_NONE,    NULL,    0x0,
173             "Requester System ID encoded as a MAC address", HFILL }},
174
175         { &hf_marker_req_trans_id,
176           { "Requester Transaction ID",  "marker.requesterTransId",
177             FT_UINT32,    BASE_DEC,    NULL,    0x0,
178             NULL, HFILL }},
179
180         { &hf_marker_req_pad,
181           { "Requester Pad",  "marker.requesterPad",
182             FT_UINT32,    BASE_DEC,    NULL,    0x0,
183             NULL, HFILL }},
184
185         { &hf_marker_reserved,
186           { "Reserved",  "marker.reserved",
187             FT_BYTES,    BASE_NONE,    NULL,    0x0,
188             NULL, HFILL }},
189     };
190
191     /* Setup protocol subtree array */
192
193     static gint *ett[] = {
194         &ett_marker,
195     };
196
197     static ei_register_info ei[] = {
198     { &ei_marker_wrong_tlv_type,   { "marker.wrong_tlv_type",   PI_MALFORMED, PI_ERROR, "TLV is not expected type",   EXPFILL }},
199     { &ei_marker_wrong_tlv_length, { "marker.wrong_tlv_length", PI_MALFORMED, PI_ERROR, "TLV is not expected length", EXPFILL }},
200     { &ei_marker_wrong_pad_value,  { "marker.wrong_pad_value",  PI_PROTOCOL,  PI_WARN,  "pad value is not 0",         EXPFILL }},
201     };
202
203     expert_module_t* expert_marker;
204
205
206
207     /* Register the protocol name and description */
208
209     proto_marker = proto_register_protocol("Marker", "Link Aggregation Marker Protocol", "marker");
210
211     /* Required function calls to register the header fields and subtrees used */
212
213     proto_register_field_array(proto_marker, hf, array_length(hf));
214     proto_register_subtree_array(ett, array_length(ett));
215     expert_marker = expert_register_protocol(proto_marker);
216     expert_register_field_array(expert_marker, ei, array_length(ei));
217
218 }
219
220 void
221 proto_reg_handoff_marker(void)
222 {
223     dissector_handle_t marker_handle;
224
225     marker_handle = create_dissector_handle(dissect_marker, proto_marker);
226     dissector_add_uint("slow.subtype", MARKER_SUBTYPE, marker_handle);
227 }
228
229 /*
230  * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
231  *
232  * Local variables:
233  * c-basic-offset: 4
234  * tab-width: 8
235  * indent-tabs-mode: nil
236  * End:
237  *
238  * vi: set shiftwidth=4 tabstop=8 expandtab:
239  * :indentSize=4:tabSize=8:noTabs=true:
240  */