Coverage Report

Created: 2025-12-27 06:52

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-pppoe.c
Line
Count
Source
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)
4
 *
5
 * Wireshark - Network traffic analyzer
6
 * By Gerald Combs <gerald@wireshark.org>
7
 * Copyright 1998 Gerald Combs
8
 *
9
 * SPDX-License-Identifier: GPL-2.0-or-later
10
 */
11
12
#include "config.h"
13
14
#include <epan/packet.h>
15
#include <epan/etypes.h>
16
#include <epan/prefs.h>
17
#include <epan/expert.h>
18
#include <wiretap/wtap.h>
19
#include "packet-ppp.h"
20
21
22
void proto_register_pppoed(void);
23
void proto_reg_handoff_pppoed(void);
24
void proto_register_pppoes(void);
25
void proto_register_pppoe(void);
26
void proto_reg_handoff_pppoes(void);
27
28
static dissector_handle_t pppoed_handle;
29
static dissector_handle_t pppoes_handle;
30
31
static int proto_pppoed;
32
33
/* Common to session and discovery protocols */
34
static int hf_pppoe_version;
35
static int hf_pppoe_type;
36
static int hf_pppoe_code;
37
static int hf_pppoe_session_id;
38
static int hf_pppoe_payload_length;
39
40
/* Discovery protocol fields */
41
static int hf_pppoed_tags;
42
static int hf_pppoed_tag;
43
static int hf_pppoed_tag_length;
44
static int hf_pppoed_tag_length_8;
45
static int hf_pppoed_tag_unknown_data;
46
static int hf_pppoed_tag_service_name;
47
static int hf_pppoed_tag_ac_name;
48
static int hf_pppoed_tag_host_uniq;
49
static int hf_pppoed_tag_ac_cookie;
50
static int hf_pppoed_tag_vendor_id;
51
static int hf_pppoed_tag_vendor_unspecified;
52
static int hf_pppoed_tag_vspec_tags;
53
static int hf_pppoed_tag_vspec_tag;
54
static int hf_pppoed_tag_vspec_circuit_id;
55
static int hf_pppoed_tag_vspec_remote_id;
56
static int hf_pppoed_tag_vspec_act_data_rate_up;
57
static int hf_pppoed_tag_vspec_act_data_rate_down;
58
static int hf_pppoed_tag_vspec_min_data_rate_up;
59
static int hf_pppoed_tag_vspec_min_data_rate_down;
60
static int hf_pppoed_tag_vspec_attainable_data_rate_up;
61
static int hf_pppoed_tag_vspec_attainable_data_rate_down;
62
static int hf_pppoed_tag_vspec_max_data_rate_up;
63
static int hf_pppoed_tag_vspec_max_data_rate_down;
64
static int hf_pppoed_tag_vspec_min_data_rate_up_lp;
65
static int hf_pppoed_tag_vspec_min_data_rate_down_lp;
66
static int hf_pppoed_tag_vspec_max_int_delay_up;
67
static int hf_pppoed_tag_vspec_act_int_delay_up;
68
static int hf_pppoed_tag_vspec_max_int_delay_down;
69
static int hf_pppoed_tag_vspec_act_int_delay_down;
70
static int hf_pppoed_tag_vspec_access_loop_encapsulation;
71
static int hf_pppoed_tag_vspec_access_loop_encap_data_link;
72
static int hf_pppoed_tag_vspec_access_loop_encap_encap_1;
73
static int hf_pppoed_tag_vspec_access_loop_encap_encap_2;
74
static int hf_pppoed_tag_credits;
75
static int hf_pppoed_tag_credits_fcn;
76
static int hf_pppoed_tag_credits_bcn;
77
static int hf_pppoed_tag_metrics;
78
static int hf_pppoed_tag_metrics_r;
79
static int hf_pppoed_tag_metrics_rlq;
80
static int hf_pppoed_tag_metrics_resource;
81
static int hf_pppoed_tag_metrics_latency;
82
static int hf_pppoed_tag_metrics_curr_drate;
83
static int hf_pppoed_tag_metrics_max_drate;
84
static int hf_pppoed_tag_mdr_units;
85
static int hf_pppoed_tag_cdr_units;
86
static int hf_pppoed_tag_seq_num;
87
static int hf_pppoed_tag_cred_scale;
88
static int hf_pppoed_tag_relay_session_id;
89
static int hf_pppoed_tag_hurl;
90
static int hf_pppoed_tag_motm;
91
static int hf_pppoed_tag_max_payload;
92
static int hf_pppoed_tag_ip_route_add;
93
static int hf_pppoed_tag_service_name_error;
94
static int hf_pppoed_tag_ac_system_error;
95
static int hf_pppoed_tag_generic_error;
96
97
/* Session protocol fields */
98
static int hf_pppoes_tags;
99
/* static int hf_pppoes_tag; */
100
/* static int hf_pppoes_tag_credits; */
101
static int hf_pppoes_tag_credits_fcn;
102
static int hf_pppoes_tag_credits_bcn;
103
104
/* Session protocol fields */
105
106
static int ett_pppoed;
107
static int ett_pppoed_tags;
108
static int ett_pppoed_tag_vspec_dslf_access_loop_encaps;
109
110
static int proto_pppoes;
111
112
static int ett_pppoes;
113
static int ett_pppoes_tags;
114
115
static expert_field ei_pppoe_payload_length;
116
static expert_field ei_pppoe_tag_length;
117
118
/* PPPoE parent fields */
119
120
static int proto_pppoe;
121
static int ett_pppoe;
122
123
124
/* Handle for calling for ppp dissector to handle session data */
125
static dissector_handle_t ppp_handle;
126
127
128
/* Preference for showing discovery tag values and lengths */
129
static bool global_pppoe_show_tags_and_lengths;
130
131
132
#define PPPOE_CODE_SESSION    0x00
133
#define PPPOE_CODE_PADO       0x07
134
#define PPPOE_CODE_PADI       0x09
135
#define PPPOE_CODE_PADG       0x0a
136
#define PPPOE_CODE_PADC       0x0b
137
#define PPPOE_CODE_PADQ       0x0c
138
#define PPPOE_CODE_PADR       0x19
139
#define PPPOE_CODE_PADS       0x65
140
#define PPPOE_CODE_PADT       0xa7
141
#define PPPOE_CODE_PADM       0xd3
142
#define PPPOE_CODE_PADN       0xd4
143
144
8
#define PPPOE_TAG_EOL         0x0000
145
0
#define PPPOE_TAG_SVC_NAME    0x0101
146
0
#define PPPOE_TAG_AC_NAME     0x0102
147
0
#define PPPOE_TAG_HOST_UNIQ   0x0103
148
0
#define PPPOE_TAG_AC_COOKIE   0x0104
149
0
#define PPPOE_TAG_VENDOR      0x0105
150
42
#define PPPOE_TAG_CREDITS     0x0106
151
0
#define PPPOE_TAG_METRICS     0x0107
152
0
#define PPPOE_TAG_SEQ_NUM     0x0108
153
0
#define PPPOE_TAG_CRED_SCALE  0x0109
154
0
#define PPPOE_TAG_RELAY_ID    0x0110
155
0
#define PPPOE_TAG_HURL        0x0111
156
0
#define PPPOE_TAG_MOTM        0x0112
157
0
#define PPPOE_TAG_MAX_PAYLD   0x0120
158
0
#define PPPOE_TAG_IP_RT_ADD   0x0121
159
0
#define PPPOE_TAG_SVC_ERR     0x0201
160
0
#define PPPOE_TAG_AC_ERR      0x0202
161
0
#define PPPOE_TAG_GENERIC_ERR 0x0203
162
163
0
#define PPPOE_VENDOR_ID_DSLF  3561
164
165
#define PPPOE_TAG_VSPEC_DSLF_CIRCUIT_ID                0x01
166
#define PPPOE_TAG_VSPEC_DSLF_REMOTE_ID                 0x02
167
#define PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_UP          0x81
168
#define PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_DOWN        0x82
169
#define PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP          0x83
170
#define PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN        0x84
171
#define PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_UP   0x85
172
#define PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_DOWN 0x86
173
#define PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_UP          0x87
174
#define PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_DOWN        0x88
175
#define PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP_LP       0x89
176
#define PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN_LP     0x8a
177
#define PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_UP          0x8b
178
#define PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_UP          0x8c
179
#define PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_DOWN        0x8d
180
#define PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_DOWN        0x8e
181
0
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAPSULATION 0x90
182
183
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_DATA_LINK_ATM 0x00
184
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_DATA_LINK_ETH 0x01
185
186
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_NA                0x00
187
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_UNTAGGED_ETH      0x01
188
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_SINGLE_TAGGED_ETH 0x02
189
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_DOUBLE_TAGGED_ETH 0x03
190
191
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_NA                             0x00
192
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_PPPOA_LLC                      0x01
193
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_PPPOA_NULL                     0x02
194
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_IPOA_LLC                       0x03
195
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_IPOA_NULL                      0x04
196
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_LLC_WITH_FCS     0x05
197
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_LLC_WITHOUT_FCS  0x06
198
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_NULL_WITH_FCS    0x07
199
#define PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_NULL_WITHOUT_FCS 0x08
200
201
14
#define PPPOE_CDR_MASK        0x0006
202
14
#define PPPOE_MDR_MASK        0x0018
203
14
#define PPPOE_RCV_ONLY_MASK   0x0001
204
205
0
#define PPPOE_SCALE_KBPS      0x00
206
0
#define PPPOE_SCALE_MBPS      0x01
207
0
#define PPPOE_SCALE_GBPS      0x02
208
0
#define PPPOE_SCALE_TBPS      0x03
209
210
211
static const value_string code_vals[] = {
212
  {PPPOE_CODE_SESSION, "Session Data"                             },
213
  {PPPOE_CODE_PADO, "Active Discovery Offer (PADO)"               },
214
  {PPPOE_CODE_PADI, "Active Discovery Initiation (PADI)"          },
215
  {PPPOE_CODE_PADG, "Active Discovery Session-Grant (PADG)"       },
216
  {PPPOE_CODE_PADC, "Active Discovery Session-Credit Resp.(PADC)" },
217
  {PPPOE_CODE_PADQ, "Active Discovery Quality (PADQ)"             },
218
  {PPPOE_CODE_PADR, "Active Discovery Request (PADR)"             },
219
  {PPPOE_CODE_PADS, "Active Discovery Session-confirmation (PADS)"},
220
  {PPPOE_CODE_PADT, "Active Discovery Terminate (PADT)"           },
221
  {PPPOE_CODE_PADM, "Active Discovery Message (PADM)"             },
222
  {PPPOE_CODE_PADN, "Active Discovery Network (PADN)"             },
223
  {0,               NULL                                          }
224
};
225
226
227
static const value_string tag_vals[] = {
228
  {PPPOE_TAG_EOL,        "End-Of-List"       },
229
  {PPPOE_TAG_SVC_NAME,   "Service-Name"      },
230
  {PPPOE_TAG_AC_NAME,    "AC-Name"           },
231
  {PPPOE_TAG_HOST_UNIQ,  "Host-Uniq"         },
232
  {PPPOE_TAG_AC_COOKIE,  "AC-Cookie"         },
233
  {PPPOE_TAG_VENDOR,     "Vendor-Specific"   },
234
  {PPPOE_TAG_CREDITS,    "Credits"           },
235
  {PPPOE_TAG_METRICS,    "Metrics"           },
236
  {PPPOE_TAG_SEQ_NUM,    "Sequence Number"    },
237
  {PPPOE_TAG_CRED_SCALE, "Credit Scale Factor"},
238
  {PPPOE_TAG_RELAY_ID,   "Relay-Session-Id"  },
239
  {PPPOE_TAG_HURL,       "HURL"              },
240
  {PPPOE_TAG_MOTM,       "MOTM"              },
241
  {PPPOE_TAG_MAX_PAYLD,  "PPP-Max-Payload"   },
242
  {PPPOE_TAG_IP_RT_ADD,  "IP Route Add"      },
243
  {PPPOE_TAG_SVC_ERR,    "Service-Name-Error"},
244
  {PPPOE_TAG_AC_ERR,     "AC-System-Error"   },
245
  {PPPOE_TAG_GENERIC_ERR,"Generic-Error"     },
246
  {0,                    NULL                }
247
};
248
249
static const value_string vspec_tag_vals[] = {
250
  {PPPOE_TAG_VSPEC_DSLF_CIRCUIT_ID,                "Circuit-ID"                    },
251
  {PPPOE_TAG_VSPEC_DSLF_REMOTE_ID,                 "Remote-ID"                     },
252
  {PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_UP,          "Actual-Data-Rate-Up"           },
253
  {PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_DOWN,        "Actual-Data-Rate-Down"         },
254
  {PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP,          "Min-Data-Rate-Up"              },
255
  {PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN,        "Min-Data-Rate-Down"            },
256
  {PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_UP,   "Attainable-Data-Rate-Up"       },
257
  {PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_DOWN, "Attainable-Data-Rate-Down"     },
258
  {PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_UP,          "Max-Data-Rate-Up"              },
259
  {PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_DOWN,        "Max-Data-Rate-Down"            },
260
  {PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP_LP,       "Min-Data-Rate-Up-Low-Power"    },
261
  {PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN_LP,     "Min-Data-Rate-Down-Low-Power"  },
262
  {PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_UP,          "Max-Interleaving-Delay-Up"     },
263
  {PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_UP,          "Actual-Interleaving-Delay-Up"  },
264
  {PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_DOWN,        "Max-Interleaving-Delay-Down"   },
265
  {PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_DOWN,        "Actual-Interleaving-Delay-Down"},
266
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAPSULATION, "Access-Loop-Encapsulation"     },
267
  {0,                                              NULL                            }
268
};
269
270
static const value_string vspec_tag_dslf_access_loop_encap_data_link_vals[] = {
271
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_DATA_LINK_ATM, "ATM AAL5"},
272
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_DATA_LINK_ETH, "Ethernet"},
273
  {0,                                                     NULL     }
274
};
275
276
static const value_string vspec_tag_dslf_access_loop_encap_encap_1_vals[] = {
277
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_NA,                "NA"                    },
278
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_UNTAGGED_ETH,      "Untagged Ethernet"     },
279
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_SINGLE_TAGGED_ETH, "Single-tagged Ethernet"},
280
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_1_DOUBLE_TAGGED_ETH, "Double-tagged Ethernet"},
281
  {0,                                                     NULL                                }
282
};
283
284
static const value_string vspec_tag_dslf_access_loop_encap_encap_2_vals[] = {
285
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_NA,                            "NA"                             },
286
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_PPPOA_LLC,                     "PPPoA LLC"                      },
287
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_PPPOA_NULL,                    "PPPoA Null"                     },
288
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_IPOA_LLC,                      "IPoA LLC"                       },
289
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_IPOA_NULL,                     "IPoA Null"                      },
290
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_LLC_WITH_FCS,    "Ethernet over AAL5 LLC w FCS"   },
291
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_LLC_WITHOUT_FCS, "Ethernet over AAL5 LLC w/o FCS" },
292
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_NULL_WITH_FCS,   "Ethernet over AAL5 Null w FCS"  },
293
  {PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAP_ENCAPS_2_ETH_OVER_AAL5_NULL_WITHOUT_FCS,"Ethernet over AAL5 Null w/o FCS"},
294
  {0,                                                     NULL                               }
295
};
296
297
static const value_string datarate_scale_vals[] = {
298
  {PPPOE_SCALE_KBPS,  "kilobits per second"},
299
  {PPPOE_SCALE_MBPS,  "megabits per second"},
300
  {PPPOE_SCALE_GBPS,  "gigabits per second"},
301
  {PPPOE_SCALE_TBPS,  "terabits per second"},
302
  {0,     NULL         }
303
};
304
305
306
0
#define CASE_VSPEC_DSLF_TAG_UINT(tag_name, relation, length, hf_var) case tag_name: \
307
0
    if (!(poe_tag_length relation length)) { \
308
0
      expert_add_info_format(pinfo, pppoe_tree, &ei_pppoe_tag_length, \
309
0
      "%s: Wrong length: %u (expected %s %d)", \
310
0
      val_to_str_const(poe_tag, vspec_tag_vals, "Unknown"), poe_tag_length, #relation, length); \
311
0
    } else { \
312
0
      proto_tree_add_item(pppoe_tree, hf_var, tvb, \
313
0
        tagstart+2, poe_tag_length, ENC_BIG_ENDIAN); \
314
0
    } \
315
0
  break;
316
317
0
#define CASE_VSPEC_DSLF_TAG_STRING(tag_name, relation, length, hf_var) case tag_name: \
318
0
    if (!(poe_tag_length relation length)) { \
319
0
      expert_add_info_format(pinfo, pppoe_tree, &ei_pppoe_tag_length, \
320
0
      "%s: Wrong length: %u (expected %s %d)", \
321
0
      val_to_str_const(poe_tag, vspec_tag_vals, "Unknown"), poe_tag_length, #relation, length); \
322
0
    } else { \
323
0
      proto_tree_add_item(pppoe_tree, hf_var, tvb, \
324
0
        tagstart+2, poe_tag_length, ENC_ASCII|ENC_NA); \
325
0
    } \
326
0
  break;
327
328
/* Dissect Vendor-Specific Tags introduced by the DSLF */
329
static void
330
dissect_pppoe_subtags_dslf(tvbuff_t *tvb, packet_info *pinfo _U_, int offset, proto_tree *tree,
331
         int payload_length)
332
0
{
333
0
  uint8_t poe_tag;
334
0
  uint8_t poe_tag_length;
335
0
  int tagstart;
336
337
0
  proto_tree  *pppoe_tree, *ti, *encaps_tree;
338
339
  /* Start Decoding Here. */
340
  /* Create tags subtree */
341
0
  ti = proto_tree_add_item(tree, hf_pppoed_tag_vspec_tags, tvb, offset, payload_length, ENC_NA);
342
0
  pppoe_tree = proto_item_add_subtree(ti, ett_pppoed_tags);
343
344
0
  tagstart = offset;
345
346
  /* Loop until all data seen or End-Of-List tag found */
347
0
  while (tagstart <= offset + payload_length-2)
348
0
  {
349
0
    poe_tag = tvb_get_uint8(tvb, tagstart);
350
0
    poe_tag_length = tvb_get_uint8(tvb, tagstart + 1);
351
352
    /* Tag value and data length */
353
0
    if (global_pppoe_show_tags_and_lengths)
354
0
    {
355
0
      proto_tree_add_item(pppoe_tree, hf_pppoed_tag_vspec_tag, tvb, tagstart, 1, ENC_BIG_ENDIAN);
356
0
      proto_tree_add_item(pppoe_tree, hf_pppoed_tag_length_8, tvb, tagstart+1, 1, ENC_BIG_ENDIAN);
357
0
    }
358
359
    /* Show tag data */
360
0
    switch (poe_tag)
361
0
    {
362
0
      CASE_VSPEC_DSLF_TAG_STRING(PPPOE_TAG_VSPEC_DSLF_CIRCUIT_ID, <=, 63,
363
0
          hf_pppoed_tag_vspec_circuit_id)
364
0
      CASE_VSPEC_DSLF_TAG_STRING(PPPOE_TAG_VSPEC_DSLF_REMOTE_ID, <=, 63,
365
0
          hf_pppoed_tag_vspec_remote_id)
366
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_UP, ==, 4,
367
0
          hf_pppoed_tag_vspec_act_data_rate_up)
368
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ACT_DATA_RATE_DOWN, ==, 4,
369
0
          hf_pppoed_tag_vspec_act_data_rate_down)
370
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP, ==, 4,
371
0
          hf_pppoed_tag_vspec_min_data_rate_up)
372
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN, ==, 4,
373
0
          hf_pppoed_tag_vspec_min_data_rate_down)
374
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_UP, ==, 4,
375
0
          hf_pppoed_tag_vspec_attainable_data_rate_up)
376
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ATTAINABLE_DATA_RATE_DOWN, ==, 4,
377
0
          hf_pppoed_tag_vspec_attainable_data_rate_down)
378
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_UP, ==, 4,
379
0
          hf_pppoed_tag_vspec_max_data_rate_up)
380
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MAX_DATA_RATE_DOWN, ==, 4,
381
0
          hf_pppoed_tag_vspec_max_data_rate_down)
382
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_UP_LP, ==, 4,
383
0
          hf_pppoed_tag_vspec_min_data_rate_up_lp)
384
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MIN_DATA_RATE_DOWN_LP, ==, 4,
385
0
          hf_pppoed_tag_vspec_min_data_rate_down_lp)
386
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_UP, ==, 4,
387
0
          hf_pppoed_tag_vspec_max_int_delay_up)
388
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_UP, ==, 4,
389
0
          hf_pppoed_tag_vspec_act_int_delay_up)
390
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_MAX_INT_DELAY_DOWN, ==, 4,
391
0
          hf_pppoed_tag_vspec_max_int_delay_down)
392
0
      CASE_VSPEC_DSLF_TAG_UINT(PPPOE_TAG_VSPEC_DSLF_ACT_INT_DELAY_DOWN, ==, 4,
393
0
          hf_pppoed_tag_vspec_act_int_delay_down)
394
0
      case PPPOE_TAG_VSPEC_DSLF_ACCESS_LOOP_ENCAPSULATION:
395
0
        ti = proto_tree_add_item(pppoe_tree, hf_pppoed_tag_vspec_access_loop_encapsulation, tvb,
396
0
            tagstart+2, 3, ENC_NA);
397
0
        if (poe_tag_length != 3) {
398
0
          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);
399
0
        }
400
0
        encaps_tree = proto_item_add_subtree(ti, ett_pppoed_tag_vspec_dslf_access_loop_encaps);
401
0
        proto_tree_add_item(encaps_tree, hf_pppoed_tag_vspec_access_loop_encap_data_link,
402
0
            tvb, tagstart+2, 1, ENC_BIG_ENDIAN);
403
0
        proto_tree_add_item(encaps_tree, hf_pppoed_tag_vspec_access_loop_encap_encap_1,
404
0
            tvb, tagstart+3, 1, ENC_BIG_ENDIAN);
405
0
        proto_tree_add_item(encaps_tree, hf_pppoed_tag_vspec_access_loop_encap_encap_2,
406
0
            tvb, tagstart+4, 1, ENC_BIG_ENDIAN);
407
408
0
        break;
409
0
      default:
410
0
        if (poe_tag_length > 0 )
411
0
        {
412
          /* Presumably unknown tag;
413
             show tag value if we didn't do it above */
414
0
          if (!global_pppoe_show_tags_and_lengths)
415
0
          {
416
0
            proto_tree_add_item(pppoe_tree, hf_pppoed_tag, tvb, tagstart, 1, ENC_BIG_ENDIAN);
417
0
            proto_tree_add_item(pppoe_tree, hf_pppoed_tag_length_8, tvb, tagstart+1, 1, ENC_BIG_ENDIAN);
418
0
          }
419
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_unknown_data, tvb,
420
0
              tagstart+2, poe_tag_length, ENC_NA);
421
0
        }
422
0
    }
423
424
0
    tagstart += (2 + poe_tag_length);
425
0
  }
426
0
}
427
428
429
/* Dissect discovery protocol tags */
430
static void
431
dissect_pppoe_tags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *tree,
432
       int payload_length)
433
9
{
434
9
  uint16_t poe_tag;
435
9
  uint16_t poe_tag_length;
436
9
  int tagstart;
437
9
  uint16_t poe_rsv = 0;
438
439
9
  proto_tree  *pppoe_tree;
440
9
  proto_item  *ti;
441
9
  proto_item  *pppoe_tree_tag_length_item = NULL;
442
443
  /* Start Decoding Here. */
444
  /* Create tags subtree */
445
9
  ti = proto_tree_add_item(tree, hf_pppoed_tags, tvb, offset, payload_length-6, ENC_NA);
446
9
  pppoe_tree = proto_item_add_subtree(ti, ett_pppoed_tags);
447
448
9
  tagstart = offset;
449
450
  /* Loop until all data seen or End-Of-List tag found */
451
9
  while (tagstart <= payload_length-2)
452
9
  {
453
9
    poe_tag = tvb_get_ntohs(tvb, tagstart);
454
9
    poe_tag_length = tvb_get_ntohs(tvb, tagstart + 2);
455
456
    /* Tag value and data length */
457
9
    if (global_pppoe_show_tags_and_lengths)
458
0
    {
459
0
      proto_tree_add_item(pppoe_tree, hf_pppoed_tag, tvb, tagstart, 2, ENC_BIG_ENDIAN);
460
0
      pppoe_tree_tag_length_item =
461
0
        proto_tree_add_item(pppoe_tree, hf_pppoed_tag_length, tvb, tagstart+2, 2, ENC_BIG_ENDIAN);
462
0
    }
463
464
    /* Show tag data */
465
9
    switch (poe_tag)
466
9
    {
467
0
      case PPPOE_TAG_SVC_NAME:
468
0
        if (poe_tag_length > 0)
469
0
        {
470
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_service_name, tvb,
471
0
                  tagstart+4, poe_tag_length, ENC_ASCII);
472
0
        }
473
0
        break;
474
0
      case PPPOE_TAG_AC_NAME:
475
0
        {
476
0
        const uint8_t* str;
477
0
        proto_tree_add_item_ret_string(pppoe_tree, hf_pppoed_tag_ac_name, tvb,
478
0
                tagstart+4, poe_tag_length, ENC_ASCII|ENC_NA, pinfo->pool, &str);
479
        /* Show AC-Name in info column */
480
0
        col_append_fstr(pinfo->cinfo, COL_INFO, " AC-Name='%s'", str);
481
0
        }
482
0
        break;
483
0
      case PPPOE_TAG_HOST_UNIQ:
484
0
        proto_tree_add_item(pppoe_tree, hf_pppoed_tag_host_uniq, tvb,
485
0
                tagstart+4, poe_tag_length, ENC_NA);
486
0
        break;
487
0
      case PPPOE_TAG_AC_COOKIE:
488
0
        proto_tree_add_item(pppoe_tree, hf_pppoed_tag_ac_cookie, tvb,
489
0
                tagstart+4, poe_tag_length, ENC_NA);
490
0
        break;
491
0
      case PPPOE_TAG_VENDOR:
492
0
        if (poe_tag_length >= 4)
493
0
        {
494
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_vendor_id, tvb,
495
0
                    tagstart+4, 4, ENC_BIG_ENDIAN);
496
0
        }
497
0
        if (poe_tag_length > 4)
498
0
        {
499
0
          uint32_t vendor_id = tvb_get_ntohl(tvb, tagstart+4);
500
0
          switch (vendor_id)
501
0
          {
502
0
            case PPPOE_VENDOR_ID_DSLF:
503
0
              dissect_pppoe_subtags_dslf(tvb,pinfo,tagstart+4+4,pppoe_tree,poe_tag_length-4);
504
0
              break;
505
0
            default:
506
0
              proto_tree_add_item(pppoe_tree, hf_pppoed_tag_vendor_unspecified, tvb,
507
0
                      tagstart+4+4, poe_tag_length-4, ENC_NA);
508
509
0
          }
510
0
        }
511
0
        break;
512
0
      case PPPOE_TAG_CREDITS:
513
0
        if (poe_tag_length == 4)
514
0
        {
515
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_credits_fcn, tvb,
516
0
                  tagstart+4, 2, ENC_BIG_ENDIAN);
517
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_credits_bcn, tvb,
518
0
                  tagstart+6, 2, ENC_BIG_ENDIAN);
519
0
        } else {
520
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_credits, tvb,
521
0
                  tagstart+4, poe_tag_length, ENC_NA);
522
0
        }
523
0
        break;
524
0
      case PPPOE_TAG_METRICS:
525
0
        if (poe_tag_length == 10)
526
0
        {
527
0
          poe_rsv = tvb_get_ntohs(tvb, tagstart+4);
528
529
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_mdr_units, tvb,
530
0
                  tagstart+4, 2, ENC_BIG_ENDIAN);
531
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_cdr_units, tvb,
532
0
                  tagstart+4, 2, ENC_BIG_ENDIAN);
533
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_metrics_r, tvb,
534
0
                  tagstart+4, 2, ENC_BIG_ENDIAN);
535
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_metrics_rlq, tvb,
536
0
                  tagstart+6, 1, ENC_BIG_ENDIAN);
537
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_metrics_resource, tvb,
538
0
                  tagstart+7, 1, ENC_BIG_ENDIAN);
539
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_metrics_latency, tvb,
540
0
                  tagstart+8, 2, ENC_BIG_ENDIAN);
541
542
          /* CDR */
543
0
          ti = proto_tree_add_item(pppoe_tree, hf_pppoed_tag_metrics_curr_drate, tvb,
544
0
                 tagstart+10, 2, ENC_BIG_ENDIAN);
545
546
0
          switch ((poe_rsv & PPPOE_CDR_MASK) >> 1)
547
0
          {
548
0
            case (PPPOE_SCALE_KBPS):
549
0
              proto_item_append_text(ti, " kbps");
550
0
              break;
551
0
            case (PPPOE_SCALE_MBPS):
552
0
              proto_item_append_text(ti, " mbps");
553
0
              break;
554
0
            case (PPPOE_SCALE_GBPS):
555
0
              proto_item_append_text(ti, " gbps");
556
0
              break;
557
0
            case (PPPOE_SCALE_TBPS):
558
0
              proto_item_append_text(ti, " tbps");
559
0
              break;
560
0
          }
561
562
          /* MDR */
563
0
          ti = proto_tree_add_item(pppoe_tree, hf_pppoed_tag_metrics_max_drate, tvb,
564
0
                  tagstart+12, 2, ENC_BIG_ENDIAN);
565
566
0
          switch ((poe_rsv & PPPOE_MDR_MASK) >> 3)
567
0
          {
568
0
            case (PPPOE_SCALE_KBPS):
569
0
              proto_item_append_text(ti, " kbps");
570
0
              break;
571
0
            case (PPPOE_SCALE_MBPS):
572
0
              proto_item_append_text(ti, " mbps");
573
0
              break;
574
0
            case (PPPOE_SCALE_GBPS):
575
0
              proto_item_append_text(ti, " gbps");
576
0
              break;
577
0
            case (PPPOE_SCALE_TBPS):
578
0
              proto_item_append_text(ti, " tbps");
579
0
              break;
580
0
          }
581
582
0
        } else {
583
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_metrics, tvb,
584
0
                  tagstart+4, poe_tag_length, ENC_NA);
585
0
        }
586
0
        break;
587
0
      case PPPOE_TAG_SEQ_NUM:
588
0
        if (poe_tag_length == 2) {
589
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_seq_num, tvb,
590
0
                  tagstart+4, poe_tag_length, ENC_BIG_ENDIAN);
591
0
        } else {
592
0
          if (global_pppoe_show_tags_and_lengths) {
593
0
            proto_item_append_text(pppoe_tree_tag_length_item, " [Wrong: should be 2]");
594
0
          }
595
596
0
          proto_tree_add_expert_format(pppoe_tree, pinfo, &ei_pppoe_tag_length, tvb, tagstart+4, poe_tag_length,
597
0
                "Sequence Number tag: Wrong length: %u (expected 2)", poe_tag_length);
598
0
        }
599
0
        break;
600
0
      case PPPOE_TAG_CRED_SCALE:
601
0
        if (poe_tag_length == 2) {
602
0
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_cred_scale, tvb,
603
0
                  tagstart+4, poe_tag_length, ENC_BIG_ENDIAN);
604
0
        } else {
605
0
          if (global_pppoe_show_tags_and_lengths) {
606
0
            proto_item_append_text(pppoe_tree_tag_length_item, " [Wrong: should be 2]");
607
0
          }
608
0
          proto_tree_add_expert_format(pppoe_tree, pinfo, &ei_pppoe_tag_length, tvb, tagstart+4, poe_tag_length,
609
0
                "Credit Scale Factor tag: Wrong length: %u (expected 2)", poe_tag_length);
610
0
        }
611
0
        break;
612
0
      case PPPOE_TAG_RELAY_ID:
613
0
        proto_tree_add_item(pppoe_tree, hf_pppoed_tag_relay_session_id, tvb,
614
0
                tagstart+4, poe_tag_length, ENC_NA);
615
0
        break;
616
0
      case PPPOE_TAG_HURL:
617
0
        proto_tree_add_item(pppoe_tree, hf_pppoed_tag_hurl, tvb,
618
0
                tagstart+4, poe_tag_length, ENC_NA);
619
0
        break;
620
0
      case PPPOE_TAG_MOTM:
621
0
        proto_tree_add_item(pppoe_tree, hf_pppoed_tag_motm, tvb,
622
0
                tagstart+4, poe_tag_length, ENC_NA);
623
0
        break;
624
0
      case PPPOE_TAG_MAX_PAYLD:
625
0
        proto_tree_add_item(pppoe_tree, hf_pppoed_tag_max_payload, tvb,
626
0
                tagstart+4, poe_tag_length, ENC_NA);
627
0
        break;
628
0
      case PPPOE_TAG_IP_RT_ADD:
629
0
        proto_tree_add_item(pppoe_tree, hf_pppoed_tag_ip_route_add, tvb,
630
0
                tagstart+4, poe_tag_length, ENC_NA);
631
0
        break;
632
633
      /* These error tag values should be interpreted as a utf-8 unterminated
634
         strings. */
635
0
      case PPPOE_TAG_SVC_ERR:
636
0
        proto_tree_add_item(pppoe_tree, hf_pppoed_tag_service_name_error, tvb,
637
0
                tagstart+4, poe_tag_length, ENC_ASCII);
638
0
        break;
639
0
      case PPPOE_TAG_AC_ERR:
640
0
        proto_tree_add_item(pppoe_tree, hf_pppoed_tag_ac_system_error, tvb,
641
0
                tagstart+4, poe_tag_length, ENC_ASCII);
642
0
        break;
643
0
      case PPPOE_TAG_GENERIC_ERR:
644
0
        proto_tree_add_item(pppoe_tree, hf_pppoed_tag_generic_error, tvb,
645
0
                tagstart+4, poe_tag_length, ENC_ASCII);
646
0
        break;
647
648
      /* Get out if see end-of-list tag */
649
8
      case PPPOE_TAG_EOL:
650
8
        return;
651
652
1
      default:
653
1
        if (poe_tag_length > 0 )
654
1
        {
655
          /* Presumably unknown tag;
656
             show tag value if we didn't
657
             do it above */
658
1
          if (!global_pppoe_show_tags_and_lengths)
659
1
          {
660
1
            proto_tree_add_item(pppoe_tree, hf_pppoed_tag, tvb, tagstart, 2, ENC_BIG_ENDIAN);
661
1
            proto_tree_add_item(pppoe_tree, hf_pppoed_tag_length, tvb, tagstart+2, 2, ENC_BIG_ENDIAN);
662
1
          }
663
1
          proto_tree_add_item(pppoe_tree, hf_pppoed_tag_unknown_data, tvb,
664
1
              tagstart+2, poe_tag_length, ENC_NA);
665
1
        }
666
9
    }
667
668
0
    tagstart += (4 + poe_tag_length);
669
0
  }
670
9
}
671
672
673
/* Discovery protocol, i.e. PPP session not yet established */
674
static int dissect_pppoed(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
675
17
{
676
17
  uint8_t pppoe_code;
677
17
  uint16_t reported_payload_length;
678
679
17
  proto_tree  *pppoe_tree = NULL;
680
17
  proto_item  *ti;
681
682
17
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPPoED");
683
17
  col_clear(pinfo->cinfo, COL_INFO);
684
685
  /* Start Decoding Here. */
686
17
  pppoe_code = tvb_get_uint8(tvb, 1);
687
688
17
  col_append_str(pinfo->cinfo, COL_INFO, val_to_str_const(pppoe_code, code_vals, "Unknown"));
689
690
  /* Read length of payload */
691
17
  reported_payload_length = tvb_get_ntohs(tvb, 4);
692
693
17
  if (tree)
694
17
  {
695
17
    ti = proto_tree_add_item(tree, proto_pppoed, tvb, 0, reported_payload_length+6, ENC_NA);
696
17
    pppoe_tree = proto_item_add_subtree(ti, ett_pppoed);
697
698
    /* Dissect fixed fields */
699
17
    proto_tree_add_item(pppoe_tree, hf_pppoe_version, tvb, 0, 1, ENC_BIG_ENDIAN);
700
17
    proto_tree_add_item(pppoe_tree, hf_pppoe_type, tvb, 0, 1, ENC_BIG_ENDIAN);
701
17
    proto_tree_add_item(pppoe_tree, hf_pppoe_code, tvb, 1, 1, ENC_BIG_ENDIAN);
702
17
    proto_tree_add_item(pppoe_tree, hf_pppoe_session_id, tvb, 2, 2, ENC_BIG_ENDIAN);
703
17
    proto_tree_add_item(pppoe_tree, hf_pppoe_payload_length, tvb, 4, 2, ENC_BIG_ENDIAN);
704
17
  }
705
706
  /* Now dissect any tags */
707
17
  if (reported_payload_length > 0)
708
9
  {
709
9
    dissect_pppoe_tags(tvb, pinfo, 6, pppoe_tree, 6+reported_payload_length);
710
9
  }
711
712
17
  return tvb_captured_length(tvb);
713
17
}
714
715
void proto_register_pppoed(void)
716
14
{
717
14
  static hf_register_info hf[] =
718
14
  {
719
    /* Discovery tag fields */
720
14
    { &hf_pppoed_tags,
721
14
      { "PPPoE Tags", "pppoed.tags", FT_NONE, BASE_NONE,
722
14
         NULL, 0x0, NULL, HFILL
723
14
      }
724
14
    },
725
14
    { &hf_pppoed_tag,
726
14
      { "Tag", "pppoed.tag", FT_UINT16, BASE_HEX,
727
14
         VALS(tag_vals), 0x0, NULL, HFILL
728
14
      }
729
14
    },
730
14
    { &hf_pppoed_tag_length,
731
14
      { "Tag Length", "pppoed.tag_length", FT_UINT16, BASE_DEC,
732
14
         NULL, 0x0, NULL, HFILL
733
14
      }
734
14
    },
735
14
    { &hf_pppoed_tag_length_8,
736
14
      { "Tag Length", "pppoed.tag_length_8", FT_UINT8, BASE_DEC,
737
14
         NULL, 0x0, NULL, HFILL
738
14
      }
739
14
    },
740
14
    { &hf_pppoed_tag_unknown_data,
741
14
      { "Unknown Data", "pppoed.tag.unknown_data", FT_BYTES, BASE_NONE,
742
14
         NULL, 0x0, NULL, HFILL
743
14
      }
744
14
    },
745
14
    { &hf_pppoed_tag_service_name,
746
14
      { "Service-Name", "pppoed.tags.service_name", FT_STRING, BASE_NONE,
747
14
         NULL, 0x0, NULL, HFILL
748
14
      }
749
14
    },
750
14
    { &hf_pppoed_tag_ac_name,
751
14
      { "AC-Name", "pppoed.tags.ac_name", FT_STRING, BASE_NONE,
752
14
         NULL, 0x0, NULL, HFILL
753
14
      }
754
14
    },
755
14
    { &hf_pppoed_tag_host_uniq,
756
14
      { "Host-Uniq", "pppoed.tags.host_uniq", FT_BYTES, BASE_NONE,
757
14
         NULL, 0x0, NULL, HFILL
758
14
      }
759
14
    },
760
14
    { &hf_pppoed_tag_ac_cookie,
761
14
      { "AC-Cookie", "pppoed.tags.ac_cookie", FT_BYTES, BASE_NONE,
762
14
         NULL, 0x0, NULL, HFILL
763
14
      }
764
14
    },
765
14
    { &hf_pppoed_tag_vendor_id,
766
14
      { "Vendor id", "pppoed.tags.vendor_id", FT_UINT32, BASE_DEC,
767
14
         NULL, 0x0, NULL, HFILL
768
14
      }
769
14
    },
770
14
    { &hf_pppoed_tag_vendor_unspecified,
771
14
      { "Vendor unspecified", "pppoed.tags.vendor_unspecified", FT_BYTES, BASE_NONE,
772
14
         NULL, 0x0, NULL, HFILL
773
14
      }
774
14
    },
775
14
    { &hf_pppoed_tag_vspec_tags,
776
14
      { "Vendor Specific PPPoE Tags", "pppoed.tags.vendorspecific.tags", FT_NONE, BASE_NONE,
777
14
         NULL, 0x0, NULL, HFILL
778
14
      }
779
14
    },
780
14
    { &hf_pppoed_tag_vspec_tag,
781
14
      { "Tag", "pppoed.tags.vendorspecific.tag", FT_UINT8, BASE_HEX,
782
14
         VALS(vspec_tag_vals), 0x0, NULL, HFILL
783
14
      }
784
14
    },
785
14
    { &hf_pppoed_tag_vspec_circuit_id,
786
14
            { "Circuit ID", "pppoed.tags.circuit_id", FT_STRING, BASE_NONE,
787
14
                     NULL, 0x0, NULL, HFILL
788
14
            }
789
14
    },
790
14
    { &hf_pppoed_tag_vspec_remote_id,
791
14
            { "Remote ID", "pppoed.tags.remote_id", FT_STRING, BASE_NONE,
792
14
                     NULL, 0x0, NULL, HFILL
793
14
            }
794
14
    },
795
14
    { &hf_pppoed_tag_vspec_act_data_rate_up,
796
14
            { "Actual Data Rate Upstream", "pppoed.tags.act_data_rate_up", FT_UINT32, BASE_DEC,
797
14
                     NULL, 0x0, NULL, HFILL
798
14
            }
799
14
    },
800
14
    { &hf_pppoed_tag_vspec_act_data_rate_down,
801
14
            { "Actual Data Rate Downstream", "pppoed.tags.act_data_rate_down", FT_UINT32, BASE_DEC,
802
14
                     NULL, 0x0, NULL, HFILL
803
14
            }
804
14
    },
805
14
    { &hf_pppoed_tag_vspec_min_data_rate_up,
806
14
            { "Minimum Data Rate Upstream", "pppoed.tags.min_data_rate_up", FT_UINT32, BASE_DEC,
807
14
                     NULL, 0x0, NULL, HFILL
808
14
            }
809
14
    },
810
14
    { &hf_pppoed_tag_vspec_min_data_rate_down,
811
14
            { "Minimum Data Rate Downstream", "pppoed.tags.min_data_rate_down", FT_UINT32, BASE_DEC,
812
14
                     NULL, 0x0, NULL, HFILL
813
14
            }
814
14
    },
815
14
    { &hf_pppoed_tag_vspec_attainable_data_rate_up,
816
14
            { "Attainable DataRate Upstream", "pppoed.tags.attainable_data_rate_up", FT_UINT32, BASE_DEC,
817
14
                     NULL, 0x0, NULL, HFILL
818
14
            }
819
14
    },
820
14
    { &hf_pppoed_tag_vspec_attainable_data_rate_down,
821
14
            { "Attainable DataRate Downstream", "pppoed.tags.attainable_data_rate_down", FT_UINT32, BASE_DEC,
822
14
                     NULL, 0x0, NULL, HFILL
823
14
            }
824
14
    },
825
14
    { &hf_pppoed_tag_vspec_max_data_rate_up,
826
14
            { "Maximum Data Rate Upstream", "pppoed.tags.max_data_rate_up", FT_UINT32, BASE_DEC,
827
14
                     NULL, 0x0, NULL, HFILL
828
14
            }
829
14
    },
830
14
    { &hf_pppoed_tag_vspec_max_data_rate_down,
831
14
            { "Maximum Data Rate Downstream", "pppoed.tags.max_data_rate_down", FT_UINT32, BASE_DEC,
832
14
                     NULL, 0x0, NULL, HFILL
833
14
            }
834
14
    },
835
14
    { &hf_pppoed_tag_vspec_min_data_rate_up_lp,
836
14
            { "Min DataRate Upstream in low power state", "pppoed.tags.min_data_rate_up_lp", FT_UINT32, BASE_DEC,
837
14
                     NULL, 0x0, NULL, HFILL
838
14
            }
839
14
    },
840
14
    { &hf_pppoed_tag_vspec_min_data_rate_down_lp,
841
14
            { "Minimum Data Rate Downstream in low power state", "pppoed.tags.min_data_rate_down_lp", FT_UINT32, BASE_DEC,
842
14
                     NULL, 0x0, NULL, HFILL
843
14
            }
844
14
    },
845
14
    { &hf_pppoed_tag_vspec_max_int_delay_up,
846
14
            { "Max Interleaving Delay Upstream", "pppoed.tags.max_int_delay_up", FT_UINT32, BASE_DEC,
847
14
                     NULL, 0x0, NULL, HFILL
848
14
            }
849
14
    },
850
14
    { &hf_pppoed_tag_vspec_act_int_delay_up,
851
14
            { "Actual Interleaving Delay Upstream", "pppoed.tags.act_int_delay_up", FT_UINT32, BASE_DEC,
852
14
                     NULL, 0x0, NULL, HFILL
853
14
            }
854
14
    },
855
14
    { &hf_pppoed_tag_vspec_max_int_delay_down,
856
14
            { "Maximum Interleaving Delay Downstream", "pppoed.tags.max_int_delay_down", FT_UINT32, BASE_DEC,
857
14
                     NULL, 0x0, NULL, HFILL
858
14
            }
859
14
    },
860
14
    { &hf_pppoed_tag_vspec_act_int_delay_down,
861
14
            { "Actual Interleaving Delay Downstream", "pppoed.tags.act_int_delay_down", FT_UINT32, BASE_DEC,
862
14
                     NULL, 0x0, NULL, HFILL
863
14
            }
864
14
    },
865
14
    { &hf_pppoed_tag_vspec_access_loop_encapsulation,
866
14
            { "Access-Loop-Encapsulation", "pppoed.tags.access_loop_encap", FT_NONE, BASE_NONE,
867
14
                     NULL, 0x0, NULL, HFILL
868
14
            }
869
14
    },
870
14
    { &hf_pppoed_tag_vspec_access_loop_encap_data_link,
871
14
      { "Data link", "pppoed.tags.access_loop_encap.data_link", FT_UINT8, BASE_HEX,
872
14
         VALS(vspec_tag_dslf_access_loop_encap_data_link_vals), 0x0, NULL, HFILL
873
14
      }
874
14
    },
875
14
    { &hf_pppoed_tag_vspec_access_loop_encap_encap_1,
876
14
      { "Encaps 1", "pppoed.tags.access_loop_encap.encap_1", FT_UINT8, BASE_HEX,
877
14
         VALS(vspec_tag_dslf_access_loop_encap_encap_1_vals), 0x0, NULL, HFILL
878
14
      }
879
14
    },
880
14
    { &hf_pppoed_tag_vspec_access_loop_encap_encap_2,
881
14
      { "Encaps 2", "pppoed.tags.access_loop_encap.encap_2", FT_UINT8, BASE_HEX,
882
14
         VALS(vspec_tag_dslf_access_loop_encap_encap_2_vals), 0x0, NULL, HFILL
883
14
      }
884
14
    },
885
14
    { &hf_pppoed_tag_credits,
886
14
      { "Credits", "pppoed.tags.credits", FT_BYTES, BASE_NONE,
887
14
         NULL, 0x0, NULL, HFILL
888
14
      }
889
14
    },
890
14
    { &hf_pppoed_tag_credits_fcn,
891
14
      { "FCN", "pppoed.tags.credits.fcn", FT_UINT16, BASE_DEC,
892
14
         NULL, 0x0, NULL, HFILL
893
14
      }
894
14
    },
895
14
    { &hf_pppoed_tag_credits_bcn,
896
14
      { "BCN", "pppoed.tags.credits.bcn", FT_UINT16, BASE_DEC,
897
14
         NULL, 0x0, NULL, HFILL
898
14
      }
899
14
    },
900
14
    { &hf_pppoed_tag_metrics,
901
14
      { "Metrics", "pppoed.tags.metrics", FT_BYTES, BASE_NONE,
902
14
         NULL, 0x0, NULL, HFILL
903
14
      }
904
14
    },
905
14
    { &hf_pppoed_tag_metrics_r,
906
14
      { "Receive Only", "pppoed.tags.metrics.r", FT_BOOLEAN, 16,
907
14
         NULL, PPPOE_RCV_ONLY_MASK, NULL, HFILL
908
14
      }
909
14
    },
910
14
    { &hf_pppoed_tag_mdr_units,
911
14
      { "MDR Units", "pppoed.tags.metrics.mdr_units", FT_UINT16, BASE_HEX,
912
14
         VALS(datarate_scale_vals), PPPOE_MDR_MASK, NULL, HFILL
913
14
      }
914
14
    },
915
14
    { &hf_pppoed_tag_cdr_units,
916
14
      { "CDR Units", "pppoed.tags.metrics.cdr_units", FT_UINT16, BASE_HEX,
917
14
         VALS(datarate_scale_vals), PPPOE_CDR_MASK, NULL, HFILL
918
14
      }
919
14
    },
920
14
    { &hf_pppoed_tag_metrics_rlq,
921
14
      { "Relative Link Quality", "pppoed.tags.metrics.rlq", FT_UINT8, BASE_DEC,
922
14
         NULL, 0x0, NULL, HFILL
923
14
      }
924
14
    },
925
14
    { &hf_pppoed_tag_metrics_resource,
926
14
      { "Resource", "pppoed.tags.metrics.resource", FT_UINT8, BASE_DEC,
927
14
         NULL, 0x0, NULL, HFILL
928
14
      }
929
14
    },
930
14
    { &hf_pppoed_tag_metrics_latency,
931
14
      { "Latency", "pppoed.tags.metrics.latency", FT_UINT16, BASE_DEC,
932
14
         NULL, 0x0, NULL, HFILL
933
14
      }
934
14
    },
935
14
    { &hf_pppoed_tag_metrics_curr_drate,
936
14
      { "Curr. datarate", "pppoed.tags.metrics.curr_drate", FT_UINT16, BASE_DEC,
937
14
         NULL, 0x0, NULL, HFILL
938
14
      }
939
14
    },
940
14
    { &hf_pppoed_tag_metrics_max_drate,
941
14
      { "Max. datarate", "pppoed.tags.metrics.max_drate", FT_UINT16, BASE_DEC,
942
14
         NULL, 0x0, NULL, HFILL
943
14
      }
944
14
    },
945
14
    { &hf_pppoed_tag_seq_num,
946
14
      { "Sequence Number", "pppoed.tags.seq_num", FT_UINT16, BASE_HEX,
947
14
         NULL, 0x0, NULL, HFILL
948
14
      }
949
14
    },
950
14
    { &hf_pppoed_tag_cred_scale,
951
14
      { "Credit Scale Factor", "pppoed.tags.credit_scale", FT_UINT16, BASE_DEC,
952
14
         NULL, 0x0, NULL, HFILL
953
14
      }
954
14
    },
955
14
    { &hf_pppoed_tag_relay_session_id,
956
14
      { "Relay-Session-Id", "pppoed.tags.relay_session_id", FT_BYTES, BASE_NONE,
957
14
         NULL, 0x0, NULL, HFILL
958
14
      }
959
14
    },
960
14
    { &hf_pppoed_tag_hurl,
961
14
      { "HURL", "pppoed.tags.hurl", FT_BYTES, BASE_NONE,
962
14
         NULL, 0x0, NULL, HFILL
963
14
      }
964
14
    },
965
14
    { &hf_pppoed_tag_motm,
966
14
      { "MOTM", "pppoed.tags.motm", FT_BYTES, BASE_NONE,
967
14
         NULL, 0x0, NULL, HFILL
968
14
      }
969
14
    },
970
14
    { &hf_pppoed_tag_max_payload,
971
14
      { "PPP-Max-Payload", "pppoed.tags.max_payload", FT_BYTES, BASE_NONE,
972
14
         NULL, 0x0, NULL, HFILL
973
14
      }
974
14
    },
975
14
    { &hf_pppoed_tag_ip_route_add,
976
14
      { "IP Route Add", "pppoed.tags.ip_route_add", FT_BYTES, BASE_NONE,
977
14
         NULL, 0x0, NULL, HFILL
978
14
      }
979
14
    },
980
14
    { &hf_pppoed_tag_service_name_error,
981
14
      { "Service-Name-Error", "pppoed.tags.service_name_error", FT_STRING, BASE_NONE,
982
14
         NULL, 0x0, NULL, HFILL
983
14
      }
984
14
    },
985
14
    { &hf_pppoed_tag_ac_system_error,
986
14
      { "AC-System-Error", "pppoed.tags.ac_system_error", FT_STRING, BASE_NONE,
987
14
         NULL, 0x0, NULL, HFILL
988
14
      }
989
14
    },
990
14
    { &hf_pppoed_tag_generic_error,
991
14
      { "Generic-Error", "pppoed.tags.generic_error", FT_STRING, BASE_NONE,
992
14
         NULL, 0x0, NULL, HFILL
993
14
      }
994
14
    }
995
14
  };
996
997
14
  static int *ett[] = {
998
14
    &ett_pppoed,
999
14
    &ett_pppoed_tags,
1000
14
    &ett_pppoed_tag_vspec_dslf_access_loop_encaps
1001
14
  };
1002
1003
14
  module_t *pppoed_module;
1004
1005
  /* Register protocol and fields */
1006
14
  proto_pppoed = proto_register_protocol("PPP-over-Ethernet Discovery",
1007
14
                                         "PPPoED", "pppoed");
1008
14
  proto_register_subtree_array(ett, array_length(ett));
1009
14
  proto_register_field_array(proto_pppoed, hf, array_length(hf));
1010
1011
  /* Register dissector handle */
1012
14
  pppoed_handle = register_dissector("pppoed", dissect_pppoed, proto_pppoed);
1013
1014
  /* Preference setting */
1015
14
  pppoed_module = prefs_register_protocol(proto_pppoed, NULL);
1016
14
  prefs_register_bool_preference(pppoed_module, "show_tags_and_lengths",
1017
14
                                 "Show tag values and lengths",
1018
14
                                 "Show values of tags and lengths of data fields",
1019
14
                                 &global_pppoe_show_tags_and_lengths);
1020
14
}
1021
1022
void proto_reg_handoff_pppoed(void)
1023
14
{
1024
14
  dissector_add_uint("ethertype", ETHERTYPE_PPPOED, pppoed_handle);
1025
14
}
1026
1027
1028
/* Session protocol, i.e. PPP session established */
1029
static int dissect_pppoes(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1030
42
{
1031
42
  uint8_t pppoe_code;
1032
42
  uint16_t reported_payload_length;
1033
42
  uint16_t poe_tag_length;
1034
42
  int     actual_payload_length;
1035
42
  int     length, reported_length;
1036
42
  int     credit_offset = 0, tagstart = 0;
1037
42
  uint16_t cp_code;
1038
1039
42
  proto_tree  *pppoe_tree;
1040
42
  proto_item  *ti = NULL;
1041
42
  tvbuff_t    *next_tvb;
1042
1043
42
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPPoES");
1044
42
  col_clear(pinfo->cinfo, COL_INFO);
1045
1046
  /* Start Decoding Here. */
1047
42
  pppoe_code = tvb_get_uint8(tvb, 1);
1048
1049
42
  col_set_str(pinfo->cinfo, COL_INFO,
1050
42
                 val_to_str_const(pppoe_code, code_vals, "Unknown"));
1051
1052
42
  reported_payload_length = tvb_get_ntohs(tvb, 4);
1053
42
  actual_payload_length = tvb_reported_length_remaining(tvb, 6);
1054
1055
42
  ti = proto_tree_add_item(tree, proto_pppoes, tvb, 0, 6, ENC_NA);
1056
42
  pppoe_tree = proto_item_add_subtree(ti, ett_pppoe);
1057
1058
42
  proto_tree_add_item(pppoe_tree, hf_pppoe_version, tvb, 0, 1, ENC_BIG_ENDIAN);
1059
42
  proto_tree_add_item(pppoe_tree, hf_pppoe_type, tvb, 0, 1, ENC_BIG_ENDIAN);
1060
42
  proto_tree_add_item(pppoe_tree, hf_pppoe_code, tvb, 1, 1, ENC_BIG_ENDIAN);
1061
42
  proto_tree_add_item(pppoe_tree, hf_pppoe_session_id, tvb, 2, 2, ENC_BIG_ENDIAN);
1062
42
  ti = proto_tree_add_item(pppoe_tree, hf_pppoe_payload_length, tvb, 4, 2, ENC_BIG_ENDIAN);
1063
1064
1065
42
  if (PPPOE_TAG_CREDITS == tvb_get_ntohs(tvb, 6))
1066
0
  {
1067
0
    tagstart = 6;
1068
0
    poe_tag_length = tvb_get_ntohs(tvb, tagstart + 2);
1069
1070
    /* Create tags subtree */
1071
0
    ti = proto_tree_add_item(pppoe_tree, hf_pppoes_tags, tvb, tagstart, 8, ENC_NA);
1072
0
    pppoe_tree = proto_item_add_subtree(ti, ett_pppoes_tags);
1073
1074
    /* Show tag data */
1075
0
    if (poe_tag_length == 4)
1076
0
    {
1077
0
      proto_tree_add_item(pppoe_tree, hf_pppoes_tag_credits_fcn, tvb,
1078
0
        tagstart+4, 2, ENC_BIG_ENDIAN);
1079
0
      proto_tree_add_item(pppoe_tree, hf_pppoes_tag_credits_bcn, tvb,
1080
0
        tagstart+6, 2, ENC_BIG_ENDIAN);
1081
0
    } else {
1082
0
      proto_tree_add_item(pppoe_tree, hf_pppoed_tag_credits, tvb,
1083
0
        tagstart+4, poe_tag_length, ENC_NA);
1084
0
    }
1085
1086
0
    credit_offset = 8;
1087
0
  }
1088
1089
  /*
1090
   * The only reason why the payload length from the header
1091
   * should differ from the remaining data in the packet
1092
   * would be if the total packet length, including Ethernet
1093
   * CRC, were < 64 bytes, so that padding was required.
1094
   *
1095
   * That means that you have 14 bytes of Ethernet header,
1096
   * 4 bytes of FCS, and fewer than 46 bytes of PPPoE packet.
1097
   *
1098
   * If that's not the case, we report a difference between
1099
   * the payload length in the packet, and the amount of
1100
   * data following the PPPoE header, as an error.
1101
   */
1102
42
  if (tvb_reported_length(tvb) > 46) {
1103
    /*
1104
     * Be forgiving about a possible trailing FCS.
1105
     *
1106
     * XXX - this dissector currently doesn't know
1107
     * whether any extra data past the end of the PPP
1108
     * payload is an FCS or not.
1109
     *
1110
     * If we know that we have an FCS, or that we don't
1111
     * have an FCS, we should have been handed a tvbuff
1112
     * without the FCS, and we should just do the strict
1113
     * length check.
1114
     *
1115
     * If we don't know whether we have an FCS, then:
1116
     *
1117
     *   if this isn't over Ethernet - the "E" in "PPPoE"
1118
     *   nonwithstanding, it can also run on top of 802.11,
1119
     *   for example - there's no trailer, so any data
1120
     *   past the payload length is either an FCS or
1121
     *   bogus;
1122
     *
1123
     *   if this is over Ethernet, there shouldn't be
1124
     *   a trailer, as the packet is long enough not to
1125
     *   require a trailer, as per the above;
1126
     *
1127
     * so perhaps we should assume that if we have exactly
1128
     * 4 bytes of extra information, it's an FCS, otherwise
1129
     * it's not.
1130
     *
1131
     * Perhaps we need to have a routine to call to
1132
     * do all the length checking, etc., and call it
1133
     * from here and from other dissectors where the
1134
     * protocol has a length field, or have a way to
1135
     * tell the dissector that called us which field
1136
     * has the length field and have *that* dissector
1137
     * do the length checking and add the expert info
1138
     * to the length field, *after* it does all the
1139
     * FCS heuristics.
1140
     */
1141
1142
    /* retrieve the control protocol code if it's there */
1143
23
    cp_code = tvb_get_ntohs(tvb, 6);
1144
    /*
1145
     * The session payload length expressly does not include pad bytes
1146
     * when LCP or IPCP or IPv6CP are present, so avoid the spurious error message
1147
     */
1148
23
    if ((cp_code != PPP_LCP) && (cp_code != PPP_IPCP) && (cp_code != PPP_IPV6CP) &&
1149
23
      (reported_payload_length != actual_payload_length) &&
1150
23
      ((reported_payload_length + 4) != actual_payload_length)) {
1151
23
      proto_item_append_text(ti, " [incorrect, should be %u]",
1152
23
        actual_payload_length);
1153
23
      expert_add_info_format(pinfo, ti, &ei_pppoe_payload_length, "Possible bad payload length %u != %u", reported_payload_length, actual_payload_length);
1154
23
    }
1155
23
  }
1156
1157
  /*
1158
   * Construct a tvbuff containing the PPP packet.
1159
   */
1160
42
  length = tvb_captured_length_remaining(tvb, 6);
1161
42
  reported_length = tvb_reported_length_remaining(tvb, 6);
1162
42
  DISSECTOR_ASSERT(length >= 0);
1163
42
  DISSECTOR_ASSERT(reported_length >= 0);
1164
42
  if (length > reported_length)
1165
0
    length = reported_length;
1166
42
  if ((unsigned)length > reported_payload_length)
1167
9
    length = reported_payload_length;
1168
42
  if ((unsigned)reported_length > reported_payload_length)
1169
9
    reported_length = reported_payload_length;
1170
42
  next_tvb = tvb_new_subset_length_caplen(tvb,(6 + credit_offset),
1171
42
        (length - credit_offset),
1172
42
        (reported_length - credit_offset));
1173
42
  call_dissector(ppp_handle,next_tvb,pinfo,tree);
1174
42
  return tvb_captured_length(tvb);
1175
42
}
1176
1177
void proto_register_pppoes(void)
1178
14
{
1179
1180
14
  static hf_register_info hf[] =
1181
14
  {
1182
14
    { &hf_pppoes_tags,
1183
14
      { "PPPoE Tags", "pppoes.tags", FT_NONE, BASE_NONE,
1184
14
         NULL, 0x0, NULL, HFILL
1185
14
      }
1186
14
    },
1187
#if 0
1188
    { &hf_pppoes_tag,
1189
      { "Tag", "pppoes.tag", FT_UINT16, BASE_HEX,
1190
         VALS(tag_vals), 0x0, NULL, HFILL
1191
      }
1192
    },
1193
#endif
1194
#if 0
1195
    { &hf_pppoes_tag_credits,
1196
      { "Credits", "pppoes.tags.credits", FT_BYTES, BASE_NONE,
1197
         NULL, 0x0, NULL, HFILL
1198
      }
1199
    },
1200
#endif
1201
14
    { &hf_pppoes_tag_credits_fcn,
1202
14
      { "FCN", "pppoes.tags.credits.fcn", FT_UINT16, BASE_DEC,
1203
14
         NULL, 0x0, NULL, HFILL
1204
14
      }
1205
14
    },
1206
14
    { &hf_pppoes_tag_credits_bcn,
1207
14
      { "BCN", "pppoes.tags.credits.bcn", FT_UINT16, BASE_DEC,
1208
14
         NULL, 0x0, NULL, HFILL
1209
14
      }
1210
14
    }
1211
14
  };
1212
1213
14
  static int *ett[] = {
1214
14
    &ett_pppoes,
1215
14
    &ett_pppoes_tags
1216
14
  };
1217
1218
  /* Register protocol */
1219
14
  proto_pppoes = proto_register_protocol("PPP-over-Ethernet Session", "PPPoES", "pppoes");
1220
1221
14
  proto_register_subtree_array(ett, array_length(ett));
1222
14
  proto_register_field_array(proto_pppoes, hf, array_length(hf));
1223
1224
14
  pppoes_handle = register_dissector("pppoes", dissect_pppoes, proto_pppoes);
1225
14
}
1226
1227
void proto_register_pppoe(void)
1228
14
{
1229
14
  static hf_register_info hf[] =
1230
14
  {
1231
    /* These fields common to discovery and session protocols */
1232
14
    { &hf_pppoe_version,
1233
14
      { "Version", "pppoe.version", FT_UINT8, BASE_DEC,
1234
14
         NULL, 0xf0, NULL, HFILL
1235
14
      }
1236
14
    },
1237
14
    { &hf_pppoe_type,
1238
14
      { "Type", "pppoe.type", FT_UINT8, BASE_DEC,
1239
14
         NULL, 0x0f, NULL, HFILL
1240
14
      }
1241
14
    },
1242
14
    { &hf_pppoe_code,
1243
14
      { "Code", "pppoe.code", FT_UINT8, BASE_HEX,
1244
14
         VALS(code_vals), 0x0, NULL, HFILL
1245
14
      }
1246
14
    },
1247
14
    { &hf_pppoe_session_id,
1248
14
      { "Session ID", "pppoe.session_id", FT_UINT16, BASE_HEX,
1249
14
         NULL, 0x0, NULL, HFILL
1250
14
      }
1251
14
    },
1252
14
    { &hf_pppoe_payload_length,
1253
14
      { "Payload Length", "pppoe.payload_length", FT_UINT16, BASE_DEC,
1254
14
         NULL, 0x0, NULL, HFILL
1255
14
      }
1256
14
    }
1257
14
  };
1258
1259
14
  static int *ett[] = {
1260
14
    &ett_pppoe
1261
14
  };
1262
1263
14
  static ei_register_info ei[] = {
1264
14
    { &ei_pppoe_tag_length, { "pppoed.tag_length.invalid", PI_MALFORMED, PI_WARN, "Wrong length", EXPFILL }},
1265
14
    { &ei_pppoe_payload_length, { "pppoe.payload_length.bad", PI_MALFORMED, PI_WARN, "Possible bad payload length", EXPFILL }},
1266
14
  };
1267
1268
14
  expert_module_t* expert_pppoe;
1269
1270
  /* Register protocol */
1271
14
  proto_pppoe = proto_register_protocol("PPP-over-Ethernet", "PPPoE", "pppoe");
1272
1273
14
  proto_register_subtree_array(ett, array_length(ett));
1274
14
  proto_register_field_array(proto_pppoe, hf, array_length(hf));
1275
14
  expert_pppoe = expert_register_protocol(proto_pppoe);
1276
14
  expert_register_field_array(expert_pppoe, ei, array_length(ei));
1277
1278
14
}
1279
1280
void proto_reg_handoff_pppoes(void)
1281
14
{
1282
14
  dissector_add_uint("ethertype", ETHERTYPE_PPPOES, pppoes_handle);
1283
14
  dissector_add_uint("wtap_encap", WTAP_ENCAP_PPP_ETHER, pppoes_handle);
1284
1285
  /* Get a handle for the PPP dissector */
1286
14
  ppp_handle = find_dissector_add_dependency("ppp", proto_pppoes);
1287
14
}
1288
1289
/*
1290
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
1291
 *
1292
 * Local variables:
1293
 * c-basic-offset: 8
1294
 * tab-width: 8
1295
 * indent-tabs-mode: t
1296
 * End:
1297
 *
1298
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1299
 * :indentSize=8:tabSize=8:noTabs=false:
1300
 */