Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-grebonding.c
blobefaa8e7aba1e9e2530e3877c595eaa436143e5ee
1 /* packet-grebonding.c
2 * Routines for Huawei's GRE bonding control (RFC8157) dissection
3 * Thomas Vogt
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later
11 * version.
13 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
14 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * details.
17 * You should have received a copy of the GNU General Public License along with this program; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 #include "config.h"
23 #include <epan/packet.h>
24 #include <epan/capture_dissectors.h>
25 #include <epan/expert.h>
26 #include <epan/to_str.h>
28 void proto_reg_handoff_greb(void);
29 void proto_register_greb(void);
31 static dissector_handle_t greb_handle;
33 static int proto_greb;
35 static int hf_greb_message_type;
36 static int hf_greb_tunnel_type;
38 static int hf_greb_attr;
39 static int hf_greb_attr_type;
40 static int hf_greb_attr_length;
41 static int hf_greb_attr_val_uint64;
42 static int hf_greb_attr_val_none;
43 static int hf_greb_attr_val_ipv6;
44 static int hf_greb_attr_val_ipv4;
45 static int hf_greb_attr_val_time;
46 static int hf_greb_attr_val_string;
47 static int hf_greb_attr_DSL_prot;
48 static int hf_greb_attr_dt_bras_name;
50 static int hf_greb_attr_filter_commit;
51 static int hf_greb_attr_filter_ack;
52 static int hf_greb_attr_filter_packetsum;
53 static int hf_greb_attr_filter_packetid;
54 static int hf_greb_attr_filter_item_type;
55 static int hf_greb_attr_filter_item_length;
56 static int hf_greb_attr_filter_item_enabled;
57 static int hf_greb_attr_filter_item_desc_length;
58 static int hf_greb_attr_filter_item_desc_val;
59 static int hf_greb_attr_filter_item_val;
61 static int hf_greb_attr_error;
63 /* Initialize the subtree pointers */
64 static int ett_grebonding;
65 static int ett_grebonding_attrb;
66 static int ett_grebonding_filter_list;
67 static int ett_grebonding_filter_item;
68 static int ett_grebonding_ipv6_prefix;
70 static int *ett[] = {
71 &ett_grebonding,
72 &ett_grebonding_attrb,
73 &ett_grebonding_filter_list,
74 &ett_grebonding_filter_item,
75 &ett_grebonding_ipv6_prefix
79 static const value_string greb_message_types[] = {
80 #define GREB_TUNNEL_SETUP_REQ 1
81 {GREB_TUNNEL_SETUP_REQ, "Tunnel setup request"},
82 #define GREB_TUNNEL_SETUP_ACK 2
83 {GREB_TUNNEL_SETUP_ACK, "Tunnel setup accept"},
84 #define GREB_TUNNEL_SETUP_DENY 3
85 {GREB_TUNNEL_SETUP_DENY, "Tunnel setup deny"},
86 #define GREB_HELLO 4
87 {GREB_HELLO, "Hello"},
88 #define GREB_TUNNEL_TEAR_DOWN 5
89 {GREB_TUNNEL_TEAR_DOWN, "Tunnel tear down"},
90 #define GREB_NOTIFY 6
91 {GREB_NOTIFY, "Notify"},
92 #define GREB_LINK_DETECTION 10
93 {GREB_LINK_DETECTION, "Link Detection (Telekom specific)"},
94 {0, NULL}
97 static const value_string greb_tunnel_types[] = {
98 #define GREB_TUNNEL_LTE 0b0000
99 {GREB_TUNNEL_LTE, "LTE-GRE tunnel (Telekom specific)"},
100 #define GREB_TUNNEL_FIRST 0b0001
101 {GREB_TUNNEL_FIRST, "first tunnel (most likely the DSL GRE tunnel)"},
102 #define GREB_TUNNEL_SECOND 0b0010
103 {GREB_TUNNEL_SECOND, "second tunnel (most likely the LTE GRE tunnel)" },
104 #define GREB_TUNNEL_DSL 0b1000
105 {GREB_TUNNEL_DSL, "DSL Tunnel (Telekom specific)" },
106 {0, NULL}
109 static const value_string greb_error_codes[] = {
110 #define GREB_ERROR_HAAP_UNREACHABLE_LTE 1
111 {GREB_ERROR_HAAP_UNREACHABLE_LTE, "HAAP not reachable over LTE"},
112 #define GREB_ERROR_HAAP_UNREACHABLE_DSL 2
113 {GREB_ERROR_HAAP_UNREACHABLE_DSL, "HAAP not reachable via DSL"},
114 #define GREB_ERROR_LTE_TUNNEL_FAILED 3
115 {GREB_ERROR_LTE_TUNNEL_FAILED, "LTE tunnel failed"},
116 #define GREB_ERROR_DSL_TUNNEL_FAILED 4
117 {GREB_ERROR_DSL_TUNNEL_FAILED, "DSL tunnel failed"},
118 #define GREB_ERROR_DSL_UID_NOT_ALLOWED 5
119 {GREB_ERROR_DSL_UID_NOT_ALLOWED, "DSL UID not allowed"},
120 #define GREB_ERROR_UID_NOT_ALLOWED 6
121 {GREB_ERROR_UID_NOT_ALLOWED, "UID not allowed"},
122 #define GREB_ERROR_UID_NOT_MATCHING 7
123 {GREB_ERROR_UID_NOT_MATCHING, "LTE and DSL User IDs do not match"},
124 #define GREB_ERROR_SECOND_SESSION_WITH_UID 8
125 {GREB_ERROR_SECOND_SESSION_WITH_UID, "Session with the same User ID already exists"},
126 #define GREB_ERROR_CIN_NOT_PERMITTED 9
127 {GREB_ERROR_CIN_NOT_PERMITTED, "Denied: CIN not permitted"},
128 #define GREB_ERROR_MAINTENANCE 10
129 {GREB_ERROR_MAINTENANCE, "Terminated for maintenance"},
130 #define GREB_ERROR_BACKEND_COMMUNICATION_FAILURE_LTE 11
131 {GREB_ERROR_BACKEND_COMMUNICATION_FAILURE_LTE, "HAAP Backend failure on LTE tunnel establishment"},
132 #define GREB_ERROR_BACKEND_COMMUNICATION_FAILURE_DSL 12
133 {GREB_ERROR_BACKEND_COMMUNICATION_FAILURE_DSL, "HAAP Backend failure on DSL tunnel establishment"},
134 #define GREB_ERROR_DT_HAAP_UNREACHABLE_DSL 401
135 {GREB_ERROR_DT_HAAP_UNREACHABLE_DSL, "DSL GRE tunnel to the HAAP failed (Telekom specific)"},
136 #define GREB_ERROR_DT_HAAP_UNREACHABLE_LTE 402
137 {GREB_ERROR_DT_HAAP_UNREACHABLE_LTE, "LTE GRE tunnel to the HAAP failed (Telekom specific)"},
138 #define GREB_ERROR_DT_UID_NOT_MATCHING 403
139 {GREB_ERROR_DT_UID_NOT_MATCHING, "Mismatch of LTE and DSL User IDs (Telekom specific)"},
140 #define GREB_ERROR_DT_SECOND_SESSION_WITH_UID 404
141 {GREB_ERROR_DT_SECOND_SESSION_WITH_UID, "Session with the same User ID already exists (Telekom specific)"},
142 #define GREB_ERROR_DT_CIN_NOT_PERMITTED 405
143 {GREB_ERROR_DT_CIN_NOT_PERMITTED, "Client uses a not permitted CIN (Telekom specific)"},
144 #define GREB_ERROR_DT_DSL_TUNNEL_FAILED 406
145 {GREB_ERROR_DT_DSL_TUNNEL_FAILED, "Communication error during the DSL Tunnel setup (Telekom specific)"},
146 #define GREB_ERROR_DT_LTE_TUNNEL_FAILED 407
147 {GREB_ERROR_DT_LTE_TUNNEL_FAILED, "Communication error during the LTE Tunnel setup (Telekom specific)"},
148 #define GREB_ERROR_DT_MAINTENANCE 501
149 {GREB_ERROR_DT_MAINTENANCE, "Terminated for maintenance (Telekom specific)"},
150 #define GREB_ERROR_DT_LTE_PARAM_UPDATE 502
151 {GREB_ERROR_DT_LTE_PARAM_UPDATE, "LTE terminated to update parameters (Telekom specific)"},
152 #define GREB_ERROR_DT_DSL_PARAM_UPDATE 503
153 {GREB_ERROR_DT_DSL_PARAM_UPDATE, "DSL terminated to update parameters (Telekom specific)"},
154 {0,NULL}
157 static const value_string greb_attribute_types[] = {
158 #define GREB_ATTRB_H_IP4_ADDR 1
159 {GREB_ATTRB_H_IP4_ADDR, "H IPv4 address"},
160 #define GREB_ATTRB_H_IP6_ADDR 2
161 {GREB_ATTRB_H_IP6_ADDR, "H IPv6 address"},
162 #define GREB_ATTRB_CIN 3
163 {GREB_ATTRB_CIN, "CIN (Client ID)"},
164 #define GREB_ATTRB_SESSIONID 4
165 {GREB_ATTRB_SESSIONID, "Session ID"},
166 #define GREB_ATTRB_TIME 5
167 {GREB_ATTRB_TIME, "Time"},
168 #define GREB_ATTRB_BYPASS_RATE 6
169 {GREB_ATTRB_BYPASS_RATE, "Bypass rate"},
170 #define GREB_ATTRB_DOWNSTREAM_RATE 7
171 {GREB_ATTRB_DOWNSTREAM_RATE, "Downstream rate"},
172 #define GREB_ATTRB_FILTER_LIST 8
173 {GREB_ATTRB_FILTER_LIST, "Filter list"},
174 #define GREB_ATTRB_RTT_THRESHOLD 9
175 {GREB_ATTRB_RTT_THRESHOLD, "RTT threshold"},
176 #define GREB_ATTRB_BYPASS_INTERVAL 10
177 {GREB_ATTRB_BYPASS_INTERVAL, "Bypass interval"},
178 #define GREB_ATTRB_ONLY_FIRST_TUNNEL 11
179 {GREB_ATTRB_ONLY_FIRST_TUNNEL, "Only first tunnel (DSL)"},
180 #define GREB_ATTRB_OVERFLOW_TO_SECOND 12
181 {GREB_ATTRB_OVERFLOW_TO_SECOND, "Overflow to second tunnel (LTE)"},
182 #define GREB_ATTRB_IPV6_PREFIX 13
183 {GREB_ATTRB_IPV6_PREFIX, "IPv6 prefix assigned by HAAP"},
184 #define GREB_ATTRB_ACTIVE_HELLO_INTERVAL 14
185 {GREB_ATTRB_ACTIVE_HELLO_INTERVAL, "Active hello interval"},
186 #define GREB_ATTRB_HELLO_RETRYS 15
187 {GREB_ATTRB_HELLO_RETRYS, "Hello retries"},
188 #define GREB_ATTRB_IDLE_TIMEOUT 16
189 {GREB_ATTRB_IDLE_TIMEOUT, "Idle timeout"},
190 #define GREB_ATTRB_ERROR 17
191 {GREB_ATTRB_ERROR, "Error"},
192 #define GREB_ATTRB_DSL_FAIL 18
193 {GREB_ATTRB_DSL_FAIL, "DSL fail"},
194 #define GREB_ATTRB_LTE_FAIL 19
195 {GREB_ATTRB_LTE_FAIL, "LTE fail"},
196 #define GREB_ATTRB_BONDING_KEY 20
197 {GREB_ATTRB_BONDING_KEY, "Bonding key"},
198 #define GREB_ATTRB_IPV6_PREFIX2 21
199 {GREB_ATTRB_IPV6_PREFIX2, "IPv6 prefix assigned to host"},
200 #define GREB_ATTRB_CONFIGURED_UPSTREAM 22
201 {GREB_ATTRB_CONFIGURED_UPSTREAM, "Configured upstream"},
202 #define GREB_ATTRB_CONFIGURED_DOWNSTREAM 23
203 {GREB_ATTRB_CONFIGURED_DOWNSTREAM, "Configured downstream"},
204 #define GREB_ATTRB_RTT_VIOLATION 24
205 {GREB_ATTRB_RTT_VIOLATION, "RTT violation"},
206 #define GREB_ATTRB_RTT_COMPLIANCE 25
207 {GREB_ATTRB_RTT_COMPLIANCE, "RTT compliance"},
208 #define GREB_ATTRB_DIAG_START_BONDING 26
209 {GREB_ATTRB_DIAG_START_BONDING, "Diagnostic start bonding"},
210 #define GREB_ATTRB_DIAG_START_DSL 27
211 {GREB_ATTRB_DIAG_START_DSL, "Diagnostic start DSL"},
212 #define GREB_ATTRB_DIAG_END 29
213 {GREB_ATTRB_DIAG_END, "Diagnostic End"},
214 #define GREB_ATTRB_FILTER_LIST_ACK 30
215 {GREB_ATTRB_FILTER_LIST_ACK, "Filter list ACK"},
216 #define GREB_ATTRB_IDLE_HELLO_INTERVAL 31
217 {GREB_ATTRB_IDLE_HELLO_INTERVAL, "Idle hello interval"},
218 #define GREB_ATTRB_NO_TRAFFIC_INTERVAL 32
219 {GREB_ATTRB_NO_TRAFFIC_INTERVAL, "No traffic interval"},
220 #define GREB_ATTRB_ACTIVE_HELLO_STATE 33
221 {GREB_ATTRB_ACTIVE_HELLO_STATE, "Active hello state"},
222 #define GREB_ATTRB_IDLE_HELLO_STATE 34
223 {GREB_ATTRB_IDLE_HELLO_STATE, "Idle hello state"},
224 #define GREB_ATTRB_TUNNEL_VERIFICATION 35
225 {GREB_ATTRB_TUNNEL_VERIFICATION, "Tunnel verification"},
226 #define GREB_ATTRB_DT_DSL_PROT 53
227 {GREB_ATTRB_DT_DSL_PROT, "DSL protocol / link type (Telekom specific)"},
228 #define GREB_ATTRB_DT_BRAS_NAME 54
229 {GREB_ATTRB_DT_BRAS_NAME, "Broadband Remote Access Server name (Telekom specific)"},
230 #define GREB_ATTRB_DT_DOWN_REORDER_TIME 56
231 {GREB_ATTRB_DT_DOWN_REORDER_TIME, "Max. downstream reordering buffer time (Telekom specific)"},
232 #define GREB_ATTRB_DT_COM_UP_BURST_TIME 57
233 {GREB_ATTRB_DT_COM_UP_BURST_TIME, "Committed upstream burst time (Telekom specific)"},
234 #define GREB_ATTRB_DT_UPSTREAM_RATE 59
235 {GREB_ATTRB_DT_UPSTREAM_RATE, "DSL synchronization Rate upstream (Telekom specific)"},
236 {255, "FIN"},
237 {0, NULL}
240 static const value_string greb_DT_DSL_prots[] = {
241 #define DT_UNDEF 0
242 {DT_UNDEF, "Undefined"},
243 #define DT_ADSL_B 1
244 {DT_ADSL_B, "ADSL/ADSL2/ADSL2+ Annex B"},
245 #define DT_ADSL_J 2
246 {DT_ADSL_J, "ADSL2+ Annex J"},
247 #define DT_VDSL 3
248 {DT_VDSL, "VDSL2"},
249 #define DT_VDSL_VEC 4
250 {DT_VDSL_VEC, "VDSL2 Vectoring"},
251 {0, NULL}
255 static const value_string greb_filter_types[] = {
256 #define GREB_ATTRB_FILTER_FQDN 1
257 {GREB_ATTRB_FILTER_FQDN, "FQDN"},
258 #define GREB_ATTRB_FILTER_DSCP 2
259 {GREB_ATTRB_FILTER_DSCP, "DSCP"},
260 #define GREB_ATTRB_FILTER_DPORT 3
261 {GREB_ATTRB_FILTER_DPORT, "Destination Port"},
262 #define GREB_ATTRB_FILTER_DIP 4
263 {GREB_ATTRB_FILTER_DIP, "Destination IP"},
264 #define GREB_ATTRB_FILTER_DIPPORT 5
265 {GREB_ATTRB_FILTER_DIPPORT, "Destination IP&Port"},
266 #define GREB_ATTRB_FILTER_SPORT 6
267 {GREB_ATTRB_FILTER_SPORT, "Source Port"},
268 #define GREB_ATTRB_FILTER_SIP 7
269 {GREB_ATTRB_FILTER_SIP, "Source IP"},
270 #define GREB_ATTRB_FILTER_SIPPORT 8
271 {GREB_ATTRB_FILTER_SIPPORT, "Source IP&Port"},
272 #define GREB_ATTRB_FILTER_SMAC 9
273 {GREB_ATTRB_FILTER_SMAC, "Source Mac"},
274 #define GREB_ATTRB_FILTER_PROTO 10
275 {GREB_ATTRB_FILTER_PROTO, "Protocol"},
276 #define GREB_ATTRB_FILTER_SIPR 11
277 {GREB_ATTRB_FILTER_SIPR, "Source IP Range"},
278 #define GREB_ATTRB_FILTER_DIPR 12
279 {GREB_ATTRB_FILTER_DIPR, "Destination IP Range"},
280 #define GREB_ATTRB_FILTER_SIPRPORT 13
281 {GREB_ATTRB_FILTER_SIPRPORT, "Source IP Range&Port"},
282 #define GREB_ATTRB_FILTER_DIPRPORT 14
283 {GREB_ATTRB_FILTER_DIPRPORT, "Destination IP Range&Port"},
284 #define GREB_ATTRB_DT_COMBO 15
285 {GREB_ATTRB_DT_COMBO, "Combination (Telekom specific)"},
286 {0, NULL}
289 static const value_string greb_filter_ack_codes[] = {
290 #define GREB_ATTRB_FILTER_ACK 0
291 {GREB_ATTRB_FILTER_ACK, "Filter list acknowledged"},
292 #define GREB_ATTRB_FILTER_NACK_NO_OLD 1
293 {GREB_ATTRB_FILTER_NACK_NO_OLD, "Filter list not acknowledged. No previous filter list to use."},
294 #define GREB_ATTRB_FILTER_NACK_OLD_USED 2
295 {GREB_ATTRB_FILTER_NACK_OLD_USED, "Filter list not acknowledged. Previous filter list will be used."},
296 {0, NULL}
299 static void
300 dissect_greb_h_gateway_ip_address(tvbuff_t *tvb, proto_tree *attrb_tree, unsigned offset, unsigned attrb_length)
302 if (attrb_length == 16)
303 proto_tree_add_item(attrb_tree, hf_greb_attr_val_ipv6, tvb, offset, attrb_length, ENC_NA);
304 else if (attrb_length == 4)
305 proto_tree_add_item(attrb_tree, hf_greb_attr_val_ipv4, tvb, offset, attrb_length, ENC_BIG_ENDIAN);
306 else
307 proto_tree_add_item(attrb_tree, hf_greb_attr_val_uint64, tvb, offset, attrb_length, ENC_BIG_ENDIAN);
310 static void
311 dissect_greb_filter_list_ack(tvbuff_t *tvb, proto_tree *attrb_tree, unsigned offset, unsigned attrb_length)
313 proto_item *it_filter;
314 proto_tree *filter_tree;
315 unsigned filter_commit_count = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
317 it_filter = proto_tree_add_none_format(attrb_tree, hf_greb_attr_val_none, tvb, offset, attrb_length,
318 "Filter list ACK - Commit %d", filter_commit_count);
319 filter_tree = proto_item_add_subtree(it_filter, ett_grebonding_filter_list);
320 proto_tree_add_item(filter_tree, hf_greb_attr_filter_commit, tvb, offset, attrb_length - 1, ENC_BIG_ENDIAN);
321 proto_tree_add_item(filter_tree, hf_greb_attr_filter_ack, tvb, offset + attrb_length, 1, ENC_BIG_ENDIAN);
325 static void
326 dissect_greb_filter_list(packet_info *pinfo, tvbuff_t *tvb, proto_tree *attrb_tree, unsigned offset, unsigned attrb_length)
328 proto_item *it_filter;
329 proto_tree *filter_tree;
330 unsigned filter_commit_count = tvb_get_uint32(tvb, offset, ENC_BIG_ENDIAN);
331 unsigned filter_packet_sum = tvb_get_uint16(tvb, offset + 4, ENC_BIG_ENDIAN);
332 unsigned filter_packet_id = tvb_get_uint16(tvb, offset + 6, ENC_BIG_ENDIAN);
333 it_filter = proto_tree_add_none_format(attrb_tree, hf_greb_attr_val_none, tvb, offset, attrb_length,
334 "Filter list - Commit %d, Packet %d/%d", filter_commit_count, filter_packet_id, filter_packet_sum);
335 filter_tree = proto_item_add_subtree(it_filter, ett_grebonding_filter_list);
336 proto_tree_add_item(filter_tree, hf_greb_attr_filter_commit, tvb, offset, 4, ENC_BIG_ENDIAN);
337 proto_tree_add_item(filter_tree, hf_greb_attr_filter_packetid, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
338 proto_tree_add_item(filter_tree, hf_greb_attr_filter_packetsum, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
340 offset += 8;
342 while (offset < attrb_length) {
343 proto_item *it_filter_item;
344 proto_tree *filter_item_tree;
345 unsigned filter_item_length = tvb_get_uint16(tvb, offset + 2, ENC_BIG_ENDIAN);
346 unsigned filter_item_desc_length = tvb_get_uint16(tvb, offset + 6, ENC_BIG_ENDIAN);
347 // bound lengths to not exceed packet
348 if (filter_item_length > (unsigned) tvb_reported_length_remaining(tvb, offset + 2))
349 filter_item_length = tvb_reported_length_remaining(tvb, offset + 2);
350 if (filter_item_desc_length > filter_item_length)
351 filter_item_length = filter_item_desc_length;
353 it_filter_item = proto_tree_add_none_format(filter_tree, hf_greb_attr_val_none, tvb, offset,
354 filter_item_length + 4, "Filter item - %s", tvb_get_string_enc(pinfo->pool, tvb, offset + 8,
355 filter_item_desc_length, ENC_UTF_8));
356 filter_item_tree = proto_item_add_subtree(it_filter_item, ett_grebonding_filter_item);
357 proto_tree_add_item(filter_item_tree, hf_greb_attr_filter_item_type, tvb, offset, 2, ENC_BIG_ENDIAN);
358 proto_tree_add_item(filter_item_tree, hf_greb_attr_filter_item_length, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
359 proto_tree_add_item(filter_item_tree, hf_greb_attr_filter_item_enabled, tvb, offset + 4, 2, ENC_BIG_ENDIAN);
360 proto_tree_add_item(filter_item_tree, hf_greb_attr_filter_item_desc_length, tvb, offset + 6, 2, ENC_BIG_ENDIAN);
361 proto_tree_add_item(filter_item_tree, hf_greb_attr_filter_item_desc_val, tvb, offset + 8,
362 filter_item_desc_length, ENC_UTF_8 | ENC_NA);
363 proto_tree_add_item(filter_item_tree, hf_greb_attr_filter_item_val, tvb, offset + 8 + filter_item_desc_length,
364 filter_item_length - 4 - filter_item_desc_length, ENC_UTF_8 | ENC_NA);
366 offset += filter_item_length + 4;
371 static void
372 dissect_greb_ipv6_prefix(packet_info *pinfo, tvbuff_t *tvb, proto_tree *attrb_tree, unsigned offset, unsigned attrb_length)
374 proto_item *item_ipv6_prefix;
375 proto_tree *ipv6_prefix_tree;
376 unsigned addr_length = attrb_length - 1;
378 ipv6_prefix_tree = proto_tree_add_subtree_format(attrb_tree, tvb, offset, attrb_length,
379 ett_grebonding_ipv6_prefix, &item_ipv6_prefix, "IPv6 prefix - %s/%d",
380 tvb_ip6_to_str(pinfo->pool, tvb, offset), tvb_get_uint8(tvb, offset + addr_length));
381 proto_tree_add_item(ipv6_prefix_tree, hf_greb_attr_val_ipv6, tvb, offset, addr_length, ENC_NA);
382 proto_tree_add_item(ipv6_prefix_tree, hf_greb_attr_val_uint64, tvb, offset + addr_length, 1, ENC_BIG_ENDIAN);
385 static int
386 dissect_greb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
388 proto_item *ti, *it_attrb;
389 proto_tree *greb_tree, *attrb_tree = NULL;
390 unsigned offset = 0;
391 unsigned message_type = tvb_get_uint8(tvb, offset) >> 4;
393 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GREbond");
394 ti = proto_tree_add_protocol_format(tree, proto_greb, tvb, offset, -1, "Huawei GRE bonding control message (%s)",
395 val_to_str(message_type, greb_message_types, "0x%01X (unknown)"));
396 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(message_type, greb_message_types, "0x%02X (unknown)"));
398 greb_tree = proto_item_add_subtree(ti, ett_grebonding);
399 proto_tree_add_item(greb_tree, hf_greb_message_type, tvb, offset, 1, ENC_BIG_ENDIAN);
400 proto_tree_add_item(greb_tree, hf_greb_tunnel_type, tvb, offset, 1, ENC_BIG_ENDIAN);
401 offset++;
403 // going through the attributes, off by one to assure length field exists
404 while (offset + 1 < tvb_captured_length(tvb)) {
405 unsigned attrb_type = tvb_get_uint8(tvb, offset);
406 unsigned attrb_length = tvb_get_uint16(tvb, offset + 1, ENC_BIG_ENDIAN);
408 it_attrb = proto_tree_add_none_format(greb_tree, hf_greb_attr, tvb, offset, attrb_length + 3, "Attribute - %s",
409 val_to_str(attrb_type, greb_attribute_types, "unknown (%d)"));
411 attrb_tree = proto_item_add_subtree(it_attrb, ett_grebonding_attrb);
412 proto_tree_add_item(attrb_tree, hf_greb_attr_type, tvb, offset, 1, ENC_BIG_ENDIAN);
413 proto_tree_add_item(attrb_tree, hf_greb_attr_length, tvb, offset + 1, 2, ENC_BIG_ENDIAN);
414 offset += 3;
416 // bound attrb_length to not exceed packet
417 if (attrb_length > (unsigned) tvb_reported_length_remaining(tvb, offset))
418 attrb_length = tvb_reported_length_remaining(tvb, offset);
420 if (attrb_length > 0) {
421 switch (attrb_type) {
422 case GREB_ATTRB_H_IP4_ADDR:
423 case GREB_ATTRB_H_IP6_ADDR:
424 dissect_greb_h_gateway_ip_address(tvb, attrb_tree, offset, attrb_length);
425 break;
427 case GREB_ATTRB_IPV6_PREFIX2:
428 case GREB_ATTRB_IPV6_PREFIX:
429 dissect_greb_ipv6_prefix(pinfo, tvb, attrb_tree, offset, attrb_length);
430 break;
432 case GREB_ATTRB_TIME:
433 proto_tree_add_item(attrb_tree, hf_greb_attr_val_time, tvb, offset, attrb_length,
434 ENC_TIME_TIMEVAL);
435 break;
437 case GREB_ATTRB_FILTER_LIST:
438 dissect_greb_filter_list(pinfo, tvb, attrb_tree, offset, attrb_length);
439 break;
441 case GREB_ATTRB_FILTER_LIST_ACK:
442 dissect_greb_filter_list_ack(tvb, attrb_tree, offset, attrb_length);
443 break;
445 case GREB_ATTRB_CIN:
446 proto_tree_add_item(attrb_tree, hf_greb_attr_val_string, tvb, offset, attrb_length,
447 ENC_UTF_8 | ENC_NA);
448 break;
450 case GREB_ATTRB_DT_BRAS_NAME:
451 proto_tree_add_item(attrb_tree, hf_greb_attr_dt_bras_name, tvb, offset, attrb_length,
452 ENC_UTF_8 | ENC_NA);
453 break;
455 case GREB_ATTRB_ERROR:
456 proto_tree_add_item(attrb_tree, hf_greb_attr_error, tvb, offset, attrb_length, ENC_BIG_ENDIAN);
457 break;
459 case GREB_ATTRB_DT_DSL_PROT:
460 proto_tree_add_item(attrb_tree, hf_greb_attr_DSL_prot, tvb, offset, attrb_length, ENC_BIG_ENDIAN);
461 break;
463 default:
464 proto_tree_add_item(attrb_tree, hf_greb_attr_val_uint64, tvb, offset, attrb_length,
465 ENC_BIG_ENDIAN);
466 break;
469 offset += attrb_length;
473 return tvb_captured_length(tvb);
476 void
477 proto_register_greb(void)
479 static hf_register_info hf[] = {
480 { &hf_greb_message_type,
481 { "Message type", "grebonding.type", FT_UINT8, BASE_DEC, VALS(greb_message_types), 0xF0, "", HFILL }
483 { &hf_greb_tunnel_type,
484 { "Tunnel type", "grebonding.tunneltype", FT_UINT8, BASE_DEC, VALS(greb_tunnel_types), 0x0F, "", HFILL }
486 { &hf_greb_attr,
487 { "Attribute", "grebonding.attr", FT_NONE, BASE_NONE, NULL, 0, "", HFILL }
489 { &hf_greb_attr_length,
490 { "Attribute length", "grebonding.attr.length", FT_UINT16, BASE_DEC, NULL, 0, "", HFILL }
492 { &hf_greb_attr_type,
493 { "Attribute type", "grebonding.attr.type", FT_UINT8, BASE_DEC, VALS(greb_attribute_types), 0, "", HFILL }
495 { &hf_greb_attr_val_uint64,
496 { "Attribute value", "grebonding.attr.val.uint64",
497 FT_UINT64, BASE_DEC, NULL, 0, "", HFILL }
499 { &hf_greb_attr_val_time,
500 { "Attribute value", "grebonding.attr.val.time",
501 FT_RELATIVE_TIME, BASE_NONE, NULL, 0, "", HFILL }
503 { &hf_greb_attr_val_string,
504 { "Attribute value", "grebonding.attr.val.string",
505 FT_STRING, BASE_NONE, NULL, 0, "", HFILL }
507 { &hf_greb_attr_val_none,
508 { "Attribute value", "grebonding.attr.val",
509 FT_NONE, BASE_NONE, NULL, 0, "", HFILL }
511 { &hf_greb_attr_val_ipv6,
512 { "Attribute value", "grebonding.attr.val.ipv6",
513 FT_IPv6, BASE_NONE, NULL, 0, NULL, HFILL }
515 { &hf_greb_attr_val_ipv4,
516 { "Attribute value", "grebonding.attr.val.ipv4",
517 FT_IPv4, BASE_NONE, NULL, 0, NULL, HFILL }
519 { &hf_greb_attr_filter_commit,
520 { "Commit", "grebonding.attr.val.filter.commit", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
522 { &hf_greb_attr_filter_ack,
523 { "Ack", "grebonding.attr.val.filter.ack",
524 FT_UINT8, BASE_DEC, VALS(greb_filter_ack_codes), 0, NULL, HFILL }
526 { &hf_greb_attr_DSL_prot,
527 { "DSL Protocol", "grebonding.attr.val.dslproto",
528 FT_UINT8, BASE_DEC, VALS(greb_DT_DSL_prots), 0, NULL, HFILL }
530 { &hf_greb_attr_dt_bras_name,
531 { "Broadband Remote Access Server (BRAS) name", "grebonding.attr.val.bras_name",
532 FT_STRING, BASE_NONE, NULL, 0, "", HFILL }
534 { &hf_greb_attr_filter_packetsum,
535 { "Packet sum", "grebonding.attr.val.filter.packetsum", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
537 { &hf_greb_attr_filter_packetid,
538 { "Packet ID", "grebonding.attr.val.filter.packetid", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
540 { &hf_greb_attr_filter_item_enabled,
541 { "Enabled", "grebonding.attr.val.filter.item.enabled", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
543 { &hf_greb_attr_filter_item_length,
544 { "Length (excl. type and length)", "grebonding.attr.val.filter.item.length",
545 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
547 { &hf_greb_attr_filter_item_type,
548 { "Type", "grebonding.attr.val.filter.item.type",
549 FT_UINT16, BASE_DEC, VALS(greb_filter_types), 0, NULL, HFILL }
551 { &hf_greb_attr_filter_item_desc_val,
552 { "Description", "grebonding.attr.val.filter.item.desc", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
554 { &hf_greb_attr_filter_item_desc_length,
555 { "Description length", "grebonding.attr.val.filter.item.desc.length",
556 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
558 { &hf_greb_attr_filter_item_val,
559 { "Value", "grebonding.attr.val.filter.item.val", FT_STRING, BASE_NONE, NULL, 0, NULL, HFILL }
561 { &hf_greb_attr_error,
562 { "Error message", "grebonding.attr.val.error",
563 FT_UINT32, BASE_DEC, VALS(greb_error_codes), 0, NULL, HFILL }
567 proto_greb = proto_register_protocol("Huawei GRE bonding", "GREbond", "grebonding");
568 proto_register_field_array(proto_greb, hf, array_length(hf));
570 proto_register_subtree_array(ett, array_length(ett));
572 greb_handle = register_dissector("grebonding", dissect_greb, proto_greb);
575 void
576 proto_reg_handoff_greb(void)
578 dissector_add_uint("gre.proto", 0x0101, greb_handle); // used in production at Deutsche Telekom
579 dissector_add_uint("gre.proto", 0xB7EA, greb_handle); // according to RFC
581 // TODO
582 // when capturing on the gre-interfaces itself, "Linux cooked" interfaces
583 //dissector_add_uint("sll.ltype", 0x0101, greb_handle);
584 //dissector_add_uint("sll.ltype", 0xB7EA, greb_handle);
585 //dissector_add_uint("sll.gretype", 0x0101, greb_handle);
586 //dissector_add_uint("sll.gretype", 0xB7EA, greb_handle);