2 * Routines for Huawei's GRE bonding control (RFC8157) dissection
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
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
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.
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
;
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"},
87 {GREB_HELLO
, "Hello"},
88 #define GREB_TUNNEL_TEAR_DOWN 5
89 {GREB_TUNNEL_TEAR_DOWN
, "Tunnel tear down"},
91 {GREB_NOTIFY
, "Notify"},
92 #define GREB_LINK_DETECTION 10
93 {GREB_LINK_DETECTION
, "Link Detection (Telekom specific)"},
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)" },
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)"},
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)"},
240 static const value_string greb_DT_DSL_prots
[] = {
242 {DT_UNDEF
, "Undefined"},
244 {DT_ADSL_B
, "ADSL/ADSL2/ADSL2+ Annex B"},
246 {DT_ADSL_J
, "ADSL2+ Annex J"},
249 #define DT_VDSL_VEC 4
250 {DT_VDSL_VEC
, "VDSL2 Vectoring"},
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)"},
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."},
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
);
307 proto_tree_add_item(attrb_tree
, hf_greb_attr_val_uint64
, tvb
, offset
, attrb_length
, ENC_BIG_ENDIAN
);
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
);
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
);
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;
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
);
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
;
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
);
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
);
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
);
427 case GREB_ATTRB_IPV6_PREFIX2
:
428 case GREB_ATTRB_IPV6_PREFIX
:
429 dissect_greb_ipv6_prefix(pinfo
, tvb
, attrb_tree
, offset
, attrb_length
);
432 case GREB_ATTRB_TIME
:
433 proto_tree_add_item(attrb_tree
, hf_greb_attr_val_time
, tvb
, offset
, attrb_length
,
437 case GREB_ATTRB_FILTER_LIST
:
438 dissect_greb_filter_list(pinfo
, tvb
, attrb_tree
, offset
, attrb_length
);
441 case GREB_ATTRB_FILTER_LIST_ACK
:
442 dissect_greb_filter_list_ack(tvb
, attrb_tree
, offset
, attrb_length
);
446 proto_tree_add_item(attrb_tree
, hf_greb_attr_val_string
, tvb
, offset
, attrb_length
,
450 case GREB_ATTRB_DT_BRAS_NAME
:
451 proto_tree_add_item(attrb_tree
, hf_greb_attr_dt_bras_name
, tvb
, offset
, attrb_length
,
455 case GREB_ATTRB_ERROR
:
456 proto_tree_add_item(attrb_tree
, hf_greb_attr_error
, tvb
, offset
, attrb_length
, ENC_BIG_ENDIAN
);
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
);
464 proto_tree_add_item(attrb_tree
, hf_greb_attr_val_uint64
, tvb
, offset
, attrb_length
,
469 offset
+= attrb_length
;
473 return tvb_captured_length(tvb
);
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
}
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
);
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
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);