2 * Routines for PPP Over Ethernet (PPPoE) packet disassembly (RFC2516)
3 * Up to date with http://www.iana.org/assignments/pppoe-parameters (2008-04-30)
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
14 #include <epan/packet.h>
15 #include <epan/etypes.h>
16 #include <epan/prefs.h>
17 #include <epan/expert.h>
18 #include <epan/ppptypes.h>
19 #include <wiretap/wtap.h>
21 void proto_register_pppoed(void);
22 void proto_reg_handoff_pppoed(void);
23 void proto_register_pppoes(void);
24 void proto_register_pppoe(void);
25 void proto_reg_handoff_pppoes(void);
27 static dissector_handle_t pppoed_handle
;
28 static dissector_handle_t pppoes_handle
;
30 static int proto_pppoed
;
32 /* Common to session and discovery protocols */
33 static int hf_pppoe_version
;
34 static int hf_pppoe_type
;
35 static int hf_pppoe_code
;
36 static int hf_pppoe_session_id
;
37 static int hf_pppoe_payload_length
;
39 /* Discovery protocol fields */
40 static int hf_pppoed_tags
;
41 static int hf_pppoed_tag
;
42 static int hf_pppoed_tag_length
;
43 static int hf_pppoed_tag_length_8
;
44 static int hf_pppoed_tag_unknown_data
;
45 static int hf_pppoed_tag_service_name
;
46 static int hf_pppoed_tag_ac_name
;
47 static int hf_pppoed_tag_host_uniq
;
48 static int hf_pppoed_tag_ac_cookie
;
49 static int hf_pppoed_tag_vendor_id
;
50 static int hf_pppoed_tag_vendor_unspecified
;
51 static int hf_pppoed_tag_vspec_tags
;
52 static int hf_pppoed_tag_vspec_tag
;
53 static int hf_pppoed_tag_vspec_circuit_id
;
54 static int hf_pppoed_tag_vspec_remote_id
;
55 static int hf_pppoed_tag_vspec_act_data_rate_up
;
56 static int hf_pppoed_tag_vspec_act_data_rate_down
;
57 static int hf_pppoed_tag_vspec_min_data_rate_up
;
58 static int hf_pppoed_tag_vspec_min_data_rate_down
;
59 static int hf_pppoed_tag_vspec_attainable_data_rate_up
;
60 static int hf_pppoed_tag_vspec_attainable_data_rate_down
;
61 static int hf_pppoed_tag_vspec_max_data_rate_up
;
62 static int hf_pppoed_tag_vspec_max_data_rate_down
;
63 static int hf_pppoed_tag_vspec_min_data_rate_up_lp
;
64 static int hf_pppoed_tag_vspec_min_data_rate_down_lp
;
65 static int hf_pppoed_tag_vspec_max_int_delay_up
;
66 static int hf_pppoed_tag_vspec_act_int_delay_up
;
67 static int hf_pppoed_tag_vspec_max_int_delay_down
;
68 static int hf_pppoed_tag_vspec_act_int_delay_down
;
69 static int hf_pppoed_tag_vspec_access_loop_encapsulation
;
70 static int hf_pppoed_tag_vspec_access_loop_encap_data_link
;
71 static int hf_pppoed_tag_vspec_access_loop_encap_encap_1
;
72 static int hf_pppoed_tag_vspec_access_loop_encap_encap_2
;
73 static int hf_pppoed_tag_credits
;
74 static int hf_pppoed_tag_credits_fcn
;
75 static int hf_pppoed_tag_credits_bcn
;
76 static int hf_pppoed_tag_metrics
;
77 static int hf_pppoed_tag_metrics_r
;
78 static int hf_pppoed_tag_metrics_rlq
;
79 static int hf_pppoed_tag_metrics_resource
;
80 static int hf_pppoed_tag_metrics_latency
;
81 static int hf_pppoed_tag_metrics_curr_drate
;
82 static int hf_pppoed_tag_metrics_max_drate
;
83 static int hf_pppoed_tag_mdr_units
;
84 static int hf_pppoed_tag_cdr_units
;
85 static int hf_pppoed_tag_seq_num
;
86 static int hf_pppoed_tag_cred_scale
;
87 static int hf_pppoed_tag_relay_session_id
;
88 static int hf_pppoed_tag_hurl
;
89 static int hf_pppoed_tag_motm
;
90 static int hf_pppoed_tag_max_payload
;
91 static int hf_pppoed_tag_ip_route_add
;
92 static int hf_pppoed_tag_service_name_error
;
93 static int hf_pppoed_tag_ac_system_error
;
94 static int hf_pppoed_tag_generic_error
;
96 /* Session protocol fields */
97 static int hf_pppoes_tags
;
98 /* static int hf_pppoes_tag; */
99 /* static int hf_pppoes_tag_credits; */
100 static int hf_pppoes_tag_credits_fcn
;
101 static int hf_pppoes_tag_credits_bcn
;
103 /* Session protocol fields */
105 static int ett_pppoed
;
106 static int ett_pppoed_tags
;
107 static int ett_pppoed_tag_vspec_dslf_access_loop_encaps
;
109 static int proto_pppoes
;
111 static int ett_pppoes
;
112 static int ett_pppoes_tags
;
114 static expert_field ei_pppoe_payload_length
;
115 static expert_field ei_pppoe_tag_length
;
117 /* PPPoE parent fields */
119 static int proto_pppoe
;
120 static int ett_pppoe
;
123 /* Handle for calling for ppp dissector to handle session data */
124 static dissector_handle_t ppp_handle
;
127 /* Preference for showing discovery tag values and lengths */
128 static bool global_pppoe_show_tags_and_lengths
;
131 #define PPPOE_CODE_SESSION 0x00
132 #define PPPOE_CODE_PADO 0x07
133 #define PPPOE_CODE_PADI 0x09
134 #define PPPOE_CODE_PADG 0x0a
135 #define PPPOE_CODE_PADC 0x0b
136 #define PPPOE_CODE_PADQ 0x0c
137 #define PPPOE_CODE_PADR 0x19
138 #define PPPOE_CODE_PADS 0x65
139 #define PPPOE_CODE_PADT 0xa7
140 #define PPPOE_CODE_PADM 0xd3
141 #define PPPOE_CODE_PADN 0xd4
143 #define PPPOE_TAG_EOL 0x0000
144 #define PPPOE_TAG_SVC_NAME 0x0101
145 #define PPPOE_TAG_AC_NAME 0x0102
146 #define PPPOE_TAG_HOST_UNIQ 0x0103
147 #define PPPOE_TAG_AC_COOKIE 0x0104
148 #define PPPOE_TAG_VENDOR 0x0105
149 #define PPPOE_TAG_CREDITS 0x0106
150 #define PPPOE_TAG_METRICS 0x0107
151 #define PPPOE_TAG_SEQ_NUM 0x0108
152 #define PPPOE_TAG_CRED_SCALE 0x0109
153 #define PPPOE_TAG_RELAY_ID 0x0110
154 #define PPPOE_TAG_HURL 0x0111
155 #define PPPOE_TAG_MOTM 0x0112
156 #define PPPOE_TAG_MAX_PAYLD 0x0120
157 #define PPPOE_TAG_IP_RT_ADD 0x0121
158 #define PPPOE_TAG_SVC_ERR 0x0201
159 #define PPPOE_TAG_AC_ERR 0x0202
160 #define PPPOE_TAG_GENERIC_ERR 0x0203
162 #define PPPOE_VENDOR_ID_DSLF 3561
164 #define PPPOE_TAG_VSPEC_DSLF_CIRCUIT_ID 0x01
165 #define PPPOE_TAG_VSPEC_DSLF_REMOTE_ID 0x02
166 #define PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_UP 0x81
167 #define PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_DOWN 0x82
168 #define PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP 0x83
169 #define PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN 0x84
170 #define PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_UP 0x85
171 #define PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_DOWN 0x86
172 #define PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_UP 0x87
173 #define PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_DOWN 0x88
174 #define PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP_LP 0x89
175 #define PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN_LP 0x8a
176 #define PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_UP 0x8b
177 #define PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_UP 0x8c
178 #define PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_DOWN 0x8d
179 #define PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_DOWN 0x8e
180 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAPSULATION 0x90
182 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_DATA_LINK_ATM 0x00
183 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_DATA_LINK_ETH 0x01
185 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_NA 0x00
186 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_UNTAGGED_ETH 0x01
187 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_SINGLE_TAGGED_ETH 0x02
188 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_DOUBLE_TAGGED_ETH 0x03
190 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_NA 0x00
191 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_PPPOA_LLC 0x01
192 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_PPPOA_NULL 0x02
193 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_IPOA_LLC 0x03
194 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_IPOA_NULL 0x04
195 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_LLC_WITH_FCS 0x05
196 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_LLC_WITHOUT_FCS 0x06
197 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_NULL_WITH_FCS 0x07
198 #define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_NULL_WITHOUT_FCS 0x08
200 #define PPPOE_CDR_MASK 0x0006
201 #define PPPOE_MDR_MASK 0x0018
202 #define PPPOE_RCV_ONLY_MASK 0x0001
204 #define PPPOE_SCALE_KBPS 0x00
205 #define PPPOE_SCALE_MBPS 0x01
206 #define PPPOE_SCALE_GBPS 0x02
207 #define PPPOE_SCALE_TBPS 0x03
210 static const value_string code_vals
[] = {
211 {PPPOE_CODE_SESSION
, "Session Data" },
212 {PPPOE_CODE_PADO
, "Active Discovery Offer (PADO)" },
213 {PPPOE_CODE_PADI
, "Active Discovery Initiation (PADI)" },
214 {PPPOE_CODE_PADG
, "Active Discovery Session-Grant (PADG)" },
215 {PPPOE_CODE_PADC
, "Active Discovery Session-Credit Resp.(PADC)" },
216 {PPPOE_CODE_PADQ
, "Active Discovery Quality (PADQ)" },
217 {PPPOE_CODE_PADR
, "Active Discovery Request (PADR)" },
218 {PPPOE_CODE_PADS
, "Active Discovery Session-confirmation (PADS)"},
219 {PPPOE_CODE_PADT
, "Active Discovery Terminate (PADT)" },
220 {PPPOE_CODE_PADM
, "Active Discovery Message (PADM)" },
221 {PPPOE_CODE_PADN
, "Active Discovery Network (PADN)" },
226 static const value_string tag_vals
[] = {
227 {PPPOE_TAG_EOL
, "End-Of-List" },
228 {PPPOE_TAG_SVC_NAME
, "Service-Name" },
229 {PPPOE_TAG_AC_NAME
, "AC-Name" },
230 {PPPOE_TAG_HOST_UNIQ
, "Host-Uniq" },
231 {PPPOE_TAG_AC_COOKIE
, "AC-Cookie" },
232 {PPPOE_TAG_VENDOR
, "Vendor-Specific" },
233 {PPPOE_TAG_CREDITS
, "Credits" },
234 {PPPOE_TAG_METRICS
, "Metrics" },
235 {PPPOE_TAG_SEQ_NUM
, "Sequence Number" },
236 {PPPOE_TAG_CRED_SCALE
, "Credit Scale Factor"},
237 {PPPOE_TAG_RELAY_ID
, "Relay-Session-Id" },
238 {PPPOE_TAG_HURL
, "HURL" },
239 {PPPOE_TAG_MOTM
, "MOTM" },
240 {PPPOE_TAG_MAX_PAYLD
, "PPP-Max-Payload" },
241 {PPPOE_TAG_IP_RT_ADD
, "IP Route Add" },
242 {PPPOE_TAG_SVC_ERR
, "Service-Name-Error"},
243 {PPPOE_TAG_AC_ERR
, "AC-System-Error" },
244 {PPPOE_TAG_GENERIC_ERR
,"Generic-Error" },
248 static const value_string vspec_tag_vals
[] = {
249 {PPPOE_TAG_VSPEC_DSLF_CIRCUIT_ID
, "Circuit-ID" },
250 {PPPOE_TAG_VSPEC_DSLF_REMOTE_ID
, "Remote-ID" },
251 {PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_UP
, "Actual-Data-Rate-Up" },
252 {PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_DOWN
, "Actual-Data-Rate-Down" },
253 {PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP
, "Min-Data-Rate-Up" },
254 {PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN
, "Min-Data-Rate-Down" },
255 {PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_UP
, "Attainable-Data-Rate-Up" },
256 {PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_DOWN
, "Attainable-Data-Rate-Down" },
257 {PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_UP
, "Max-Data-Rate-Up" },
258 {PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_DOWN
, "Max-Data-Rate-Down" },
259 {PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP_LP
, "Min-Data-Rate-Up-Low-Power" },
260 {PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN_LP
, "Min-Data-Rate-Down-Low-Power" },
261 {PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_UP
, "Max-Interleaving-Delay-Up" },
262 {PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_UP
, "Actual-Interleaving-Delay-Up" },
263 {PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_DOWN
, "Max-Interleaving-Delay-Down" },
264 {PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_DOWN
, "Actual-Interleaving-Delay-Down"},
265 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAPSULATION
, "Access-Loop-Encapsulation" },
269 static const value_string vspec_tag_dslf_access_loop_encap_data_link_vals
[] = {
270 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_DATA_LINK_ATM
, "ATM AAL5"},
271 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_DATA_LINK_ETH
, "Ethernet"},
275 static const value_string vspec_tag_dslf_access_loop_encap_encap_1_vals
[] = {
276 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_NA
, "NA" },
277 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_UNTAGGED_ETH
, "Untagged Ethernet" },
278 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_SINGLE_TAGGED_ETH
, "Single-tagged Ethernet"},
279 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_DOUBLE_TAGGED_ETH
, "Double-tagged Ethernet"},
283 static const value_string vspec_tag_dslf_access_loop_encap_encap_2_vals
[] = {
284 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_NA
, "NA" },
285 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_PPPOA_LLC
, "PPPoA LLC" },
286 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_PPPOA_NULL
, "PPPoA Null" },
287 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_IPOA_LLC
, "IPoA LLC" },
288 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_IPOA_NULL
, "IPoA Null" },
289 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_LLC_WITH_FCS
, "Ethernet over AAL5 LLC w FCS" },
290 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_LLC_WITHOUT_FCS
, "Ethernet over AAL5 LLC w/o FCS" },
291 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_NULL_WITH_FCS
, "Ethernet over AAL5 Null w FCS" },
292 {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_NULL_WITHOUT_FCS
,"Ethernet over AAL5 Null w/o FCS"},
296 static const value_string datarate_scale_vals
[] = {
297 {PPPOE_SCALE_KBPS
, "kilobits per second"},
298 {PPPOE_SCALE_MBPS
, "megabits per second"},
299 {PPPOE_SCALE_GBPS
, "gigabits per second"},
300 {PPPOE_SCALE_TBPS
, "terabits per second"},
305 #define CASE_VSPEC_DSLF_TAG_UINT(tag_name, relation, length, hf_var) case tag_name: \
306 if (!(poe_tag_length relation length)) { \
307 expert_add_info_format(pinfo, pppoe_tree, &ei_pppoe_tag_length, \
308 "%s: Wrong length: %u (expected %s %d)", \
309 val_to_str_const(poe_tag, vspec_tag_vals, "Unknown"), poe_tag_length, #relation, length); \
311 proto_tree_add_item(pppoe_tree, hf_var, tvb, \
312 tagstart+2, poe_tag_length, ENC_BIG_ENDIAN); \
316 #define CASE_VSPEC_DSLF_TAG_STRING(tag_name, relation, length, hf_var) case tag_name: \
317 if (!(poe_tag_length relation length)) { \
318 expert_add_info_format(pinfo, pppoe_tree, &ei_pppoe_tag_length, \
319 "%s: Wrong length: %u (expected %s %d)", \
320 val_to_str_const(poe_tag, vspec_tag_vals, "Unknown"), poe_tag_length, #relation, length); \
322 proto_tree_add_item(pppoe_tree, hf_var, tvb, \
323 tagstart+2, poe_tag_length, ENC_ASCII|ENC_NA); \
327 /* Dissect Vendor-Specific Tags introduced by the DSLF */
329 dissect_pppoe_subtags_dslf(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, int offset
, proto_tree
*tree
,
333 uint8_t poe_tag_length
;
336 proto_tree
*pppoe_tree
, *ti
, *encaps_tree
;
338 /* Start Decoding Here. */
341 /* Create tags subtree */
342 ti
= proto_tree_add_item(tree
, hf_pppoed_tag_vspec_tags
, tvb
, offset
, payload_length
, ENC_NA
);
343 pppoe_tree
= proto_item_add_subtree(ti
, ett_pppoed_tags
);
347 /* Loop until all data seen or End-Of-List tag found */
348 while (tagstart
<= offset
+ payload_length
-2)
350 poe_tag
= tvb_get_uint8(tvb
, tagstart
);
351 poe_tag_length
= tvb_get_uint8(tvb
, tagstart
+ 1);
353 /* Tag value and data length */
354 if (global_pppoe_show_tags_and_lengths
)
356 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_vspec_tag
, tvb
, tagstart
, 1, ENC_BIG_ENDIAN
);
357 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_length_8
, tvb
, tagstart
+1, 1, ENC_BIG_ENDIAN
);
363 CASE_VSPEC_DSLF_TAG_STRING(PPPOE_TAG_VSPEC_DSLF_CIRCUIT_ID
, <=, 63,
364 hf_pppoed_tag_vspec_circuit_id
)
365 CASE_VSPEC_DSLF_TAG_STRING(PPPOE_TAG_VSPEC_DSLF_REMOTE_ID
, <=, 63,
366 hf_pppoed_tag_vspec_remote_id
)
367 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_UP
, ==, 4,
368 hf_pppoed_tag_vspec_act_data_rate_up
)
369 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_DOWN
, ==, 4,
370 hf_pppoed_tag_vspec_act_data_rate_down
)
371 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP
, ==, 4,
372 hf_pppoed_tag_vspec_min_data_rate_up
)
373 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN
, ==, 4,
374 hf_pppoed_tag_vspec_min_data_rate_down
)
375 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_UP
, ==, 4,
376 hf_pppoed_tag_vspec_attainable_data_rate_up
)
377 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_DOWN
, ==, 4,
378 hf_pppoed_tag_vspec_attainable_data_rate_down
)
379 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_UP
, ==, 4,
380 hf_pppoed_tag_vspec_max_data_rate_up
)
381 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_DOWN
, ==, 4,
382 hf_pppoed_tag_vspec_max_data_rate_down
)
383 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP_LP
, ==, 4,
384 hf_pppoed_tag_vspec_min_data_rate_up_lp
)
385 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN_LP
, ==, 4,
386 hf_pppoed_tag_vspec_min_data_rate_down_lp
)
387 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_UP
, ==, 4,
388 hf_pppoed_tag_vspec_max_int_delay_up
)
389 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_UP
, ==, 4,
390 hf_pppoed_tag_vspec_act_int_delay_up
)
391 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_DOWN
, ==, 4,
392 hf_pppoed_tag_vspec_max_int_delay_down
)
393 CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_DOWN
, ==, 4,
394 hf_pppoed_tag_vspec_act_int_delay_down
)
395 case PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAPSULATION
:
396 ti
= proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_vspec_access_loop_encapsulation
, tvb
,
397 tagstart
+2, 3, ENC_NA
);
398 if (poe_tag_length
!= 3) {
399 expert_add_info_format(pinfo
, ti
, &ei_pppoe_tag_length
, "%s: Wrong length: %u (expected 3)", val_to_str_const(poe_tag
, vspec_tag_vals
, "Unknown"), poe_tag_length
);
401 encaps_tree
= proto_item_add_subtree(ti
, ett_pppoed_tag_vspec_dslf_access_loop_encaps
);
402 proto_tree_add_item(encaps_tree
, hf_pppoed_tag_vspec_access_loop_encap_data_link
,
403 tvb
, tagstart
+2, 1, ENC_BIG_ENDIAN
);
404 proto_tree_add_item(encaps_tree
, hf_pppoed_tag_vspec_access_loop_encap_encap_1
,
405 tvb
, tagstart
+3, 1, ENC_BIG_ENDIAN
);
406 proto_tree_add_item(encaps_tree
, hf_pppoed_tag_vspec_access_loop_encap_encap_2
,
407 tvb
, tagstart
+4, 1, ENC_BIG_ENDIAN
);
411 if (poe_tag_length
> 0 )
413 /* Presumably unknown tag;
414 show tag value if we didn't do it above */
415 if (!global_pppoe_show_tags_and_lengths
)
417 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag
, tvb
, tagstart
, 1, ENC_BIG_ENDIAN
);
418 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_length_8
, tvb
, tagstart
+1, 1, ENC_BIG_ENDIAN
);
420 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_unknown_data
, tvb
,
421 tagstart
+2, poe_tag_length
, ENC_NA
);
425 tagstart
+= (2 + poe_tag_length
);
431 /* Dissect discovery protocol tags */
433 dissect_pppoe_tags(tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
, proto_tree
*tree
,
437 uint16_t poe_tag_length
;
439 uint16_t poe_rsv
= 0;
441 proto_tree
*pppoe_tree
;
443 proto_item
*pppoe_tree_tag_length_item
= NULL
;
445 /* Start Decoding Here. */
448 /* Create tags subtree */
449 ti
= proto_tree_add_item(tree
, hf_pppoed_tags
, tvb
, offset
, payload_length
-6, ENC_NA
);
450 pppoe_tree
= proto_item_add_subtree(ti
, ett_pppoed_tags
);
454 /* Loop until all data seen or End-Of-List tag found */
455 while (tagstart
<= payload_length
-2)
457 poe_tag
= tvb_get_ntohs(tvb
, tagstart
);
458 poe_tag_length
= tvb_get_ntohs(tvb
, tagstart
+ 2);
460 /* Tag value and data length */
461 if (global_pppoe_show_tags_and_lengths
)
463 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag
, tvb
, tagstart
, 2, ENC_BIG_ENDIAN
);
464 pppoe_tree_tag_length_item
=
465 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_length
, tvb
, tagstart
+2, 2, ENC_BIG_ENDIAN
);
471 case PPPOE_TAG_SVC_NAME
:
472 if (poe_tag_length
> 0)
474 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_service_name
, tvb
,
475 tagstart
+4, poe_tag_length
, ENC_ASCII
);
478 case PPPOE_TAG_AC_NAME
:
481 proto_tree_add_item_ret_string(pppoe_tree
, hf_pppoed_tag_ac_name
, tvb
,
482 tagstart
+4, poe_tag_length
, ENC_ASCII
|ENC_NA
, pinfo
->pool
, &str
);
483 /* Show AC-Name in info column */
484 col_append_fstr(pinfo
->cinfo
, COL_INFO
, " AC-Name='%s'", str
);
487 case PPPOE_TAG_HOST_UNIQ
:
488 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_host_uniq
, tvb
,
489 tagstart
+4, poe_tag_length
, ENC_NA
);
491 case PPPOE_TAG_AC_COOKIE
:
492 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_ac_cookie
, tvb
,
493 tagstart
+4, poe_tag_length
, ENC_NA
);
495 case PPPOE_TAG_VENDOR
:
496 if (poe_tag_length
>= 4)
498 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_vendor_id
, tvb
,
499 tagstart
+4, 4, ENC_BIG_ENDIAN
);
501 if (poe_tag_length
> 4)
503 uint32_t vendor_id
= tvb_get_ntohl(tvb
, tagstart
+4);
506 case PPPOE_VENDOR_ID_DSLF
:
507 dissect_pppoe_subtags_dslf(tvb
,pinfo
,tagstart
+4+4,pppoe_tree
,poe_tag_length
-4);
510 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_vendor_unspecified
, tvb
,
511 tagstart
+4+4, poe_tag_length
-4, ENC_NA
);
516 case PPPOE_TAG_CREDITS
:
517 if (poe_tag_length
== 4)
519 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_credits_fcn
, tvb
,
520 tagstart
+4, 2, ENC_BIG_ENDIAN
);
521 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_credits_bcn
, tvb
,
522 tagstart
+6, 2, ENC_BIG_ENDIAN
);
524 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_credits
, tvb
,
525 tagstart
+4, poe_tag_length
, ENC_NA
);
528 case PPPOE_TAG_METRICS
:
529 if (poe_tag_length
== 10)
531 poe_rsv
= tvb_get_ntohs(tvb
, tagstart
+4);
533 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_mdr_units
, tvb
,
534 tagstart
+4, 2, ENC_BIG_ENDIAN
);
535 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_cdr_units
, tvb
,
536 tagstart
+4, 2, ENC_BIG_ENDIAN
);
537 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_metrics_r
, tvb
,
538 tagstart
+4, 2, ENC_BIG_ENDIAN
);
539 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_metrics_rlq
, tvb
,
540 tagstart
+6, 1, ENC_BIG_ENDIAN
);
541 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_metrics_resource
, tvb
,
542 tagstart
+7, 1, ENC_BIG_ENDIAN
);
543 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_metrics_latency
, tvb
,
544 tagstart
+8, 2, ENC_BIG_ENDIAN
);
547 ti
= proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_metrics_curr_drate
, tvb
,
548 tagstart
+10, 2, ENC_BIG_ENDIAN
);
550 switch ((poe_rsv
& PPPOE_CDR_MASK
) >> 1)
552 case (PPPOE_SCALE_KBPS
):
553 proto_item_append_text(ti
, " kbps");
555 case (PPPOE_SCALE_MBPS
):
556 proto_item_append_text(ti
, " mbps");
558 case (PPPOE_SCALE_GBPS
):
559 proto_item_append_text(ti
, " gbps");
561 case (PPPOE_SCALE_TBPS
):
562 proto_item_append_text(ti
, " tbps");
567 ti
= proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_metrics_max_drate
, tvb
,
568 tagstart
+12, 2, ENC_BIG_ENDIAN
);
570 switch ((poe_rsv
& PPPOE_MDR_MASK
) >> 3)
572 case (PPPOE_SCALE_KBPS
):
573 proto_item_append_text(ti
, " kbps");
575 case (PPPOE_SCALE_MBPS
):
576 proto_item_append_text(ti
, " mbps");
578 case (PPPOE_SCALE_GBPS
):
579 proto_item_append_text(ti
, " gbps");
581 case (PPPOE_SCALE_TBPS
):
582 proto_item_append_text(ti
, " tbps");
587 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_metrics
, tvb
,
588 tagstart
+4, poe_tag_length
, ENC_NA
);
591 case PPPOE_TAG_SEQ_NUM
:
592 if (poe_tag_length
== 2) {
593 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_seq_num
, tvb
,
594 tagstart
+4, poe_tag_length
, ENC_BIG_ENDIAN
);
596 if (global_pppoe_show_tags_and_lengths
) {
597 proto_item_append_text(pppoe_tree_tag_length_item
, " [Wrong: should be 2]");
600 proto_tree_add_expert_format(pppoe_tree
, pinfo
, &ei_pppoe_tag_length
, tvb
, tagstart
+4, poe_tag_length
,
601 "Sequence Number tag: Wrong length: %u (expected 2)", poe_tag_length
);
604 case PPPOE_TAG_CRED_SCALE
:
605 if (poe_tag_length
== 2) {
606 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_cred_scale
, tvb
,
607 tagstart
+4, poe_tag_length
, ENC_BIG_ENDIAN
);
609 if (global_pppoe_show_tags_and_lengths
) {
610 proto_item_append_text(pppoe_tree_tag_length_item
, " [Wrong: should be 2]");
612 proto_tree_add_expert_format(pppoe_tree
, pinfo
, &ei_pppoe_tag_length
, tvb
, tagstart
+4, poe_tag_length
,
613 "Credit Scale Factor tag: Wrong length: %u (expected 2)", poe_tag_length
);
616 case PPPOE_TAG_RELAY_ID
:
617 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_relay_session_id
, tvb
,
618 tagstart
+4, poe_tag_length
, ENC_NA
);
621 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_hurl
, tvb
,
622 tagstart
+4, poe_tag_length
, ENC_NA
);
625 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_motm
, tvb
,
626 tagstart
+4, poe_tag_length
, ENC_NA
);
628 case PPPOE_TAG_MAX_PAYLD
:
629 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_max_payload
, tvb
,
630 tagstart
+4, poe_tag_length
, ENC_NA
);
632 case PPPOE_TAG_IP_RT_ADD
:
633 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_ip_route_add
, tvb
,
634 tagstart
+4, poe_tag_length
, ENC_NA
);
637 /* These error tag values should be interpreted as a utf-8 unterminated
639 case PPPOE_TAG_SVC_ERR
:
640 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_service_name_error
, tvb
,
641 tagstart
+4, poe_tag_length
, ENC_ASCII
);
643 case PPPOE_TAG_AC_ERR
:
644 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_ac_system_error
, tvb
,
645 tagstart
+4, poe_tag_length
, ENC_ASCII
);
647 case PPPOE_TAG_GENERIC_ERR
:
648 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_generic_error
, tvb
,
649 tagstart
+4, poe_tag_length
, ENC_ASCII
);
652 /* Get out if see end-of-list tag */
657 if (poe_tag_length
> 0 )
659 /* Presumably unknown tag;
660 show tag value if we didn't
662 if (!global_pppoe_show_tags_and_lengths
)
664 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag
, tvb
, tagstart
, 2, ENC_BIG_ENDIAN
);
665 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_length
, tvb
, tagstart
+2, 2, ENC_BIG_ENDIAN
);
667 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_unknown_data
, tvb
,
668 tagstart
+2, poe_tag_length
, ENC_NA
);
672 tagstart
+= (4 + poe_tag_length
);
678 /* Discovery protocol, i.e. PPP session not yet established */
679 static int dissect_pppoed(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
682 uint16_t reported_payload_length
;
684 proto_tree
*pppoe_tree
= NULL
;
687 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "PPPoED");
688 col_clear(pinfo
->cinfo
, COL_INFO
);
690 /* Start Decoding Here. */
691 pppoe_code
= tvb_get_uint8(tvb
, 1);
693 col_append_str(pinfo
->cinfo
, COL_INFO
, val_to_str_const(pppoe_code
, code_vals
, "Unknown"));
695 /* Read length of payload */
696 reported_payload_length
= tvb_get_ntohs(tvb
, 4);
700 ti
= proto_tree_add_item(tree
, proto_pppoed
, tvb
, 0, reported_payload_length
+6, ENC_NA
);
701 pppoe_tree
= proto_item_add_subtree(ti
, ett_pppoed
);
703 /* Dissect fixed fields */
704 proto_tree_add_item(pppoe_tree
, hf_pppoe_version
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
705 proto_tree_add_item(pppoe_tree
, hf_pppoe_type
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
706 proto_tree_add_item(pppoe_tree
, hf_pppoe_code
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
707 proto_tree_add_item(pppoe_tree
, hf_pppoe_session_id
, tvb
, 2, 2, ENC_BIG_ENDIAN
);
708 proto_tree_add_item(pppoe_tree
, hf_pppoe_payload_length
, tvb
, 4, 2, ENC_BIG_ENDIAN
);
711 /* Now dissect any tags */
712 if (reported_payload_length
> 0)
714 dissect_pppoe_tags(tvb
, pinfo
, 6, pppoe_tree
, 6+reported_payload_length
);
717 return tvb_captured_length(tvb
);
720 void proto_register_pppoed(void)
722 static hf_register_info hf
[] =
724 /* Discovery tag fields */
726 { "PPPoE Tags", "pppoed.tags", FT_NONE
, BASE_NONE
,
727 NULL
, 0x0, NULL
, HFILL
731 { "Tag", "pppoed.tag", FT_UINT16
, BASE_HEX
,
732 VALS(tag_vals
), 0x0, NULL
, HFILL
735 { &hf_pppoed_tag_length
,
736 { "Tag Length", "pppoed.tag_length", FT_UINT16
, BASE_DEC
,
737 NULL
, 0x0, NULL
, HFILL
740 { &hf_pppoed_tag_length_8
,
741 { "Tag Length", "pppoed.tag_length_8", FT_UINT8
, BASE_DEC
,
742 NULL
, 0x0, NULL
, HFILL
745 { &hf_pppoed_tag_unknown_data
,
746 { "Unknown Data", "pppoed.tag.unknown_data", FT_BYTES
, BASE_NONE
,
747 NULL
, 0x0, NULL
, HFILL
750 { &hf_pppoed_tag_service_name
,
751 { "Service-Name", "pppoed.tags.service_name", FT_STRING
, BASE_NONE
,
752 NULL
, 0x0, NULL
, HFILL
755 { &hf_pppoed_tag_ac_name
,
756 { "AC-Name", "pppoed.tags.ac_name", FT_STRING
, BASE_NONE
,
757 NULL
, 0x0, NULL
, HFILL
760 { &hf_pppoed_tag_host_uniq
,
761 { "Host-Uniq", "pppoed.tags.host_uniq", FT_BYTES
, BASE_NONE
,
762 NULL
, 0x0, NULL
, HFILL
765 { &hf_pppoed_tag_ac_cookie
,
766 { "AC-Cookie", "pppoed.tags.ac_cookie", FT_BYTES
, BASE_NONE
,
767 NULL
, 0x0, NULL
, HFILL
770 { &hf_pppoed_tag_vendor_id
,
771 { "Vendor id", "pppoed.tags.vendor_id", FT_UINT32
, BASE_DEC
,
772 NULL
, 0x0, NULL
, HFILL
775 { &hf_pppoed_tag_vendor_unspecified
,
776 { "Vendor unspecified", "pppoed.tags.vendor_unspecified", FT_BYTES
, BASE_NONE
,
777 NULL
, 0x0, NULL
, HFILL
780 { &hf_pppoed_tag_vspec_tags
,
781 { "Vendor Specific PPPoE Tags", "pppoed.tags.vendorspecific.tags", FT_NONE
, BASE_NONE
,
782 NULL
, 0x0, NULL
, HFILL
785 { &hf_pppoed_tag_vspec_tag
,
786 { "Tag", "pppoed.tags.vendorspecific.tag", FT_UINT8
, BASE_HEX
,
787 VALS(vspec_tag_vals
), 0x0, NULL
, HFILL
790 { &hf_pppoed_tag_vspec_circuit_id
,
791 { "Circuit ID", "pppoed.tags.circuit_id", FT_STRING
, BASE_NONE
,
792 NULL
, 0x0, NULL
, HFILL
795 { &hf_pppoed_tag_vspec_remote_id
,
796 { "Remote ID", "pppoed.tags.remote_id", FT_STRING
, BASE_NONE
,
797 NULL
, 0x0, NULL
, HFILL
800 { &hf_pppoed_tag_vspec_act_data_rate_up
,
801 { "Actual Data Rate Upstream", "pppoed.tags.act_data_rate_up", FT_UINT32
, BASE_DEC
,
802 NULL
, 0x0, NULL
, HFILL
805 { &hf_pppoed_tag_vspec_act_data_rate_down
,
806 { "Actual Data Rate Downstream", "pppoed.tags.act_data_rate_down", FT_UINT32
, BASE_DEC
,
807 NULL
, 0x0, NULL
, HFILL
810 { &hf_pppoed_tag_vspec_min_data_rate_up
,
811 { "Minimum Data Rate Upstream", "pppoed.tags.min_data_rate_up", FT_UINT32
, BASE_DEC
,
812 NULL
, 0x0, NULL
, HFILL
815 { &hf_pppoed_tag_vspec_min_data_rate_down
,
816 { "Minimum Data Rate Downstream", "pppoed.tags.min_data_rate_down", FT_UINT32
, BASE_DEC
,
817 NULL
, 0x0, NULL
, HFILL
820 { &hf_pppoed_tag_vspec_attainable_data_rate_up
,
821 { "Attainable DataRate Upstream", "pppoed.tags.attainable_data_rate_up", FT_UINT32
, BASE_DEC
,
822 NULL
, 0x0, NULL
, HFILL
825 { &hf_pppoed_tag_vspec_attainable_data_rate_down
,
826 { "Attainable DataRate Downstream", "pppoed.tags.attainable_data_rate_down", FT_UINT32
, BASE_DEC
,
827 NULL
, 0x0, NULL
, HFILL
830 { &hf_pppoed_tag_vspec_max_data_rate_up
,
831 { "Maximum Data Rate Upstream", "pppoed.tags.max_data_rate_up", FT_UINT32
, BASE_DEC
,
832 NULL
, 0x0, NULL
, HFILL
835 { &hf_pppoed_tag_vspec_max_data_rate_down
,
836 { "Maximum Data Rate Downstream", "pppoed.tags.max_data_rate_down", FT_UINT32
, BASE_DEC
,
837 NULL
, 0x0, NULL
, HFILL
840 { &hf_pppoed_tag_vspec_min_data_rate_up_lp
,
841 { "Min DataRate Upstream in low power state", "pppoed.tags.min_data_rate_up_lp", FT_UINT32
, BASE_DEC
,
842 NULL
, 0x0, NULL
, HFILL
845 { &hf_pppoed_tag_vspec_min_data_rate_down_lp
,
846 { "Minimum Data Rate Downstream in low power state", "pppoed.tags.min_data_rate_down_lp", FT_UINT32
, BASE_DEC
,
847 NULL
, 0x0, NULL
, HFILL
850 { &hf_pppoed_tag_vspec_max_int_delay_up
,
851 { "Max Interleaving Delay Upstream", "pppoed.tags.max_int_delay_up", FT_UINT32
, BASE_DEC
,
852 NULL
, 0x0, NULL
, HFILL
855 { &hf_pppoed_tag_vspec_act_int_delay_up
,
856 { "Actual Interleaving Delay Upstream", "pppoed.tags.act_int_delay_up", FT_UINT32
, BASE_DEC
,
857 NULL
, 0x0, NULL
, HFILL
860 { &hf_pppoed_tag_vspec_max_int_delay_down
,
861 { "Maximum Interleaving Delay Downstream", "pppoed.tags.max_int_delay_down", FT_UINT32
, BASE_DEC
,
862 NULL
, 0x0, NULL
, HFILL
865 { &hf_pppoed_tag_vspec_act_int_delay_down
,
866 { "Actual Interleaving Delay Downstream", "pppoed.tags.act_int_delay_down", FT_UINT32
, BASE_DEC
,
867 NULL
, 0x0, NULL
, HFILL
870 { &hf_pppoed_tag_vspec_access_loop_encapsulation
,
871 { "Access-Loop-Encapsulation", "pppoed.tags.access_loop_encap", FT_NONE
, BASE_NONE
,
872 NULL
, 0x0, NULL
, HFILL
875 { &hf_pppoed_tag_vspec_access_loop_encap_data_link
,
876 { "Data link", "pppoed.tags.access_loop_encap.data_link", FT_UINT8
, BASE_HEX
,
877 VALS(vspec_tag_dslf_access_loop_encap_data_link_vals
), 0x0, NULL
, HFILL
880 { &hf_pppoed_tag_vspec_access_loop_encap_encap_1
,
881 { "Encaps 1", "pppoed.tags.access_loop_encap.encap_1", FT_UINT8
, BASE_HEX
,
882 VALS(vspec_tag_dslf_access_loop_encap_encap_1_vals
), 0x0, NULL
, HFILL
885 { &hf_pppoed_tag_vspec_access_loop_encap_encap_2
,
886 { "Encaps 2", "pppoed.tags.access_loop_encap.encap_2", FT_UINT8
, BASE_HEX
,
887 VALS(vspec_tag_dslf_access_loop_encap_encap_2_vals
), 0x0, NULL
, HFILL
890 { &hf_pppoed_tag_credits
,
891 { "Credits", "pppoed.tags.credits", FT_BYTES
, BASE_NONE
,
892 NULL
, 0x0, NULL
, HFILL
895 { &hf_pppoed_tag_credits_fcn
,
896 { "FCN", "pppoed.tags.credits.fcn", FT_UINT16
, BASE_DEC
,
897 NULL
, 0x0, NULL
, HFILL
900 { &hf_pppoed_tag_credits_bcn
,
901 { "BCN", "pppoed.tags.credits.bcn", FT_UINT16
, BASE_DEC
,
902 NULL
, 0x0, NULL
, HFILL
905 { &hf_pppoed_tag_metrics
,
906 { "Metrics", "pppoed.tags.metrics", FT_BYTES
, BASE_NONE
,
907 NULL
, 0x0, NULL
, HFILL
910 { &hf_pppoed_tag_metrics_r
,
911 { "Receive Only", "pppoed.tags.metrics.r", FT_BOOLEAN
, 16,
912 NULL
, PPPOE_RCV_ONLY_MASK
, NULL
, HFILL
915 { &hf_pppoed_tag_mdr_units
,
916 { "MDR Units", "pppoed.tags.metrics.mdr_units", FT_UINT16
, BASE_HEX
,
917 VALS(datarate_scale_vals
), PPPOE_MDR_MASK
, NULL
, HFILL
920 { &hf_pppoed_tag_cdr_units
,
921 { "CDR Units", "pppoed.tags.metrics.cdr_units", FT_UINT16
, BASE_HEX
,
922 VALS(datarate_scale_vals
), PPPOE_CDR_MASK
, NULL
, HFILL
925 { &hf_pppoed_tag_metrics_rlq
,
926 { "Relative Link Quality", "pppoed.tags.metrics.rlq", FT_UINT8
, BASE_DEC
,
927 NULL
, 0x0, NULL
, HFILL
930 { &hf_pppoed_tag_metrics_resource
,
931 { "Resource", "pppoed.tags.metrics.resource", FT_UINT8
, BASE_DEC
,
932 NULL
, 0x0, NULL
, HFILL
935 { &hf_pppoed_tag_metrics_latency
,
936 { "Latency", "pppoed.tags.metrics.latency", FT_UINT16
, BASE_DEC
,
937 NULL
, 0x0, NULL
, HFILL
940 { &hf_pppoed_tag_metrics_curr_drate
,
941 { "Curr. datarate", "pppoed.tags.metrics.curr_drate", FT_UINT16
, BASE_DEC
,
942 NULL
, 0x0, NULL
, HFILL
945 { &hf_pppoed_tag_metrics_max_drate
,
946 { "Max. datarate", "pppoed.tags.metrics.max_drate", FT_UINT16
, BASE_DEC
,
947 NULL
, 0x0, NULL
, HFILL
950 { &hf_pppoed_tag_seq_num
,
951 { "Sequence Number", "pppoed.tags.seq_num", FT_UINT16
, BASE_HEX
,
952 NULL
, 0x0, NULL
, HFILL
955 { &hf_pppoed_tag_cred_scale
,
956 { "Credit Scale Factor", "pppoed.tags.credit_scale", FT_UINT16
, BASE_DEC
,
957 NULL
, 0x0, NULL
, HFILL
960 { &hf_pppoed_tag_relay_session_id
,
961 { "Relay-Session-Id", "pppoed.tags.relay_session_id", FT_BYTES
, BASE_NONE
,
962 NULL
, 0x0, NULL
, HFILL
965 { &hf_pppoed_tag_hurl
,
966 { "HURL", "pppoed.tags.hurl", FT_BYTES
, BASE_NONE
,
967 NULL
, 0x0, NULL
, HFILL
970 { &hf_pppoed_tag_motm
,
971 { "MOTM", "pppoed.tags.motm", FT_BYTES
, BASE_NONE
,
972 NULL
, 0x0, NULL
, HFILL
975 { &hf_pppoed_tag_max_payload
,
976 { "PPP-Max-Payload", "pppoed.tags.max_payload", FT_BYTES
, BASE_NONE
,
977 NULL
, 0x0, NULL
, HFILL
980 { &hf_pppoed_tag_ip_route_add
,
981 { "IP Route Add", "pppoed.tags.ip_route_add", FT_BYTES
, BASE_NONE
,
982 NULL
, 0x0, NULL
, HFILL
985 { &hf_pppoed_tag_service_name_error
,
986 { "Service-Name-Error", "pppoed.tags.service_name_error", FT_STRING
, BASE_NONE
,
987 NULL
, 0x0, NULL
, HFILL
990 { &hf_pppoed_tag_ac_system_error
,
991 { "AC-System-Error", "pppoed.tags.ac_system_error", FT_STRING
, BASE_NONE
,
992 NULL
, 0x0, NULL
, HFILL
995 { &hf_pppoed_tag_generic_error
,
996 { "Generic-Error", "pppoed.tags.generic_error", FT_STRING
, BASE_NONE
,
997 NULL
, 0x0, NULL
, HFILL
1002 static int *ett
[] = {
1005 &ett_pppoed_tag_vspec_dslf_access_loop_encaps
1008 module_t
*pppoed_module
;
1010 /* Register protocol and fields */
1011 proto_pppoed
= proto_register_protocol("PPP-over-Ethernet Discovery",
1012 "PPPoED", "pppoed");
1013 proto_register_subtree_array(ett
, array_length(ett
));
1014 proto_register_field_array(proto_pppoed
, hf
, array_length(hf
));
1016 /* Register dissector handle */
1017 pppoed_handle
= register_dissector("pppoed", dissect_pppoed
, proto_pppoed
);
1019 /* Preference setting */
1020 pppoed_module
= prefs_register_protocol(proto_pppoed
, NULL
);
1021 prefs_register_bool_preference(pppoed_module
, "show_tags_and_lengths",
1022 "Show tag values and lengths",
1023 "Show values of tags and lengths of data fields",
1024 &global_pppoe_show_tags_and_lengths
);
1027 void proto_reg_handoff_pppoed(void)
1029 dissector_add_uint("ethertype", ETHERTYPE_PPPOED
, pppoed_handle
);
1033 /* Session protocol, i.e. PPP session established */
1034 static int dissect_pppoes(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1037 uint16_t reported_payload_length
;
1038 uint16_t poe_tag_length
;
1039 int actual_payload_length
;
1040 int length
, reported_length
;
1041 int credit_offset
= 0, tagstart
= 0;
1044 proto_tree
*pppoe_tree
;
1045 proto_item
*ti
= NULL
;
1048 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "PPPoES");
1049 col_clear(pinfo
->cinfo
, COL_INFO
);
1051 /* Start Decoding Here. */
1052 pppoe_code
= tvb_get_uint8(tvb
, 1);
1054 col_set_str(pinfo
->cinfo
, COL_INFO
,
1055 val_to_str_const(pppoe_code
, code_vals
, "Unknown"));
1057 reported_payload_length
= tvb_get_ntohs(tvb
, 4);
1058 actual_payload_length
= tvb_reported_length_remaining(tvb
, 6);
1062 ti
= proto_tree_add_item(tree
, proto_pppoes
, tvb
, 0, 6, ENC_NA
);
1063 pppoe_tree
= proto_item_add_subtree(ti
, ett_pppoe
);
1065 proto_tree_add_item(pppoe_tree
, hf_pppoe_version
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1066 proto_tree_add_item(pppoe_tree
, hf_pppoe_type
, tvb
, 0, 1, ENC_BIG_ENDIAN
);
1067 proto_tree_add_item(pppoe_tree
, hf_pppoe_code
, tvb
, 1, 1, ENC_BIG_ENDIAN
);
1068 proto_tree_add_item(pppoe_tree
, hf_pppoe_session_id
, tvb
, 2, 2, ENC_BIG_ENDIAN
);
1069 ti
= proto_tree_add_item(pppoe_tree
, hf_pppoe_payload_length
, tvb
, 4, 2, ENC_BIG_ENDIAN
);
1072 if (PPPOE_TAG_CREDITS
== tvb_get_ntohs(tvb
, 6))
1075 poe_tag_length
= tvb_get_ntohs(tvb
, tagstart
+ 2);
1077 /* Create tags subtree */
1078 ti
= proto_tree_add_item(pppoe_tree
, hf_pppoes_tags
, tvb
, tagstart
, 8, ENC_NA
);
1079 pppoe_tree
= proto_item_add_subtree(ti
, ett_pppoes_tags
);
1082 if (poe_tag_length
== 4)
1084 proto_tree_add_item(pppoe_tree
, hf_pppoes_tag_credits_fcn
, tvb
,
1085 tagstart
+4, 2, ENC_BIG_ENDIAN
);
1086 proto_tree_add_item(pppoe_tree
, hf_pppoes_tag_credits_bcn
, tvb
,
1087 tagstart
+6, 2, ENC_BIG_ENDIAN
);
1089 proto_tree_add_item(pppoe_tree
, hf_pppoed_tag_credits
, tvb
,
1090 tagstart
+4, poe_tag_length
, ENC_NA
);
1098 * The only reason why the payload length from the header
1099 * should differ from the remaining data in the packet
1100 * would be if the total packet length, including Ethernet
1101 * CRC, were < 64 bytes, so that padding was required.
1103 * That means that you have 14 bytes of Ethernet header,
1104 * 4 bytes of FCS, and fewer than 46 bytes of PPPoE packet.
1106 * If that's not the case, we report a difference between
1107 * the payload length in the packet, and the amount of
1108 * data following the PPPoE header, as an error.
1110 if (tvb_reported_length(tvb
) > 46) {
1112 * Be forgiving about a possible trailing FCS.
1114 * XXX - this dissector currently doesn't know
1115 * whether any extra data past the end of the PPP
1116 * payload is an FCS or not.
1118 * If we know that we have an FCS, or that we don't
1119 * have an FCS, we should have been handed a tvbuff
1120 * without the FCS, and we should just do the strict
1123 * If we don't know whether we have an FCS, then:
1125 * if this isn't over Ethernet - the "E" in "PPPoE"
1126 * nonwithstanding, it can also run on top of 802.11,
1127 * for example - there's no trailer, so any data
1128 * past the payload length is either an FCS or
1131 * if this is over Ethernet, there shouldn't be
1132 * a trailer, as the packet is long enough not to
1133 * require a trailer, as per the above;
1135 * so perhaps we should assume that if we have exactly
1136 * 4 bytes of extra information, it's an FCS, otherwise
1139 * Perhaps we need to have a routine to call to
1140 * do all the length checking, etc., and call it
1141 * from here and from other dissectors where the
1142 * protocol has a length field, or have a way to
1143 * tell the dissector that called us which field
1144 * has the length field and have *that* dissector
1145 * do the length checking and add the expert info
1146 * to the length field, *after* it does all the
1150 /* retrieve the control protocol code if it's there */
1151 cp_code
= tvb_get_ntohs(tvb
, 6);
1153 * The session payload length expressly does not include pad bytes
1154 * when LCP or IPCP or IPv6CP are present, so avoid the spurious error message
1156 if ((cp_code
!= PPP_LCP
) && (cp_code
!= PPP_IPCP
) && (cp_code
!= PPP_IPV6CP
) &&
1157 (reported_payload_length
!= actual_payload_length
) &&
1158 ((reported_payload_length
+ 4) != actual_payload_length
)) {
1159 proto_item_append_text(ti
, " [incorrect, should be %u]",
1160 actual_payload_length
);
1161 expert_add_info_format(pinfo
, ti
, &ei_pppoe_payload_length
, "Possible bad payload length %u != %u", reported_payload_length
, actual_payload_length
);
1166 * Construct a tvbuff containing the PPP packet.
1168 length
= tvb_captured_length_remaining(tvb
, 6);
1169 reported_length
= tvb_reported_length_remaining(tvb
, 6);
1170 DISSECTOR_ASSERT(length
>= 0);
1171 DISSECTOR_ASSERT(reported_length
>= 0);
1172 if (length
> reported_length
)
1173 length
= reported_length
;
1174 if ((unsigned)length
> reported_payload_length
)
1175 length
= reported_payload_length
;
1176 if ((unsigned)reported_length
> reported_payload_length
)
1177 reported_length
= reported_payload_length
;
1178 next_tvb
= tvb_new_subset_length_caplen(tvb
,(6 + credit_offset
),
1179 (length
- credit_offset
),
1180 (reported_length
- credit_offset
));
1181 call_dissector(ppp_handle
,next_tvb
,pinfo
,tree
);
1182 return tvb_captured_length(tvb
);
1185 void proto_register_pppoes(void)
1188 static hf_register_info hf
[] =
1191 { "PPPoE Tags", "pppoes.tags", FT_NONE
, BASE_NONE
,
1192 NULL
, 0x0, NULL
, HFILL
1197 { "Tag", "pppoes.tag", FT_UINT16
, BASE_HEX
,
1198 VALS(tag_vals
), 0x0, NULL
, HFILL
1203 { &hf_pppoes_tag_credits
,
1204 { "Credits", "pppoes.tags.credits", FT_BYTES
, BASE_NONE
,
1205 NULL
, 0x0, NULL
, HFILL
1209 { &hf_pppoes_tag_credits_fcn
,
1210 { "FCN", "pppoes.tags.credits.fcn", FT_UINT16
, BASE_DEC
,
1211 NULL
, 0x0, NULL
, HFILL
1214 { &hf_pppoes_tag_credits_bcn
,
1215 { "BCN", "pppoes.tags.credits.bcn", FT_UINT16
, BASE_DEC
,
1216 NULL
, 0x0, NULL
, HFILL
1221 static int *ett
[] = {
1226 /* Register protocol */
1227 proto_pppoes
= proto_register_protocol("PPP-over-Ethernet Session", "PPPoES", "pppoes");
1229 proto_register_subtree_array(ett
, array_length(ett
));
1230 proto_register_field_array(proto_pppoes
, hf
, array_length(hf
));
1232 pppoes_handle
= register_dissector("pppoes", dissect_pppoes
, proto_pppoes
);
1235 void proto_register_pppoe(void)
1237 static hf_register_info hf
[] =
1239 /* These fields common to discovery and session protocols */
1240 { &hf_pppoe_version
,
1241 { "Version", "pppoe.version", FT_UINT8
, BASE_DEC
,
1242 NULL
, 0xf0, NULL
, HFILL
1246 { "Type", "pppoe.type", FT_UINT8
, BASE_DEC
,
1247 NULL
, 0x0f, NULL
, HFILL
1251 { "Code", "pppoe.code", FT_UINT8
, BASE_HEX
,
1252 VALS(code_vals
), 0x0, NULL
, HFILL
1255 { &hf_pppoe_session_id
,
1256 { "Session ID", "pppoe.session_id", FT_UINT16
, BASE_HEX
,
1257 NULL
, 0x0, NULL
, HFILL
1260 { &hf_pppoe_payload_length
,
1261 { "Payload Length", "pppoe.payload_length", FT_UINT16
, BASE_DEC
,
1262 NULL
, 0x0, NULL
, HFILL
1267 static int *ett
[] = {
1271 static ei_register_info ei
[] = {
1272 { &ei_pppoe_tag_length
, { "pppoed.tag_length.invalid", PI_MALFORMED
, PI_WARN
, "Wrong length", EXPFILL
}},
1273 { &ei_pppoe_payload_length
, { "pppoe.payload_length.bad", PI_MALFORMED
, PI_WARN
, "Possible bad payload length", EXPFILL
}},
1276 expert_module_t
* expert_pppoe
;
1278 /* Register protocol */
1279 proto_pppoe
= proto_register_protocol("PPP-over-Ethernet", "PPPoE", "pppoe");
1281 proto_register_subtree_array(ett
, array_length(ett
));
1282 proto_register_field_array(proto_pppoe
, hf
, array_length(hf
));
1283 expert_pppoe
= expert_register_protocol(proto_pppoe
);
1284 expert_register_field_array(expert_pppoe
, ei
, array_length(ei
));
1288 void proto_reg_handoff_pppoes(void)
1290 dissector_add_uint("ethertype", ETHERTYPE_PPPOES
, pppoes_handle
);
1291 dissector_add_uint("wtap_encap", WTAP_ENCAP_PPP_ETHER
, pppoes_handle
);
1293 /* Get a handle for the PPP dissector */
1294 ppp_handle
= find_dissector_add_dependency("ppp", proto_pppoes
);
1298 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1303 * indent-tabs-mode: t
1306 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1307 * :indentSize=8:tabSize=8:noTabs=false: