Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-pppoe.c
blobb1dca4b5ab75d909dca25d4b81a6a1fbaaaa8d46
1 /* packet-pppoe.c
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
12 #include "config.h"
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)" },
222 {0, NULL }
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" },
245 {0, NULL }
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" },
266 {0, NULL }
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"},
272 {0, NULL }
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"},
280 {0, NULL }
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"},
293 {0, NULL }
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"},
301 {0, NULL }
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); \
310 } else { \
311 proto_tree_add_item(pppoe_tree, hf_var, tvb, \
312 tagstart+2, poe_tag_length, ENC_BIG_ENDIAN); \
314 break;
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); \
321 } else { \
322 proto_tree_add_item(pppoe_tree, hf_var, tvb, \
323 tagstart+2, poe_tag_length, ENC_ASCII|ENC_NA); \
325 break;
327 /* Dissect Vendor-Specific Tags introduced by the DSLF */
328 static void
329 dissect_pppoe_subtags_dslf(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree,
330 int payload_length)
332 uint8_t poe_tag;
333 uint8_t poe_tag_length;
334 int tagstart;
336 proto_tree *pppoe_tree, *ti, *encaps_tree;
338 /* Start Decoding Here. */
339 /* if (tree) */
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);
345 tagstart = offset;
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);
360 /* Show tag data */
361 switch (poe_tag)
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);
409 break;
410 default:
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 */
432 static void
433 dissect_pppoe_tags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree,
434 int payload_length)
436 uint16_t poe_tag;
437 uint16_t poe_tag_length;
438 int tagstart;
439 uint16_t poe_rsv = 0;
441 proto_tree *pppoe_tree;
442 proto_item *ti;
443 proto_item *pppoe_tree_tag_length_item = NULL;
445 /* Start Decoding Here. */
446 /* if (tree) */
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);
452 tagstart = offset;
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);
468 /* Show tag data */
469 switch (poe_tag)
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);
477 break;
478 case PPPOE_TAG_AC_NAME:
480 const uint8_t* str;
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);
486 break;
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);
490 break;
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);
494 break;
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);
504 switch (vendor_id)
506 case PPPOE_VENDOR_ID_DSLF:
507 dissect_pppoe_subtags_dslf(tvb,pinfo,tagstart+4+4,pppoe_tree,poe_tag_length-4);
508 break;
509 default:
510 proto_tree_add_item(pppoe_tree, hf_pppoed_tag_vendor_unspecified, tvb,
511 tagstart+4+4, poe_tag_length-4, ENC_NA);
515 break;
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);
523 } else {
524 proto_tree_add_item(pppoe_tree, hf_pppoed_tag_credits, tvb,
525 tagstart+4, poe_tag_length, ENC_NA);
527 break;
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);
546 /* CDR */
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");
554 break;
555 case (PPPOE_SCALE_MBPS):
556 proto_item_append_text(ti, " mbps");
557 break;
558 case (PPPOE_SCALE_GBPS):
559 proto_item_append_text(ti, " gbps");
560 break;
561 case (PPPOE_SCALE_TBPS):
562 proto_item_append_text(ti, " tbps");
563 break;
566 /* MDR */
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");
574 break;
575 case (PPPOE_SCALE_MBPS):
576 proto_item_append_text(ti, " mbps");
577 break;
578 case (PPPOE_SCALE_GBPS):
579 proto_item_append_text(ti, " gbps");
580 break;
581 case (PPPOE_SCALE_TBPS):
582 proto_item_append_text(ti, " tbps");
583 break;
586 } else {
587 proto_tree_add_item(pppoe_tree, hf_pppoed_tag_metrics, tvb,
588 tagstart+4, poe_tag_length, ENC_NA);
590 break;
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);
595 } else {
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);
603 break;
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);
608 } else {
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);
615 break;
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);
619 break;
620 case PPPOE_TAG_HURL:
621 proto_tree_add_item(pppoe_tree, hf_pppoed_tag_hurl, tvb,
622 tagstart+4, poe_tag_length, ENC_NA);
623 break;
624 case PPPOE_TAG_MOTM:
625 proto_tree_add_item(pppoe_tree, hf_pppoed_tag_motm, tvb,
626 tagstart+4, poe_tag_length, ENC_NA);
627 break;
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);
631 break;
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);
635 break;
637 /* These error tag values should be interpreted as a utf-8 unterminated
638 strings. */
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);
642 break;
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);
646 break;
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);
650 break;
652 /* Get out if see end-of-list tag */
653 case PPPOE_TAG_EOL:
654 return;
656 default:
657 if (poe_tag_length > 0 )
659 /* Presumably unknown tag;
660 show tag value if we didn't
661 do it above */
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_)
681 uint8_t pppoe_code;
682 uint16_t reported_payload_length;
684 proto_tree *pppoe_tree = NULL;
685 proto_item *ti;
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);
698 if (tree)
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 */
725 { &hf_pppoed_tags,
726 { "PPPoE Tags", "pppoed.tags", FT_NONE, BASE_NONE,
727 NULL, 0x0, NULL, HFILL
730 { &hf_pppoed_tag,
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[] = {
1003 &ett_pppoed,
1004 &ett_pppoed_tags,
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_)
1036 uint8_t pppoe_code;
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;
1042 uint16_t cp_code;
1044 proto_tree *pppoe_tree;
1045 proto_item *ti = NULL;
1046 tvbuff_t *next_tvb;
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);
1060 if (tree)
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))
1074 tagstart = 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);
1081 /* Show tag data */
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);
1088 } else {
1089 proto_tree_add_item(pppoe_tree, hf_pppoed_tag_credits, tvb,
1090 tagstart+4, poe_tag_length, ENC_NA);
1093 credit_offset = 8;
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
1121 * length check.
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
1129 * bogus;
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
1137 * it's not.
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
1147 * FCS heuristics.
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[] =
1190 { &hf_pppoes_tags,
1191 { "PPPoE Tags", "pppoes.tags", FT_NONE, BASE_NONE,
1192 NULL, 0x0, NULL, HFILL
1195 #if 0
1196 { &hf_pppoes_tag,
1197 { "Tag", "pppoes.tag", FT_UINT16, BASE_HEX,
1198 VALS(tag_vals), 0x0, NULL, HFILL
1201 #endif
1202 #if 0
1203 { &hf_pppoes_tag_credits,
1204 { "Credits", "pppoes.tags.credits", FT_BYTES, BASE_NONE,
1205 NULL, 0x0, NULL, HFILL
1208 #endif
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[] = {
1222 &ett_pppoes,
1223 &ett_pppoes_tags
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
1245 { &hf_pppoe_type,
1246 { "Type", "pppoe.type", FT_UINT8, BASE_DEC,
1247 NULL, 0x0f, NULL, HFILL
1250 { &hf_pppoe_code,
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[] = {
1268 &ett_pppoe
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
1300 * Local variables:
1301 * c-basic-offset: 8
1302 * tab-width: 8
1303 * indent-tabs-mode: t
1304 * End:
1306 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1307 * :indentSize=8:tabSize=8:noTabs=false: