1 /* packet-ppp.c
2 * Routines for ppp packet disassembly
3 * RFC 1661, RFC 1662
4 *
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 *
8 * This file created and by Mike Hall <mlh@io.com>
9 * Copyright 1998
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
14 #include "config.h"
15
16 #include <epan/packet.h>
17 #include <epan/capture_dissectors.h>
18 #include <wsutil/pint.h>
19 #include <wsutil/str_util.h>
20 #include <epan/prefs.h>
21 #include "packet-ppp.h"
22 #include <epan/ppptypes.h>
23 #include <epan/etypes.h>
24 #include <epan/expert.h>
25 #include <epan/ip_opts.h>
26 #include "packet-chdlc.h"
27 #include "packet-ip.h"
28 #include "packet-ipx.h"
29 #include <epan/nlpid.h>
30 #include <epan/crc16-tvb.h>
31 #include <epan/crc32-tvb.h>
32 #include <epan/ipproto.h>
33 #include <epan/addr_resolv.h>
34 #include <epan/reassemble.h>
35 #include "packet-sll.h"
36 #include "packet-juniper.h"
37 #include "packet-sflow.h"
38 #include "packet-l2tp.h"
39
40 void proto_register_ppp_raw_hdlc(void);
41 void proto_reg_handoff_ppp_raw_hdlc(void);
42 void proto_register_ppp(void);
43 void proto_reg_handoff_ppp(void);
44 void proto_register_mp(void);
45 void proto_reg_handoff_mp(void);
46 void proto_register_lcp(void);
47 void proto_reg_handoff_lcp(void);
48 void proto_register_vsncp(void);
49 void proto_reg_handoff_vsncp(void);
50 void proto_register_vsnp(void);
51 void proto_reg_handoff_vsnp(void);
52 void proto_register_ipcp(void);
53 void proto_reg_handoff_ipcp(void);
54 void proto_register_bcp_bpdu(void);
55 void proto_reg_handoff_bcp_bpdu(void);
56 void proto_register_bcp_ncp(void);
57 void proto_reg_handoff_bcp_ncp(void);
58 void proto_register_osinlcp(void);
59 void proto_reg_handoff_bcp(void);
60 void proto_reg_handoff_osinlcp(void);
61 void proto_register_ccp(void);
62 void proto_reg_handoff_ccp(void);
63 void proto_register_cbcp(void);
64 void proto_reg_handoff_cbcp(void);
65 void proto_register_bacp(void);
66 void proto_reg_handoff_bacp(void);
67 void proto_register_bap(void);
68 void proto_reg_handoff_bap(void);
69 void proto_register_comp_data(void);
70 void proto_reg_handoff_comp_data(void);
71 void proto_register_pap(void);
72 void proto_reg_handoff_pap(void);
73 void proto_register_chap(void);
74 void proto_reg_handoff_chap(void);
75 void proto_register_pppmuxcp(void);
76 void proto_reg_handoff_pppmuxcp(void);
77 void proto_register_pppmux(void);
78 void proto_reg_handoff_pppmux(void);
79 void proto_register_mplscp(void);
80 void proto_reg_handoff_mplscp(void);
81 void proto_register_cdpcp(void);
82 void proto_reg_handoff_cdpcp(void);
83 void proto_register_ipv6cp(void);
84 void proto_reg_handoff_ipv6cp(void);
85 void proto_register_iphc_crtp(void);
86 void proto_reg_handoff_iphc_crtp(void);
87
88
89 static int proto_ppp = -1;
90 static int hf_ppp_direction = -1;
91 static int hf_ppp_address = -1;
92 static int hf_ppp_control = -1;
93 static int hf_ppp_protocol = -1;
94 static int hf_ppp_code = -1;
95 static int hf_ppp_identifier = -1;
96 static int hf_ppp_length = -1;
97 static int hf_ppp_magic_number = -1;
98 static int hf_ppp_oui = -1;
99 static int hf_ppp_kind = -1;
100 static int hf_ppp_data = -1;
101 static int hf_ppp_fcs_16 = -1;
102 static int hf_ppp_fcs_32 = -1;
103 static int hf_ppp_fcs_status = -1;
104
105 static gint ett_ppp = -1;
106 static gint ett_ppp_opt_type = -1;
107 static gint ett_ppp_unknown_opt = -1;
108
109 static expert_field ei_ppp_opt_len_invalid = EI_INIT;
110 static expert_field ei_ppp_fcs = EI_INIT;
111
112 static int proto_ppp_hdlc = -1;
113
114 /* Generated from convert_proto_tree_add_text.pl */
115 static int hf_ppp_hdlc_data = -1;
116 static int hf_ppp_hdlc_fragment = -1;
117
118 static gint ett_ppp_hdlc_data = -1;
119
120 static int proto_lcp = -1;
121 static int proto_lcp_option_vendor = -1;
122 static int proto_lcp_option_mru = -1;
123 static int proto_lcp_option_async_map = -1;
124 static int proto_lcp_option_authprot = -1;
125 static int proto_lcp_option_qualprot = -1;
126 static int proto_lcp_option_magicnumber = -1;
127 static int proto_lcp_option_linkqualmon = -1;
128 static int proto_lcp_option_field_compress = -1;
129 static int proto_lcp_option_addr_field_compress = -1;
130 static int proto_lcp_option_fcs_alternatives = -1;
131 static int proto_lcp_option_self_desc_pad = -1;
132 static int proto_lcp_option_numbered_mode = -1;
133 static int proto_lcp_option_callback = -1;
134 static int proto_lcp_option_compound_frames = -1;
135 static int proto_lcp_option_nomdataencap = -1;
136 static int proto_lcp_option_multilink_mrru = -1;
137 static int proto_lcp_option_multilink_ssnh = -1;
138 static int proto_lcp_option_multilink_ep_disc = -1;
139 static int proto_lcp_option_dce_identifier = -1;
140 static int proto_lcp_option_multilink_pp = -1;
141 static int proto_lcp_option_link_discrim = -1;
142 static int proto_lcp_option_auth = -1;
143 static int proto_lcp_option_cobs = -1;
144 static int proto_lcp_option_prefix_elision = -1;
145 static int proto_lcp_option_multilink_hdr_fmt = -1;
146 static int proto_lcp_option_internationalization = -1;
147 static int proto_lcp_option_sonet_sdh = -1;
148
149 static gint ett_lcp = -1;
150 static gint ett_lcp_options = -1;
151 static gint ett_lcp_vendor_opt = -1;
152 static gint ett_lcp_mru_opt = -1;
153 static gint ett_lcp_asyncmap_opt = -1;
154 static gint ett_lcp_authprot_opt = -1;
155 static gint ett_lcp_qualprot_opt = -1;
156 static gint ett_lcp_magicnumber_opt = -1;
157 static gint ett_lcp_linkqualmon_opt = -1;
158 static gint ett_lcp_pcomp_opt = -1;
159 static gint ett_lcp_acccomp_opt = -1;
160 static gint ett_lcp_fcs_alternatives_opt = -1;
161 static gint ett_lcp_self_desc_pad_opt = -1;
162 static gint ett_lcp_numbered_mode_opt = -1;
163 static gint ett_lcp_callback_opt = -1;
164 static gint ett_lcp_compound_frames_opt = -1;
165 static gint ett_lcp_nomdataencap_opt = -1;
166 static gint ett_lcp_multilink_mrru_opt = -1;
167 static gint ett_lcp_multilink_ssnh_opt = -1;
168 static gint ett_lcp_multilink_ep_disc_opt = -1;
169 static gint ett_lcp_magic_block = -1;
170 static gint ett_lcp_dce_identifier_opt = -1;
171 static gint ett_lcp_multilink_pp_opt = -1;
172 static gint ett_lcp_bacp_link_discrim_opt = -1;
173 static gint ett_lcp_auth_opt = -1;
174 static gint ett_lcp_cobs_opt = -1;
175 static gint ett_lcp_prefix_elision_opt = -1;
176 static gint ett_multilink_hdr_fmt_opt = -1;
177 static gint ett_lcp_internationalization_opt = -1;
178 static gint ett_lcp_sonet_sdh_opt = -1;
179
180 static dissector_table_t lcp_option_table;
181
182 static int proto_ipcp = -1;
183 static int proto_ipcp_option_addrs = -1;
184 static int proto_ipcp_option_compress = -1;
185 static int proto_ipcp_option_addr = -1;
186 static int proto_ipcp_option_mobileipv4 = -1;
187 static int proto_ipcp_option_pri_dns = -1;
188 static int proto_ipcp_option_pri_nbns = -1;
189 static int proto_ipcp_option_sec_dns = -1;
190 static int proto_ipcp_option_sec_nbns = -1;
191 static int proto_ipcp_rohc_option_profiles = -1;
192 static int proto_ipcp_iphc_option_rtp_compress = -1;
193 static int proto_ipcp_iphc_option_enhanced_rtp_compress = -1;
194 static int proto_ipcp_iphc_option_neghdrcomp = -1;
195
196 static gint ett_ipcp = -1;
197 static gint ett_ipcp_options = -1;
198 static gint ett_ipcp_ipaddrs_opt = -1;
199 static gint ett_ipcp_compress_opt = -1;
200 static gint ett_ipcp_ipaddr_opt = -1;
201 static gint ett_ipcp_mobileipv4_opt = -1;
202 static gint ett_ipcp_pridns_opt = -1;
203 static gint ett_ipcp_secdns_opt = -1;
204 static gint ett_ipcp_prinbns_opt = -1;
205 static gint ett_ipcp_secnbns_opt = -1;
206
207 static gint ett_ipcp_iphc_rtp_compress_opt = -1;
208 static gint ett_ipcp_iphc_enhanced_rtp_compress_opt = -1;
209 static gint ett_ipcp_iphc_neghdrcomp_opt = -1;
210 static gint ett_ipcp_rohc_profiles_opt = -1;
211
212 static dissector_table_t ipcp_option_table;
213 static dissector_table_t ipcp_rohc_suboption_table;
214 static dissector_table_t ipcp_iphc_suboption_table;
215
216 static int proto_vsncp = -1;
217 static int proto_vsncp_option_pdnid = -1;
218 static int proto_vsncp_option_apname = -1;
219 static int proto_vsncp_option_pdntype = -1;
220 static int proto_vsncp_option_pdnaddress = -1;
221 static int proto_vsncp_option_pco = -1;
222 static int proto_vsncp_option_errorcode = -1;
223 static int proto_vsncp_option_attachtype = -1;
224 static int proto_vsncp_option_ipv4address = -1;
225 static int proto_vsncp_option_addressalloc = -1;
226 static int proto_vsncp_option_apn_ambr = -1;
227 static int proto_vsncp_option_ipv6_hsgw_lla_iid = -1;
228
229 static int hf_vsncp_opt_type = -1;
230 static int hf_vsncp_opt_length = -1;
231 /* Generated from convert_proto_tree_add_text.pl */
232 static int hf_vsncp_protocol_configuration_length = -1;
233 static int hf_vsncp_error_code = -1;
234 static int hf_vsncp_identifier = -1;
235 static int hf_vsncp_attach_type = -1;
236 static int hf_vsncp_protocol_configuration_data = -1;
237 static int hf_vsncp_default_router_address = -1;
238 static int hf_vsncp_pdn_identifier = -1;
239 static int hf_vsncp_address_allocation_cause = -1;
240 static int hf_vsncp_length = -1;
241 static int hf_vsncp_code = -1;
242 static int hf_vsncp_protocol = -1;
243 static int hf_vsncp_pdn_type = -1;
244 static int hf_vsncp_ipv6_interface_identifier = -1;
245 static int hf_vsncp_pdn_ipv4 = -1;
246 static int hf_vsncp_access_point_name = -1;
247 static int hf_vsncp_ambr_data = -1;
248 static int hf_vsncp_pdn_ipv6 = -1;
249
250 static gint ett_vsncp = -1;
251 static gint ett_vsncp_options = -1;
252 static gint ett_vsncp_pdnid_opt = -1;
253 static gint ett_vsncp_apname_opt = -1;
254 static gint ett_vsncp_pdntype_opt = -1;
255 static gint ett_vsncp_pdnaddress_opt = -1;
256 static gint ett_vsncp_pco_opt = -1;
257 static gint ett_vsncp_errorcode_opt = -1;
258 static gint ett_vsncp_attachtype_opt = -1;
259 static gint ett_vsncp_ipv4address_opt = -1;
260 static gint ett_vsncp_addressalloc_opt = -1;
261 static gint ett_vsncp_apn_ambr_opt = -1;
262 static gint ett_vsncp_ipv6_hsgw_lla_iid_opt = -1;
263
264 static dissector_table_t vsncp_option_table;
265
266 static int proto_vsnp = -1;
267 static gint hf_vsnp_pdnid = -1;
268
269 static gint ett_vsnp =-1;
270
271 static int proto_osinlcp = -1;
272 static int proto_osinlcp_option_align_npdu = -1;
273
274 static gint ett_osinlcp = -1;
275 static gint ett_osinlcp_options = -1;
276 static gint ett_osinlcp_align_npdu_opt = -1;
277
278 static dissector_table_t osinlcp_option_table;
279
280 static int proto_bcp_bpdu = -1;
281 static int hf_bcp_bpdu_flags = -1;
282 static int hf_bcp_bpdu_fcs_present = -1;
283 static int hf_bcp_bpdu_zeropad = -1;
284 static int hf_bcp_bpdu_bcontrol = -1;
285 static int hf_bcp_bpdu_pads = -1;
286 static int hf_bcp_bpdu_mac_type = -1;
287 static int hf_bcp_bpdu_pad = -1;
288
289 static gint ett_bcp_bpdu = -1;
290 static gint ett_bcp_bpdu_flags = -1;
291
292 static int proto_bcp_ncp = -1;
293 static int proto_bcp_ncp_option_bridge_id = -1;
294 static int proto_bcp_ncp_option_line_id = -1;
295 static int proto_bcp_ncp_option_mac_sup = -1;
296 static int proto_bcp_ncp_option_tinygram_comp = -1;
297 static int proto_bcp_ncp_option_lan_id = -1;
298 static int proto_bcp_ncp_option_mac_addr = -1;
299 static int proto_bcp_ncp_option_stp = -1;
300 static int proto_bcp_ncp_option_ieee_802_tagged_frame = -1;
301 static int proto_bcp_ncp_option_management_inline = -1;
302 static int proto_bcp_ncp_option_bcp_ind = -1;
303
304 static int hf_bcp_ncp_opt_type = -1;
305 static int hf_bcp_ncp_opt_length = -1;
306 static int hf_bcp_ncp_lan_seg_no = -1;
307 static int hf_bcp_ncp_bridge_no = -1;
308 static int hf_bcp_ncp_tinygram_comp = -1;
309 static int hf_bcp_ncp_mac = -1;
310 static int hf_bcp_ncp_mac_l = -1;
311 static int hf_bcp_ncp_mac_m = -1;
312 static int hf_bcp_ncp_stp_prot = -1;
313 static int hf_bcp_ncp_ieee_802_tagged_frame = -1;
314
315 static gint ett_bcp_ncp = -1;
316 static gint ett_bcp_ncp_options = -1;
317 static gint ett_bcp_ncp_ieee_802_tagged_frame_opt = -1;
318 static gint ett_bcp_ncp_management_inline_opt = -1;
319 static gint ett_bcp_ncp_bcp_ind_opt = -1;
320 static gint ett_bcp_ncp_bridge_id_opt = -1;
321 static gint ett_bcp_ncp_line_id_opt = -1;
322 static gint ett_bcp_ncp_mac_sup_opt = -1;
323 static gint ett_bcp_ncp_tinygram_comp_opt = -1;
324 static gint ett_bcp_ncp_lan_id_opt = -1;
325 static gint ett_bcp_ncp_mac_addr_opt = -1;
326 static gint ett_bcp_ncp_stp_opt = -1;
327
328 static dissector_table_t bcp_ncp_option_table;
329
330 static int proto_ccp = -1;
331 static int proto_ccp_option_oui = -1;
332 static int proto_ccp_option_predict1 = -1;
333 static int proto_ccp_option_predict2 = -1;
334 static int proto_ccp_option_puddle = -1;
335 static int proto_ccp_option_hpppc = -1;
336 static int proto_ccp_option_stac = -1;
337 static int proto_ccp_option_stac_ascend = -1;
338 static int proto_ccp_option_mppe = -1;
339 static int proto_ccp_option_gfza = -1;
340 static int proto_ccp_option_v42bis = -1;
341 static int proto_ccp_option_bsdcomp = -1;
342 static int proto_ccp_option_lzsdcp = -1;
343 static int proto_ccp_option_mvrca = -1;
344 static int proto_ccp_option_dce = -1;
345 static int proto_ccp_option_deflate = -1;
346 static int proto_ccp_option_v44lzjh = -1;
347
348 static gint ett_ccp = -1;
349 static gint ett_ccp_options = -1;
350 static gint ett_ccp_oui_opt = -1;
351 static gint ett_ccp_predict1_opt = -1;
352 static gint ett_ccp_predict2_opt = -1;
353 static gint ett_ccp_puddle_opt = -1;
354 static gint ett_ccp_hpppc_opt = -1;
355 static gint ett_ccp_stac_opt = -1;
356 static gint ett_ccp_stac_opt_check_mode = -1;
357 static gint ett_ccp_mppe_opt = -1;
358 static gint ett_ccp_mppe_opt_supp_bits = -1;
359 static gint ett_ccp_gfza_opt = -1;
360 static gint ett_ccp_v42bis_opt = -1;
361 static gint ett_ccp_bsdcomp_opt = -1;
362 static gint ett_ccp_lzsdcp_opt = -1;
363 static gint ett_ccp_mvrca_opt = -1;
364 static gint ett_ccp_dce_opt = -1;
365 static gint ett_ccp_deflate_opt = -1;
366 static gint ett_ccp_v44lzjh_opt = -1;
367
368 static dissector_table_t ccp_option_table;
369
370 static int proto_cbcp = -1;
371 static int proto_cbcp_option_no_callback = -1;
372 static int proto_cbcp_option_callback_user = -1;
373 static int proto_cbcp_option_callback_admin = -1;
374 static int proto_cbcp_option_callback_list = -1;
375
376 static int hf_cbcp_opt_type = -1;
377 static int hf_cbcp_opt_length = -1;
378 /* Generated from convert_proto_tree_add_text.pl */
379 static int hf_cbcp_address_type = -1;
380 static int hf_cbcp_address = -1;
381 static int hf_cbcp_callback_delay = -1;
382 static int hf_cbcp_no_callback = -1;
383
384 static gint ett_cbcp = -1;
385 static gint ett_cbcp_options = -1;
386 static gint ett_cbcp_callback_opt = -1;
387 static gint ett_cbcp_callback_opt_addr = -1;
388 static gint ett_cbcp_no_callback = -1;
389 static gint ett_cbcp_callback_user = -1;
390 static gint ett_cbcp_callback_admin = -1;
391 static gint ett_cbcp_callback_list = -1;
392
393 static expert_field ei_cbcp_address = EI_INIT;
394
395 static dissector_table_t cbcp_option_table;
396
397 static int proto_bacp = -1;
398 static int proto_bacp_option_favored_peer = -1;
399
400 static int hf_bacp_opt_type = -1;
401 static int hf_bacp_opt_length = -1;
402 /* Generated from convert_proto_tree_add_text.pl */
403 static int hf_bacp_link_speed = -1;
404 static int hf_bacp_magic_number = -1;
405 static int hf_bacp_link_type = -1;
406
407 static gint ett_bacp = -1;
408 static gint ett_bacp_options = -1;
409 static gint ett_bacp_favored_peer_opt = -1;
410
411 static dissector_table_t bacp_option_table;
412
413 static int proto_bap = -1;
414 static int proto_bap_option_link_type = -1;
415 static int proto_bap_option_phone_delta = -1;
416 static int proto_bap_option_no_phone = -1;
417 static int proto_bap_option_reason = -1;
418 static int proto_bap_option_link_disc = -1;
419 static int proto_bap_option_call_status = -1;
420
421 static int hf_bap_opt_type = -1;
422 static int hf_bap_opt_length = -1;
423 /* Generated from convert_proto_tree_add_text.pl */
424 static int hf_bap_sub_option_length = -1;
425 static int hf_bap_call_status = -1;
426 static int hf_bap_unknown_option_data = -1;
427 static int hf_bap_sub_option_type = -1;
428 static int hf_bap_reason = -1;
429 static int hf_bap_link_discriminator = -1;
430 static int hf_bap_unique_digit = -1;
431 static int hf_bap_type = -1;
432 static int hf_bap_identifier = -1;
433 static int hf_bap_subscriber_number = -1;
434 static int hf_bap_phone_number_sub_address = -1;
435 static int hf_bap_response_code = -1;
436 static int hf_bap_call_action = -1;
437 static int hf_bap_length = -1;
438
439 static gint ett_bap = -1;
440 static gint ett_bap_options = -1;
441 static gint ett_bap_link_type_opt = -1;
442 static gint ett_bap_phone_delta_opt = -1;
443 static gint ett_bap_phone_delta_subopt = -1;
444 static gint ett_bap_call_status_opt = -1;
445 static gint ett_bap_no_phone_opt = -1;
446 static gint ett_bap_reason_opt = -1;
447 static gint ett_bap_link_disc_opt = -1;
448
449 static expert_field ei_bap_sub_option_length = EI_INIT;
450
451 static dissector_table_t bap_option_table;
452
453 static dissector_handle_t ppp_hdlc_handle, ppp_handle;
454
455 static int proto_comp_data = -1;
456
457 #if 0 /* see dissect_comp_data() */
458 static gint ett_comp_data = -1;
459 #endif
460 static int proto_pppmuxcp = -1;
461 static int proto_pppmuxcp_option_def_pid = -1;
462
463 static int hf_pppmux_flags_pid = -1;
464 static int hf_pppmux_flags_field_length = -1;
465 static int hf_pppmuxcp_opt_type = -1;
466 static int hf_pppmuxcp_opt_length = -1;
467 /* Generated from convert_proto_tree_add_text.pl */
468 static int hf_pppmux_sub_frame_length = -1;
469 static int hf_pppmux_flags = -1;
470 static int hf_pppmux_def_prot_id = -1;
471
472 static gint ett_pppmuxcp = -1;
473 static gint ett_pppmuxcp_options = -1;
474 static gint ett_pppmuxcp_def_pid_opt = -1;
475
476 static dissector_table_t pppmuxcp_option_table;
477
478 static int proto_pppmux = -1;
479 static int hf_pppmux_protocol = -1;
480
481 static gint ett_pppmux = -1;
482 static gint ett_pppmux_subframe = -1;
483 static gint ett_pppmux_subframe_hdr = -1;
484 static gint ett_pppmux_subframe_flags = -1;
485 static gint ett_pppmux_subframe_info = -1;
486
487 static reassembly_table mp_reassembly_table;
488
489 static int proto_mp = -1;
490 static int hf_mp_frag = -1;
491 static int hf_mp_frag_short = -1;
492 static int hf_mp_frag_first = -1;
493 static int hf_mp_frag_last = -1;
494 static int hf_mp_sequence_num = -1;
495 static int hf_mp_sequence_num_cls = -1;
496 static int hf_mp_sequence_num_reserved = -1;
497 static int hf_mp_short_sequence_num = -1;
498 static int hf_mp_short_sequence_num_cls = -1;
499 static int hf_mp_payload = -1;
500 static gint hf_mp_fragments = -1;
501 static gint hf_mp_fragment = -1;
502 static gint hf_mp_fragment_overlap = -1;
503 static gint hf_mp_fragment_overlap_conflicts = -1;
504 static gint hf_mp_fragment_multiple_tails = -1;
505 static gint hf_mp_fragment_too_long_fragment = -1;
506 static gint hf_mp_fragment_error = -1;
507 static gint hf_mp_fragment_count = -1;
508 static gint hf_mp_reassembled_in = -1;
509 static gint hf_mp_reassembled_length = -1;
510
511 static int ett_mp = -1;
512 static int ett_mp_flags = -1;
513 static gint ett_mp_fragment = -1;
514 static gint ett_mp_fragments = -1;
515
516 static const fragment_items mp_frag_items = {
517 /* Fragment subtrees */
518 &ett_mp_fragment,
519 &ett_mp_fragments,
520 /* Fragment fields */
521 &hf_mp_fragments,
522 &hf_mp_fragment,
523 &hf_mp_fragment_overlap,
524 &hf_mp_fragment_overlap_conflicts,
525 &hf_mp_fragment_multiple_tails,
526 &hf_mp_fragment_too_long_fragment,
527 &hf_mp_fragment_error,
528 &hf_mp_fragment_count,
529 /* Reassembled in field */
530 &hf_mp_reassembled_in,
531 /* Reassembled length field */
532 &hf_mp_reassembled_length,
533 /* Reassembled data field */
534 NULL,
535 /* Tag */
536 "Message fragments"
537 };
538
539 static int proto_mplscp = -1;
540 static gint ett_mplscp = -1;
541 static gint ett_mplscp_options = -1;
542
543 static int proto_cdpcp = -1;
544 static gint ett_cdpcp = -1;
545 static gint ett_cdpcp_options = -1;
546
547 static int proto_pap = -1; /* PAP vars */
548 static gint ett_pap = -1;
549 static gint ett_pap_data = -1;
550
551 static gint hf_pap_code = -1;
552 static gint hf_pap_identifier = -1;
553 static gint hf_pap_length = -1;
554 static gint hf_pap_data = -1;
555 static gint hf_pap_peer_id = -1;
556 static gint hf_pap_peer_id_length = -1;
557 static gint hf_pap_password = -1;
558 static gint hf_pap_password_length = -1;
559 static gint hf_pap_message = -1;
560 static gint hf_pap_message_length = -1;
561 static gint hf_pap_stuff = -1;
562
563 static int proto_chap = -1; /* CHAP vars */
564 static gint ett_chap = -1;
565 static gint ett_chap_data = -1;
566
567
568 static gint hf_chap_code = -1;
569 static gint hf_chap_identifier = -1;
570 static gint hf_chap_length = -1;
571 static gint hf_chap_data = -1;
572 static gint hf_chap_value_size = -1;
573 static gint hf_chap_value = -1;
574 static gint hf_chap_name = -1;
575 static gint hf_chap_message = -1;
576 static int hf_chap_stuff = -1;
577
578 static int proto_ipv6cp = -1; /* IPv6CP vars */
579 static int proto_ipv6cp_option_if_id = -1;
580 static int proto_ipv6cp_option_compress = -1;
581
582 /* Generated from convert_proto_tree_add_text.pl */
583 static int hf_ipv6cp_opt_type = -1;
584 static int hf_ipv6cp_opt_length = -1;
585 static int hf_ipv6cp_interface_identifier = -1;
586
587 static gint ett_ipv6cp = -1;
588 static gint ett_ipv6cp_options = -1;
589 static gint ett_ipv6cp_if_id_opt = -1;
590 static gint ett_ipv6cp_compress_opt = -1;
591
592 static dissector_table_t ipv6cp_option_table;
593
594 static int proto_iphc_crtp = -1; /* CRTP vars */
595 static int proto_iphc_crtp_cudp16 = -1;
596 static int proto_iphc_crtp_cudp8 = -1;
597 static int proto_iphc_crtp_cs = -1;
598 static int proto_iphc_crtp_cntcp = -1;
599
600 static int hf_iphc_crtp_cid8 = -1;
601 static int hf_iphc_crtp_cid16 = -1;
602 static int hf_iphc_crtp_gen = -1;
603 static int hf_iphc_crtp_seq = -1;
604 static int hf_iphc_crtp_fh_flags = -1;
605 static int hf_iphc_crtp_fh_cidlenflag = -1;
606 static int hf_iphc_crtp_fh_dataflag = -1;
607 static int hf_iphc_crtp_cs_flags = -1;
608 static int hf_iphc_crtp_cs_cnt = -1;
609 static int hf_iphc_crtp_cs_invalid = -1;
610 static int hf_iphc_crtp_ip_id = -1;
611 static int hf_iphc_crtp_data = -1;
612
613 static gint ett_iphc_crtp = -1;
614 static gint ett_iphc_crtp_hdr = -1;
615 static gint ett_iphc_crtp_info = -1;
616 static gint ett_iphc_crtp_fh_flags = -1;
617
618 static expert_field ei_iphc_crtp_ip_version = EI_INIT;
619 static expert_field ei_iphc_crtp_next_protocol = EI_INIT;
620 static expert_field ei_iphc_crtp_seq_nonzero = EI_INIT;
621
622 static dissector_table_t ppp_subdissector_table;
623 static dissector_handle_t chdlc_handle;
624 static dissector_handle_t eth_withfcs_handle;
625 static dissector_handle_t eth_withoutfcs_handle;
626
627 static capture_dissector_handle_t chdlc_cap_handle;
628
629 static const value_string ppp_direction_vals[] = {
630 {P2P_DIR_RECV, "DCE->DTE"},
631 {P2P_DIR_SENT, "DTE->DCE"},
632 {0, NULL}
633 };
634
635 /* options */
636 static gint ppp_fcs_decode = 0; /* 0 = No FCS, 1 = 16 bit FCS, 2 = 32 bit FCS */
637 #define NO_FCS 0
638 #define FCS_16 1
639 #define FCS_32 2
640
641 const enum_val_t fcs_options[] = {
642 {"none", "None", NO_FCS},
643 {"16-bit", "16-Bit", FCS_16},
644 {"32-bit", "32-Bit", FCS_32},
645 {NULL, NULL, -1}
646 };
647
648 /*
649 * For Default Protocol ID negotiated with PPPMuxCP. We need to
650 * this ID so that if the first subframe doesn't have protocol
651 * ID, we can use it
652 */
653
654 static guint pppmux_def_prot_id = 0;
655
656 /* PPP definitions */
657
658 /*
659 * Used by the GTP dissector as well.
660 * www.iana.org/assignments/ppp-numbers
661 */
662 static const value_string ppp_vals[] = {
663 {PPP_PADDING, "Padding Protocol"},
664 {PPP_ROHC_SCID, "ROHC small-CID"},
665 {PPP_ROHC_LCID, "ROHC large-CID"},
666 {PPP_IP, "Internet Protocol version 4"},
667 {PPP_OSI, "OSI Network Layer"},
668 {PPP_XNSIDP, "Xerox NS IDP"},
669 {PPP_DEC4, "DECnet Phase IV"},
670 {PPP_AT, "Appletalk"},
671 {PPP_IPX, "Novell IPX"},
672 {PPP_VJC_COMP, "Van Jacobson Compressed TCP/IP"},
673 {PPP_VJC_UNCOMP, "Van Jacobson Uncompressed TCP/IP"},
674 {PPP_BCP_BPDU, "Bridging PDU"},
675 {PPP_ST, "Stream Protocol (ST-II)"},
676 {PPP_VINES, "Banyan Vines"},
677 {PPP_AT_EDDP, "AppleTalk EDDP"},
678 {PPP_AT_SB, "AppleTalk SmartBuffered"},
679 {PPP_MP, "Multi-Link"},
680 {PPP_NB, "NETBIOS Framing"},
681 {PPP_CISCO, "Cisco Systems"},
682 {PPP_ASCOM, "Ascom Timeplex"},
683 {PPP_LBLB, "Fujitsu Link Backup and Load Balancing (LBLB)"},
684 {PPP_RL, "DCA Remote Lan"},
685 {PPP_SDTP, "Serial Data Transport Protocol (PPP-SDTP)"},
686 {PPP_LLC, "SNA over 802.2"},
687 {PPP_SNA, "SNA"},
688 {PPP_IPV6HC, "IPv6 Header Compression "},
689 {PPP_KNX, "KNX Bridging Data"},
690 {PPP_ENCRYPT, "Encryption"},
691 {PPP_ILE, "Individual Link Encryption"},
692 {PPP_IPV6, "Internet Protocol version 6"},
693 {PPP_MUX, "PPP Muxing"},
694 {PPP_VSNP, "Vendor-Specific Network Protocol (VSNP)"},
695 {PPP_TNP, "TRILL Network Protocol (TNP)"},
696 {PPP_RTP_FH, "RTP IPHC Full Header"},
697 {PPP_RTP_CTCP, "RTP IPHC Compressed TCP"},
698 {PPP_RTP_CNTCP, "RTP IPHC Compressed Non TCP"},
699 {PPP_RTP_CUDP8, "RTP IPHC Compressed UDP 8"},
700 {PPP_RTP_CRTP8, "RTP IPHC Compressed RTP 8"},
701 {PPP_STAMPEDE, "Stampede Bridging"},
702 {PPP_MPPLUS, "MP+ Protocol"},
703 {PPP_NTCITS_IPI, "NTCITS IPI"},
704 {PPP_ML_SLCOMP, "Single link compression in multilink"},
705 {PPP_COMP, "Compressed datagram"},
706 {PPP_STP_HELLO, "802.1d Hello Packets"},
707 {PPP_IBM_SR, "IBM Source Routing BPDU"},
708 {PPP_DEC_LB, "DEC LANBridge100 Spanning Tree"},
709 {PPP_CDP, "Cisco Discovery Protocol"},
710 {PPP_NETCS, "Netcs Twin Routing"},
711 {PPP_STP, "STP - Scheduled Transfer Protocol"},
712 {PPP_EDP, "EDP - Extreme Discovery Protocol"},
713 {PPP_OSCP, "Optical Supervisory Channel Protocol (OSCP)"},
714 {PPP_OSCP2, "Optical Supervisory Channel Protocol (OSCP)"},
715 {PPP_LUXCOM, "Luxcom"},
716 {PPP_SIGMA, "Sigma Network Systems"},
717 {PPP_ACSP, "Apple Client Server Protocol"},
718 {PPP_MPLS_UNI, "MPLS Unicast"},
719 {PPP_MPLS_MULTI, "MPLS Multicast"},
720 {PPP_P12844, "IEEE p1284.4 standard - data packets"},
721 {PPP_TETRA, "ETSI TETRA Network Protocol Type 1"},
722 {PPP_MFTP, "Multichannel Flow Treatment Protocol"},
723 {PPP_RTP_CTCPND, "RTP IPHC Compressed TCP No Delta"},
724 {PPP_RTP_CS, "RTP IPHC Context State"},
725 {PPP_RTP_CUDP16, "RTP IPHC Compressed UDP 16"},
726 {PPP_RTP_CRDP16, "RTP IPHC Compressed RTP 16"},
727 {PPP_CCCP, "Cray Communications Control Protocol"},
728 {PPP_CDPD_MNRP, "CDPD Mobile Network Registration Protocol"},
729 {PPP_EXPANDAP, "Expand accelerator protocol"},
730 {PPP_ODSICP, "ODSICP NCP"},
731 {PPP_DOCSIS, "DOCSIS DLL"},
732 {PPP_CETACEANNDP, "Cetacean Network Detection Protocol"},
733 {PPP_LZS, "Stacker LZS"},
734 {PPP_REFTEK, "RefTek Protocol"},
735 {PPP_FC, "Fibre Channel"},
736 {PPP_EMIT, "EMIT Protocols"},
737 {PPP_VSP, "Vendor-Specific Protocol (VSP)"},
738 {PPP_TLSP, "TRILL Link State Protocol (TLSP)"},
739 {PPP_IPCP, "Internet Protocol Control Protocol"},
740 {PPP_OSINLCP, "OSI Network Layer Control Protocol"},
741 {PPP_XNSIDPCP, "Xerox NS IDP Control Protocol"},
742 {PPP_DECNETCP, "DECnet Phase IV Control Protocol"},
743 {PPP_ATCP, "AppleTalk Control Protocol"},
744 {PPP_IPXCP, "Novell IPX Control Protocol"},
745 {PPP_BCP_NCP, "Bridging NCP"},
746 {PPP_SPCP, "Stream Protocol Control Protocol"},
747 {PPP_BVCP, "Banyan Vines Control Protocol"},
748 {PPP_MLCP, "Multi-Link Control Protocol"},
749 {PPP_NBCP, "NETBIOS Framing Control Protocol"},
750 {PPP_CISCOCP, "Cisco Systems Control Protocol"},
751 {PPP_ASCOMCP, "Ascom Timeplex"},
752 {PPP_LBLBCP, "Fujitsu LBLB Control Protocol"},
753 {PPP_RLNCP, "DCA Remote Lan Network Control Protocol (RLNCP)"},
754 {PPP_SDCP, "Serial Data Control Protocol (PPP-SDCP)"},
755 {PPP_LLCCP, "SNA over 802.2 Control Protocol"},
756 {PPP_SNACP, "SNA Control Protocol"},
757 {PPP_IP6HCCP, "IP6 Header Compression Control Protocol"},
758 {PPP_KNXCP, "KNX Bridging Control Protocol"},
759 {PPP_ECP, "Encryption Control Protocol"},
760 {PPP_ILECP, "Individual Link Encryption Control Protocol"},
761 {PPP_IPV6CP, "IPv6 Control Protocol"},
762 {PPP_MUXCP, "PPP Muxing Control Protocol"},
763 {PPP_VSNCP, "Vendor-Specific Network Control Protocol (VSNCP)"},
764 {PPP_TNCP, "TRILL Network Control Protocol"},
765 {PPP_STAMPEDECP, "Stampede Bridging Control Protocol"},
766 {PPP_MPPCP, "MP+ Control Protocol"},
767 {PPP_IPICP, "NTCITS IPI Control Protocol"},
768 {PPP_SLCC, "Single link compression in multilink control"},
769 {PPP_CCP, "Compression Control Protocol"},
770 {PPP_CDPCP, "Cisco Discovery Protocol Control Protocol"},
771 {PPP_NETCSCP, "Netcs Twin Routing"},
772 {PPP_STPCP, "STP - Control Protocol"},
773 {PPP_EDPCP, "EDPCP - Extreme Discovery Protocol Control Protocol"},
774 {PPP_ACSPC, "Apple Client Server Protocol Control"},
775 {PPP_MPLSCP, "MPLS Control Protocol"},
776 {PPP_P12844CP, "IEEE p1284.4 standard - Protocol Control"},
777 {PPP_TETRACP, "ETSI TETRA TNP1 Control Protocol"},
778 {PPP_MFTPCP, "Multichannel Flow Treatment Protocol"},
779 {PPP_LCP, "Link Control Protocol"},
780 {PPP_PAP, "Password Authentication Protocol"},
781 {PPP_LQR, "Link Quality Report"},
782 {PPP_SPAP, "Shiva Password Authentication Protocol"},
783 {PPP_CBCP, "Callback Control Protocol (CBCP)"},
784 {PPP_BACP, "BACP Bandwidth Allocation Control Protocol"},
785 {PPP_BAP, "BAP Bandwidth Allocation Protocol"},
786 {PPP_VSAP, "Vendor-Specific Authentication Protocol (VSAP)"},
787 {PPP_CONTCP, "Container Control Protocol"},
788 {PPP_CHAP, "Challenge Handshake Authentication Protocol"},
789 {PPP_RSAAP, "RSA Authentication Protocol"},
790 {PPP_EAP, "Extensible Authentication Protocol"},
791 {PPP_SIEP, "Mitsubishi Security Information Exchange Protocol (SIEP)"},
792 {PPP_SBAP, "Stampede Bridging Authorization Protocol"},
793 {PPP_PRPAP, "Proprietary Authentication Protocol"},
794 {PPP_PRPAP2, "Proprietary Authentication Protocol"},
795 {PPP_PRPNIAP, "Proprietary Node ID Authentication Protocol"},
796 {0, NULL}
797 };
798 value_string_ext ppp_vals_ext = VALUE_STRING_EXT_INIT(ppp_vals);
799
800 /* CP (LCP, CCP, IPCP, etc.) codes.
801 * from pppd fsm.h
802 */
803 #define VNDRSPCFC 0 /* Vendor Specific: RFC 2153 */
804 #define CONFREQ 1 /* Configuration Request */
805 #define CONFACK 2 /* Configuration Ack */
806 #define CONFNAK 3 /* Configuration Nak */
807 #define CONFREJ 4 /* Configuration Reject */
808 #define TERMREQ 5 /* Termination Request */
809 #define TERMACK 6 /* Termination Ack */
810 #define CODEREJ 7 /* Code Reject */
811
812 static const value_string cp_vals[] = {
813 {VNDRSPCFC, "Vendor Specific"},
814 {CONFREQ, "Configuration Request"},
815 {CONFACK, "Configuration Ack"},
816 {CONFNAK, "Configuration Nak"},
817 {CONFREJ, "Configuration Reject"},
818 {TERMREQ, "Termination Request"},
819 {TERMACK, "Termination Ack"},
820 {CODEREJ, "Code Reject"},
821 {0, NULL}
822 };
823
824 /*
825 * LCP-specific packet types.
826 */
827 #define PROTREJ 8 /* Protocol Reject */
828 #define ECHOREQ 9 /* Echo Request */
829 #define ECHOREP 10 /* Echo Reply */
830 #define DISCREQ 11 /* Discard Request */
831 #define IDENT 12 /* Identification */
832 #define TIMEREMAIN 13 /* Time remaining */
833
834 /*
835 * CCP-specific packet types.
836 */
837 #define RESETREQ 14 /* Reset Request */
838 #define RESETACK 15 /* Reset Ack */
839
840 /*
841 * CBCP-specific packet types.
842 */
843 #define CBREQ 1 /* Callback Request */
844 #define CBRES 2 /* Callback Response */
845 #define CBACK 3 /* Callback Ack */
846
847 #define CBCP_OPT 6 /* Use callback control protocol */
848
849 /*
850 * BAP-specific packet types.
851 */
852 #define BAP_CREQ 1 /* Call Request */
853 #define BAP_CRES 2 /* Call Response */
854 #define BAP_CBREQ 3 /* Callback Request */
855 #define BAP_CBRES 4 /* Callback Response */
856 #define BAP_LDQREQ 5 /* Link Drop Query Request */
857 #define BAP_LDQRES 6 /* Link Drop Query Response */
858 #define BAP_CSI 7 /* Call Status Indication */
859 #define BAP_CSRES 8 /* Call Status Response */
860
861 static const value_string lcp_vals[] = {
862 {VNDRSPCFC, "Vendor Specific"},
863 {CONFREQ, "Configuration Request"},
864 {CONFACK, "Configuration Ack"},
865 {CONFNAK, "Configuration Nak"},
866 {CONFREJ, "Configuration Reject"},
867 {TERMREQ, "Termination Request"},
868 {TERMACK, "Termination Ack"},
869 {CODEREJ, "Code Reject"},
870 {PROTREJ, "Protocol Reject"},
871 {ECHOREQ, "Echo Request"},
872 {ECHOREP, "Echo Reply"},
873 {DISCREQ, "Discard Request"},
874 {IDENT, "Identification"},
875 {TIMEREMAIN, "Time Remaining"},
876 {0, NULL}
877 };
878
879 static const value_string ccp_vals[] = {
880 {VNDRSPCFC, "Vendor Specific"},
881 {CONFREQ, "Configuration Request"},
882 {CONFACK, "Configuration Ack"},
883 {CONFNAK, "Configuration Nak"},
884 {CONFREJ, "Configuration Reject"},
885 {TERMREQ, "Termination Request"},
886 {TERMACK, "Termination Ack"},
887 {CODEREJ, "Code Reject"},
888 {RESETREQ, "Reset Request"},
889 {RESETACK, "Reset Ack"},
890 {0, NULL}
891 };
892
893 static const value_string cbcp_vals[] = {
894 {CBREQ, "Callback Request"},
895 {CBRES, "Callback Response"},
896 {CBACK, "Callback Ack"},
897 {0, NULL}
898 };
899
900 static const value_string bap_vals[] = {
901 {BAP_CREQ, "Call Request"},
902 {BAP_CRES, "Call Response"},
903 {BAP_CBREQ, "Callback Request"},
904 {BAP_CBRES, "Callback Response"},
905 {BAP_LDQREQ, "Link Drop Query Request"},
906 {BAP_LDQRES, "Link Drop Query Response"},
907 {BAP_CSI, "Call Status Indication"},
908 {BAP_CSRES, "Call Status Response"},
909 {0, NULL}
910 };
911
912 #define BAP_RESP_CODE_REQACK 0x00
913 #define BAP_RESP_CODE_REQNAK 0x01
914 #define BAP_RESP_CODE_REQREJ 0x02
915 #define BAP_RESP_CODE_REQFULLNAK 0x03
916 static const value_string bap_resp_code_vals[] = {
917 {BAP_RESP_CODE_REQACK, "Request Ack"},
918 {BAP_RESP_CODE_REQNAK, "Request Nak"},
919 {BAP_RESP_CODE_REQREJ, "Request Rej"},
920 {BAP_RESP_CODE_REQFULLNAK, "Request Full Nak"},
921 {0, NULL}
922 };
923
924 #define BAP_LINK_TYPE_ISDN 0 /* ISDN */
925 #define BAP_LINK_TYPE_X25 1 /* X.25 */
926 #define BAP_LINK_TYPE_ANALOG 2 /* Analog */
927 #define BAP_LINK_TYPE_SD 3 /* Switched Digital (non-ISDN) */
928 #define BAP_LINK_TYPE_ISDNOV 4 /* ISDN data over voice */
929 #define BAP_LINK_TYPE_RESV5 5 /* Reserved */
930 #define BAP_LINK_TYPE_RESV6 6 /* Reserved */
931 #define BAP_LINK_TYPE_RESV7 7 /* Reserved */
932 static const value_string bap_link_type_vals[] = {
933 {BAP_LINK_TYPE_ISDN, "ISDN"},
934 {BAP_LINK_TYPE_X25, "X.25"},
935 {BAP_LINK_TYPE_ANALOG, "Analog"},
936 {BAP_LINK_TYPE_SD, "Switched Digital (non-ISDN)"},
937 {BAP_LINK_TYPE_ISDNOV, "ISDN data over voice"},
938 {BAP_LINK_TYPE_RESV5, "Reserved"},
939 {BAP_LINK_TYPE_RESV6, "Reserved"},
940 {BAP_LINK_TYPE_RESV7, "Reserved"},
941 {0, NULL}
942 };
943
944 #define BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT 1 /* Unique Digit */
945 #define BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM 2 /* Subscriber Number */
946 #define BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR 3 /* Phone Number Sub Address */
947 static const value_string bap_phone_delta_subopt_vals[] = {
948 {BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT, "Unique Digit"},
949 {BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM, "Subscriber Number"},
950 {BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR, "Phone Number Sub Address"},
951 {0, NULL}
952 };
953
954 /*
955 * Cause codes for Cause.
956 *
957 * The following code table is taken from packet-q931.c but is slightly
958 * adapted to BAP protocol.
959 */
960 static const value_string q931_cause_code_vals[] = {
961 {0x00, "Call successful"},
962 {0x01, "Unallocated (unassigned) number"},
963 {0x02, "No route to specified transit network"},
964 {0x03, "No route to destination"},
965 {0x04, "Send special information tone"},
966 {0x05, "Misdialled trunk prefix"},
967 {0x06, "Channel unacceptable"},
968 {0x07, "Call awarded and being delivered in an established channel"},
969 {0x08, "Prefix 0 dialed but not allowed"},
970 {0x09, "Prefix 1 dialed but not allowed"},
971 {0x0A, "Prefix 1 dialed but not required"},
972 {0x0B, "More digits received than allowed, call is proceeding"},
973 {0x10, "Normal call clearing"},
974 {0x11, "User busy"},
975 {0x12, "No user responding"},
976 {0x13, "No answer from user (user alerted)"},
977 {0x14, "Subscriber absent"},
978 {0x15, "Call rejected"},
979 {0x16, "Number changed"},
980 {0x17, "Reverse charging rejected"},
981 {0x18, "Call suspended"},
982 {0x19, "Call resumed"},
983 {0x1A, "Non-selected user clearing"},
984 {0x1B, "Destination out of order"},
985 {0x1C, "Invalid number format (incomplete number)"},
986 {0x1D, "Facility rejected"},
987 {0x1E, "Response to STATUS ENQUIRY"},
988 {0x1F, "Normal unspecified"},
989 {0x21, "Circuit out of order"},
990 {0x22, "No circuit/channel available"},
991 {0x23, "Destination unattainable"},
992 {0x25, "Degraded service"},
993 {0x26, "Network out of order"},
994 {0x27, "Transit delay range cannot be achieved"},
995 {0x28, "Throughput range cannot be achieved"},
996 {0x29, "Temporary failure"},
997 {0x2A, "Switching equipment congestion"},
998 {0x2B, "Access information discarded"},
999 {0x2C, "Requested circuit/channel not available"},
1000 {0x2D, "Pre-empted"},
1001 {0x2E, "Precedence call blocked"},
1002 {0x2F, "Resources unavailable, unspecified"},
1003 {0x31, "Quality of service unavailable"},
1004 {0x32, "Requested facility not subscribed"},
1005 {0x33, "Reverse charging not allowed"},
1006 {0x34, "Outgoing calls barred"},
1007 {0x35, "Outgoing calls barred within CUG"},
1008 {0x36, "Incoming calls barred"},
1009 {0x37, "Incoming calls barred within CUG"},
1010 {0x38, "Call waiting not subscribed"},
1011 {0x39, "Bearer capability not authorized"},
1012 {0x3A, "Bearer capability not presently available"},
1013 {0x3E, "Inconsistency in designated outgoing access information and subscriber class"},
1014 {0x3F, "Service or option not available, unspecified"},
1015 {0x41, "Bearer capability not implemented"},
1016 {0x42, "Channel type not implemented"},
1017 {0x43, "Transit network selection not implemented"},
1018 {0x44, "Message not implemented"},
1019 {0x45, "Requested facility not implemented"},
1020 {0x46, "Only restricted digital information bearer capability is available"},
1021 {0x4F, "Service or option not implemented, unspecified"},
1022 {0x51, "Invalid call reference value"},
1023 {0x52, "Identified channel does not exist"},
1024 {0x53, "Call identity does not exist for suspended call"},
1025 {0x54, "Call identity in use"},
1026 {0x55, "No call suspended"},
1027 {0x56, "Call having the requested call identity has been cleared"},
1028 {0x57, "Called user not member of CUG"},
1029 {0x58, "Incompatible destination"},
1030 {0x59, "Non-existent abbreviated address entry"},
1031 {0x5A, "Destination address missing, and direct call not subscribed"},
1032 {0x5B, "Invalid transit network selection (national use)"},
1033 {0x5C, "Invalid facility parameter"},
1034 {0x5D, "Mandatory information element is missing"},
1035 {0x5F, "Invalid message, unspecified"},
1036 {0x60, "Mandatory information element is missing"},
1037 {0x61, "Message type non-existent or not implemented"},
1038 {0x62, "Message not compatible with call state or message type non-existent or not implemented"},
1039 {0x63, "Information element non-existent or not implemented"},
1040 {0x64, "Invalid information element contents"},
1041 {0x65, "Message not compatible with call state"},
1042 {0x66, "Recovery on timer expiry"},
1043 {0x67, "Parameter non-existent or not implemented - passed on"},
1044 {0x6E, "Message with unrecognized parameter discarded"},
1045 {0x6F, "Protocol error, unspecified"},
1046 {0x7F, "Internetworking, unspecified"},
1047 {0xFF, "Non-specific failure"},
1048 {0, NULL}
1049 };
1050 static value_string_ext q931_cause_code_vals_ext = VALUE_STRING_EXT_INIT(q931_cause_code_vals);
1051
1052 static const value_string bap_call_status_opt_action_vals[] = {
1053 {0, "No retry"},
1054 {1, "Retry"},
1055 {0, NULL}
1056 };
1057
1058 #define STAC_CM_NONE 0
1059 #define STAC_CM_LCB 1
1060 #define STAC_CM_CRC 2
1061 #define STAC_CM_SN 3
1062 #define STAC_CM_EXTMODE 4
1063 static const value_string stac_checkmode_vals[] = {
1064 {STAC_CM_NONE, "None"},
1065 {STAC_CM_LCB, "LCB"},
1066 {STAC_CM_CRC, "CRC"},
1067 {STAC_CM_SN, "Sequence Number"},
1068 {STAC_CM_EXTMODE, "Extended Mode"},
1069 {0, NULL}
1070 };
1071
1072 #define LZSDCP_CM_NONE 0
1073 #define LZSDCP_CM_LCB 1
1074 #define LZSDCP_CM_SN 2
1075 #define LZSDCP_CM_SN_LCB 3
1076 static const value_string lzsdcp_checkmode_vals[] = {
1077 {LZSDCP_CM_NONE, "None"},
1078 {LZSDCP_CM_LCB, "LCB"},
1079 {LZSDCP_CM_SN, "Sequence Number"},
1080 {LZSDCP_CM_SN_LCB, "Sequence Number + LCB (default)"},
1081 {0, NULL}
1082 };
1083
1084 #define LZSDCP_PM_NONE 0
1085 #define LZSDCP_PM_PROC_UNCOMP 1
1086 static const value_string lzsdcp_processmode_vals[] = {
1087 {LZSDCP_PM_NONE, "None (default)"},
1088 {LZSDCP_PM_PROC_UNCOMP, "Process-Uncompressed"},
1089 {0, NULL}
1090 };
1091
1092 #define DCE_MODE_1 1
1093 #define DCE_MODE_2 2
1094 static const value_string dce_mode_vals[] = {
1095 {DCE_MODE_1, "No Additional Negotiation"},
1096 {DCE_MODE_2, "Full PPP Negotiation and State Machine"},
1097 {0, NULL}
1098 };
1099
1100 /*
1101 * Options. (LCP)
1102 */
1103 #define CI_VENDORSPECIFIC 0 /* Vendor Specific [RFC2153] */
1104 #define CI_MRU 1 /* Maximum Receive Unit [RFC1661] */
1105 #define CI_ASYNCMAP 2 /* Async Control Character Map */
1106 #define CI_AUTHPROT 3 /* Authentication Protocol [RFC1661] */
1107 #define CI_QUALITY 4 /* Quality Protocol [RFC1661] */
1108 #define CI_MAGICNUMBER 5 /* Magic Number [RFC1661] */
1109 #define CI_LINKQUALMON 6 /* DEPRECATED (Quality Protocol) [RFC1172] */
1110 #define CI_PCOMPRESSION 7 /* Protocol Field Compression [RFC1661] */
1111 #define CI_ACCOMPRESSION 8 /* Address/Control Field Compression
1112 [RFC1661] */
1113 #define CI_FCS_ALTERNATIVES 9 /* FCS Alternatives [RFC1570] */
1114 #define CI_SELF_DESCRIBING_PAD 10 /* Self-Describing Pad [RFC1570] */
1115 #define CI_NUMBERED_MODE 11 /* Numbered Mode [RFC1663] */
1116 #define CI_MULTILINK_PROC 12 /* DEPRECATED (Multi-Link Procedure) */
1117 #define CI_CALLBACK 13 /* Callback [RFC1570] */
1118 #define CI_CONNECTTIME 14 /* DEPRECATED (Connect Time) */
1119 #define CI_COMPOUND_FRAMES 15 /* DEPRECATED (Compound Frames) [RFC1570] */
1120 #define CI_NOMDATAENCAP 16 /* DEPRECATED (Nominal Data Encapsulation) */
1121 /* NOTE: IANA lists CI_NOMDATAENCAP as 16, but it is listed as 14 in
1122 * https://tools.ietf.org/html/draft-ietf-pppext-dataencap-03.
1123 * Which is correct is anyone's guess. */
1124 #define CI_MULTILINK_MRRU 17 /* Multilink MRRU [RFC1990] */
1125 #define CI_MULTILINK_SSNH 18 /* Multilink Short Sequence Number Header
1126 [RFC1990] */
1127 #define CI_MULTILINK_EP_DISC 19 /* Multilink Endpoint Discriminator
1128 [RFC1990] */
1129 #define CI_PROP_KEN 20 /* Proprietary [Ken Culbert] ken@funk.com */
1130 #define CI_DCE_IDENTIFIER 21 /* DCE Identifier [RFC1976]: Warning:
1131 Option type 25 in the RFC is incorrect */
1132 #define CI_MULTILINK_PLUS_PROC 22 /* Multilink Plus Procedure [RFC1934] */
1133 #define CI_LINK_DISC_FOR_BACP 23 /* Link Discriminator for BACP [RFC2125] */
1134 #define CI_LCP_AUTHENTICATION 24 /* LCP Authentication Option [Culbert] */
1135 #define CI_COBS 25 /* Consistent Overhead Byte Stuffing (COBS)
1136 [Carlson] */
1137 #define CI_PREFIX_ELISION 26 /* Prefix elision [RFC2686][RFC2687] */
1138 #define CI_MULTILINK_HDR_FMT 27 /* Multilink header format
1139 [RFC2686][RFC2687] */
1140 #define CI_INTERNATIONALIZATION 28 /* Internationalization [RFC2484] */
1141 #define CI_SDL_ON_SONET_SDH 29 /* Simple Data Link on SONET/SDH
1142 [RFC2823] */
1143 #define CI_UNASSIGNED 30 /* Unassigned ... but so are 31-255, so
1144 why do they bother specifically
1145 mentioning this one, I wonder? */
1146
1147 static int hf_lcp_magic_number = -1;
1148 static int hf_lcp_data = -1;
1149 static int hf_lcp_message = -1;
1150 static int hf_lcp_secs_remaining = -1;
1151 static int hf_lcp_rej_proto = -1;
1152 static int hf_lcp_opt_type = -1;
1153 static int hf_lcp_opt_length = -1;
1154 static int hf_lcp_opt_oui = -1;
1155 static int hf_lcp_opt_kind = -1;
1156 static int hf_lcp_opt_data = -1;
1157 static int hf_lcp_opt_mru = -1;
1158 static int hf_lcp_opt_asyncmap = -1;
1159 static int hf_lcp_opt_asyncmap_nul = -1;
1160 static int hf_lcp_opt_asyncmap_soh = -1;
1161 static int hf_lcp_opt_asyncmap_stx = -1;
1162 static int hf_lcp_opt_asyncmap_etx = -1;
1163 static int hf_lcp_opt_asyncmap_eot = -1;
1164 static int hf_lcp_opt_asyncmap_enq = -1;
1165 static int hf_lcp_opt_asyncmap_ack = -1;
1166 static int hf_lcp_opt_asyncmap_bel = -1;
1167 static int hf_lcp_opt_asyncmap_bs = -1;
1168 static int hf_lcp_opt_asyncmap_ht = -1;
1169 static int hf_lcp_opt_asyncmap_lf = -1;
1170 static int hf_lcp_opt_asyncmap_vt = -1;
1171 static int hf_lcp_opt_asyncmap_ff = -1;
1172 static int hf_lcp_opt_asyncmap_cr = -1;
1173 static int hf_lcp_opt_asyncmap_so = -1;
1174 static int hf_lcp_opt_asyncmap_si = -1;
1175 static int hf_lcp_opt_asyncmap_dle = -1;
1176 static int hf_lcp_opt_asyncmap_dc1 = -1;
1177 static int hf_lcp_opt_asyncmap_dc2 = -1;
1178 static int hf_lcp_opt_asyncmap_dc3 = -1;
1179 static int hf_lcp_opt_asyncmap_dc4 = -1;
1180 static int hf_lcp_opt_asyncmap_nak = -1;
1181 static int hf_lcp_opt_asyncmap_syn = -1;
1182 static int hf_lcp_opt_asyncmap_etb = -1;
1183 static int hf_lcp_opt_asyncmap_can = -1;
1184 static int hf_lcp_opt_asyncmap_em = -1;
1185 static int hf_lcp_opt_asyncmap_sub = -1;
1186 static int hf_lcp_opt_asyncmap_esc = -1;
1187 static int hf_lcp_opt_asyncmap_fs = -1;
1188 static int hf_lcp_opt_asyncmap_gs = -1;
1189 static int hf_lcp_opt_asyncmap_rs = -1;
1190 static int hf_lcp_opt_asyncmap_us = -1;
1191 static int hf_lcp_opt_auth_protocol = -1;
1192 static int hf_lcp_opt_algorithm = -1;
1193 static int hf_lcp_opt_quality_protocol = -1;
1194 static int hf_lcp_opt_magic_number = -1;
1195 static int hf_lcp_opt_reportingperiod = -1;
1196 static int hf_lcp_opt_fcs_alternatives = -1;
1197 static int hf_lcp_opt_fcs_alternatives_null = -1;
1198 static int hf_lcp_opt_fcs_alternatives_ccitt16 = -1;
1199 static int hf_lcp_opt_fcs_alternatives_ccitt32 = -1;
1200 static int hf_lcp_opt_maximum = -1;
1201 static int hf_lcp_opt_window = -1;
1202 static int hf_lcp_opt_hdlc_address = -1;
1203 static int hf_lcp_opt_operation = -1;
1204 static int hf_lcp_opt_message = -1;
1205 static int hf_lcp_opt_mrru = -1;
1206 static int hf_lcp_opt_ep_disc_class = -1;
1207 static int hf_lcp_opt_ip_address = -1;
1208 static int hf_lcp_opt_802_1_address = -1;
1209 static int hf_lcp_opt_magic_block = -1;
1210 static int hf_lcp_opt_psndn = -1;
1211 static int hf_lcp_opt_mode = -1;
1212 static int hf_lcp_opt_unused = -1;
1213 static int hf_lcp_opt_link_discrim = -1;
1214 static int hf_lcp_opt_id = -1;
1215 static int hf_lcp_opt_cobs_flags = -1;
1216 static int hf_lcp_opt_cobs_flags_res = -1;
1217 static int hf_lcp_opt_cobs_flags_pre = -1;
1218 static int hf_lcp_opt_cobs_flags_zxe = -1;
1219 static int hf_lcp_opt_class = -1;
1220 static int hf_lcp_opt_prefix = -1;
1221 static int hf_lcp_opt_code = -1;
1222 static int hf_lcp_opt_max_susp_classes = -1;
1223 static int hf_lcp_opt_MIBenum = -1;
1224 static int hf_lcp_opt_language_tag = -1;
1225
1226 static gboolean
ppp_option_len_check(proto_tree * tree,packet_info * pinfo,tvbuff_t * tvb,int proto,guint len,guint optlen)1227 ppp_option_len_check(proto_tree* tree, packet_info *pinfo, tvbuff_t *tvb, int proto, guint len, guint optlen)
1228 {
1229 if (len != optlen) {
1230 /* Bogus - option length isn't what it's supposed to be for this option. */
1231 proto_tree_add_expert_format(tree, pinfo, &ei_ppp_opt_len_invalid, tvb, 0, len,
1232 "%s (with option length = %u byte%s; should be %u)",
1233 proto_get_protocol_short_name(find_protocol_by_id(proto)),
1234 len, plurality(len, "", "s"), optlen);
1235 return FALSE;
1236 }
1237
1238 return TRUE;
1239 }
1240
1241 /* Started as a copy of dissect_ip_tcp_options(), but was changed to support
1242 options as a dissector table */
1243 static void
ppp_dissect_options(tvbuff_t * tvb,int offset,guint length,dissector_table_t const option_dissectors,packet_info * pinfo,proto_tree * opt_tree)1244 ppp_dissect_options(tvbuff_t *tvb, int offset, guint length, dissector_table_t const option_dissectors,
1245 packet_info *pinfo, proto_tree *opt_tree)
1246 {
1247 guchar opt;
1248 guint optlen;
1249 const char *name;
1250 dissector_handle_t option_dissector = NULL;
1251 tvbuff_t *next_tvb;
1252
1253 while (length > 0) {
1254 opt = tvb_get_guint8(tvb, offset);
1255 --length; /* account for type byte */
1256 if (option_dissectors != NULL) {
1257 option_dissector = dissector_get_uint_handle(option_dissectors, opt);
1258 if (option_dissector == NULL) {
1259 name = wmem_strdup_printf(pinfo->pool, "Unknown (0x%02x)", opt);
1260 } else {
1261 name = dissector_handle_get_short_name(option_dissector);
1262 }
1263 } else {
1264 name = wmem_strdup_printf(pinfo->pool, "Unknown (0x%02x)", opt);
1265 }
1266
1267 /* Option has a length. Is it in the packet? */
1268 if (length == 0) {
1269 /* Bogus - packet must at least include option code byte and
1270 length byte! */
1271 proto_tree_add_expert_format(opt_tree, pinfo, &ei_ppp_opt_len_invalid, tvb, offset, 1,
1272 "%s (length byte past end of options)", name);
1273 return;
1274 }
1275
1276 optlen = tvb_get_guint8(tvb, offset + 1); /* total including type, len */
1277 --length; /* account for length byte */
1278
1279 if (optlen < 2) {
1280 /* Bogus - option length is too short to include option code and
1281 option length. */
1282 proto_tree_add_expert_format(opt_tree, pinfo, &ei_ppp_opt_len_invalid, tvb, offset, 2,
1283 "%s (with too-short option length = %u byte%s)",
1284 name, optlen, plurality(optlen, "", "s"));
1285 return;
1286 } else if (optlen - 2 > length) {
1287 /* Bogus - option goes past the end of the header. */
1288 proto_tree_add_expert_format(opt_tree, pinfo, &ei_ppp_opt_len_invalid, tvb, offset, length,
1289 "%s (option length = %u byte%s says option goes past end of options)",
1290 name, optlen, plurality(optlen, "", "s"));
1291 return;
1292 }
1293
1294 if (option_dissector == NULL) {
1295 proto_tree_add_subtree_format(opt_tree, tvb, offset, optlen, ett_ppp_unknown_opt, NULL, "%s (%u byte%s)",
1296 name, optlen, plurality(optlen, "", "s"));
1297 } else {
1298 next_tvb = tvb_new_subset_length(tvb, offset, optlen);
1299 call_dissector(option_dissector, next_tvb, pinfo, opt_tree);
1300 proto_item_append_text(proto_tree_get_parent(opt_tree), ", %s", name);
1301 }
1302 offset += optlen;
1303 length -= (optlen-2); //already accounted for type and len bytes
1304 }
1305 }
1306
1307 static void
dissect_lcp_opt_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)1308 dissect_lcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
1309 const char *name)
1310 {
1311 guint8 type;
1312
1313 type = tvb_get_guint8(tvb, offset);
1314 proto_tree_add_uint_format_value(tree, hf_lcp_opt_type, tvb, offset, 1,
1315 type, "%s (%u)", name, type);
1316 proto_tree_add_item(tree, hf_lcp_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
1317 }
1318
1319 static gboolean
dissect_lcp_fixed_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)1320 dissect_lcp_fixed_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1321 int proto, int ett, int expected_length,
1322 proto_tree** ret_tree, proto_item** ret_item)
1323 {
1324 if (!ppp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), expected_length))
1325 return FALSE;
1326
1327 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, expected_length, ENC_NA);
1328 *ret_tree = proto_item_add_subtree(*ret_item, ett);
1329
1330 dissect_lcp_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
1331 return TRUE;
1332 }
1333
1334 static gboolean
dissect_lcp_var_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)1335 dissect_lcp_var_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1336 int proto, int ett, int expected_length,
1337 proto_tree** ret_tree, proto_item** ret_item)
1338 {
1339 int len = tvb_reported_length(tvb);
1340
1341 if (len < expected_length) {
1342 /* Bogus - option length isn't what it's supposed to be for this option. */
1343 proto_tree_add_expert_format(tree, pinfo, &ei_ppp_opt_len_invalid, tvb, 0, len,
1344 "%s (with option length = %u byte%s; should be at least %u)",
1345 proto_get_protocol_short_name(find_protocol_by_id(proto_lcp_option_vendor)),
1346 len, plurality(len, "", "s"), 6);
1347 return FALSE;
1348 }
1349
1350 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, -1, ENC_NA);
1351 *ret_tree = proto_item_add_subtree(*ret_item, ett);
1352
1353 dissect_lcp_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
1354 return TRUE;
1355 }
1356
1357 /* Used for:
1358 * Protocol Field Compression
1359 * Address and Control Field Compression
1360 * Compound Frames (Deprecated)
1361 * Nominal Data Encapsulation (Deprecated)
1362 * Multilink Short Sequence Number Header
1363 * Simple Data Link on SONET/SDH
1364 */
1365 static int
dissect_lcp_simple_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett)1366 dissect_lcp_simple_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int proto, int ett)
1367 {
1368 proto_tree *field_tree;
1369 proto_item *ti;
1370
1371 dissect_lcp_fixed_opt(tvb, pinfo, tree, proto, ett, 2, &field_tree, &ti);
1372 return tvb_captured_length(tvb);
1373 }
1374
1375 /* 3GPP2 X.S0057-B v1.0
1376 * 9.1.4.1 3GPP2 VSNCP Configuration Options
1377 * Options. (VSNCP)
1378 */
1379
1380 #define CI_PDN_IDENTIFIER 1
1381 #define CI_ACCESS_POINT_NM 2
1382 #define CI_PDN_TYPE 3
1383 #define CI_PDN_ADDRESS 4
1384 #define CI_PROTOCOL_CONFIG 5
1385 #define CI_ERROR_CODE 6
1386 #define CI_ATTACH_TYPE 7
1387 #define CI_IPv4DEFAULT_ROUTER 8
1388 #define CI_ADDRESS_ALLOC 9
1389 #define CI_APN_AMBR 10
1390 #define CI_IPv6_HSGW_LLA_IID 11
1391
1392 /*
1393 * CHAP Algorithms
1394 */
1395 /* 0-4: Reserved */
1396 #define CHAP_ALG_MD5 5 /* CHAP with MD5 */
1397 #define CHAP_AGL_SHA1 6 /* CHAP with SHA-1 [Black] */
1398 /* 7-127: Unassigned */
1399 #define CHAP_ALG_MSV1 128 /* MS-CHAP */
1400 #define CHAP_ALG_MSV2 129 /* MS-CHAP-2 */
1401
1402 static const range_string chap_alg_rvals[] = {
1403 {0, 4, "Reserved"},
1404 {CHAP_ALG_MD5, CHAP_ALG_MD5, "CHAP with MD5"},
1405 {CHAP_AGL_SHA1, CHAP_AGL_SHA1, "CHAP with SHA-1"},
1406 {CHAP_ALG_MSV1, CHAP_ALG_MSV1, "MS-CHAP"},
1407 {CHAP_ALG_MSV2, CHAP_ALG_MSV2, "MS-CHAP-2"},
1408 {0, 0, NULL}
1409 };
1410
1411
1412 /*
1413 * Options. (IPCP)
1414 * https://tools.ietf.org/html/rfc1172
1415 * https://tools.ietf.org/html/rfc1332
1416 * https://tools.ietf.org/html/rfc1877
1417 * https://tools.ietf.org/html/rfc2290
1418 * https://tools.ietf.org/html/rfc3241
1419 * https://tools.ietf.org/html/rfc3545
1420 */
1421 #define CI_ADDRS 1 /* IP Addresses (deprecated) (RFC 1172) */
1422 #define CI_COMPRESS_PROTO 2 /* Compression Protocol (RFC 1332) */
1423 #define CI_ADDR 3 /* IP Address (RFC 1332) */
1424 #define CI_MOBILE_IPv4 4 /* Mobile IPv4 (RFC 2290) */
1425 #define CI_PRI_DNS 129 /* Primary DNS value (RFC 1877) */
1426 #define CI_PRI_NBNS 130 /* Primary NBNS value (RFC 1877) */
1427 #define CI_SEC_DNS 131 /* Secondary DNS value (RFC 1877) */
1428 #define CI_SEC_NBNS 132 /* Secondary NBNS value (RFC 1877) */
1429
1430 static int hf_ipcp_opt_type = -1;
1431 static int hf_ipcp_opt_length = -1;
1432 static int hf_ipcp_opt_src_address = -1;
1433 static int hf_ipcp_opt_dst_address = -1;
1434 static int hf_ipcp_opt_compress_proto = -1;
1435 static int hf_ipcp_opt_max_cid = -1;
1436 static int hf_ipcp_opt_mrru = -1;
1437 static int hf_ipcp_opt_max_slot_id = -1;
1438 static int hf_ipcp_opt_comp_slot_id = -1;
1439 static int hf_ipcp_opt_tcp_space = -1;
1440 static int hf_ipcp_opt_non_tcp_space = -1;
1441 static int hf_ipcp_opt_f_max_period = -1;
1442 static int hf_ipcp_opt_f_max_time = -1;
1443 static int hf_ipcp_opt_max_header = -1;
1444 static int hf_ipcp_data = -1;
1445 static int hf_ipcp_opt_ip_address = -1;
1446 static int hf_ipcp_opt_mobilenodehomeaddr = -1;
1447 static int hf_ipcp_opt_pri_dns_address = -1;
1448 static int hf_ipcp_opt_pri_nbns_address = -1;
1449 static int hf_ipcp_opt_sec_dns_address = -1;
1450 static int hf_ipcp_opt_sec_nbns_address = -1;
1451
1452 static int hf_ipcp_opt_rohc_type = -1;
1453 static int hf_ipcp_opt_rohc_length = -1;
1454 static int hf_ipcp_opt_rohc_profile = -1;
1455 static int hf_ipcp_opt_iphc_type = -1;
1456 static int hf_ipcp_opt_iphc_length = -1;
1457 static int hf_ipcp_opt_iphc_param = -1;
1458
1459 /*
1460 * IP Compression options
1461 */
1462 #define IPCP_ROHC 0x0003 /* RFC3241 */
1463 #define IPCP_COMPRESS_VJ_1172 0x0037 /* value defined in RFC1172 (typo) */
1464 #define IPCP_COMPRESS_VJ 0x002d /* value defined in RFC1332 (correct) */
1465 #define IPCP_COMPRESS_IPHC 0x0061 /* RFC3544 (and RFC2509) */
1466
1467 static const value_string ipcp_compress_proto_vals[] = {
1468 {IPCP_ROHC, "Robust Header Compression (ROHC)"},
1469 {IPCP_COMPRESS_VJ, "VJ compression"},
1470 {IPCP_COMPRESS_VJ_1172, "VJ compression (RFC1172-typo)"},
1471 {IPCP_COMPRESS_IPHC, "IPHC compression"},
1472 {0, NULL}
1473 };
1474
1475 /* IPHC suboptions (RFC2508, 3544) */
1476 #define IPCP_IPHC_CRTP 1
1477 #define IPCP_IPHC_ECRTP 2
1478 #define IPCP_IPHC_NEGHC 3
1479
1480 static const value_string ipcp_iphc_parameter_vals[] = {
1481 {1, "The number of contexts for TCP Space is 0"},
1482 {2, "The number of contexts for Non TCP Space is 0"},
1483 {0, NULL}
1484 };
1485
1486
1487 /* ROHC suboptions */
1488 #define IPCP_ROHC_PROFILES 1
1489
1490 /* From https://tools.ietf.org/html/rfc3095 */
1491 static const value_string ipcp_rohc_profile_vals[] = {
1492 {0x0000, "ROHC uncompressed -- no compression"},
1493 {0x0002, "ROHC UDP -- non-RTP UDP/IP compression"},
1494 {0x0003, "ROHC ESP -- ESP/IP compression"},
1495 {0, NULL}
1496 };
1497
1498 /*
1499 * Options. (bcp_ncp)
1500 1 Bridge-Identification
1501 2 Line-Identification
1502 3 MAC-Support
1503 4 Tinygram-Compression
1504 5 LAN-Identification (obsoleted)
1505 6 MAC-Address
1506 7 Spanning-Tree-Protocol (old formatted)
1507 8 IEEE 802 Tagged Frame
1508 9 Management Inline
1509 10 Bridge Control Packet Indicator
1510
1511 */
1512 #define CI_BCPNCP_BRIDGE_ID 1
1513 #define CI_BCPNCP_LINE_ID 2
1514 #define CI_BCPNCP_MAC_SUPPORT 3
1515 #define CI_BCPNCP_TINYGRAM_COMP 4
1516 #define CI_BCPNCP_LAN_ID 5
1517 #define CI_BCPNCP_MAC_ADDRESS 6
1518 #define CI_BCPNCP_STP 7
1519 #define CI_BCPNCP_IEEE_802_TAGGED_FRAME 8
1520 #define CI_BCPNCP_MANAGEMENT_INLINE 9
1521 #define CI_BCPNCP_BCP_IND 10
1522
1523 /*
1524 * Options. (OSINLCP)
1525 */
1526 #define CI_OSINLCP_ALIGN_NPDU 1 /* Alignment of the OSI NPDU (RFC 1377) */
1527
1528 static int hf_osinlcp_opt_type = -1;
1529 static int hf_osinlcp_opt_length = -1;
1530 static int hf_osinlcp_opt_alignment = -1;
1531
1532 /*
1533 * Options. (CCP)
1534 */
1535 #define CI_CCP_OUI 0 /* OUI (RFC1962) */
1536 #define CI_CCP_PREDICT1 1 /* Predictor type 1 (RFC1962) */
1537 #define CI_CCP_PREDICT2 2 /* Predictor type 2 (RFC1962) */
1538 #define CI_CCP_PUDDLE 3 /* Puddle Jumper (RFC1962) */
1539 #define CI_CCP_HPPPC 16 /* Hewlett-Packard PPC (RFC1962) */
1540 #define CI_CCP_STAC 17 /* stac Electronics LZS (RFC1974) */
1541 #define CI_CCP_MPPE 18 /* Microsoft PPE/C (RFC2118/3078) */
1542 #define CI_CCP_GFZA 19 /* Gandalf FZA (RFC1962) */
1543 #define CI_CCP_V42BIS 20 /* V.42bis compression */
1544 #define CI_CCP_BSDLZW 21 /* BSD LZW Compress (RFC1977) */
1545 #define CI_CCP_LZSDCP 23 /* LZS-DCP (RFC1967) */
1546 #define CI_CCP_MVRCA 24 /* MVRCA (Magnalink) (RFC1975) */
1547 #define CI_CCP_DCE 25 /* DCE (RFC1976) */
1548 #define CI_CCP_DEFLATE 26 /* Deflate (RFC1979) */
1549 #define CI_CCP_V44LZJH 27 /* V.44/LZJH (https://tools.ietf.org/html/draft-heath-ppp-v44-01) */
1550 #define CI_CCP_RESERVED 255 /* Reserved (RFC1962) */
1551
1552 static int hf_ccp_opt_type = -1;
1553 static int hf_ccp_opt_length = -1;
1554 static int hf_ccp_opt_oui = -1;
1555 static int hf_ccp_opt_subtype = -1;
1556 static int hf_ccp_opt_data = -1;
1557 static int hf_ccp_opt_history_count = -1;
1558 static int hf_ccp_opt_cm = -1;
1559 static int hf_ccp_opt_cm_reserved = -1;
1560 static int hf_ccp_opt_cm_check_mode = -1;
1561 static int hf_ccp_opt_supported_bits = -1;
1562 static int hf_ccp_opt_supported_bits_h = -1;
1563 static int hf_ccp_opt_supported_bits_m = -1;
1564 static int hf_ccp_opt_supported_bits_s = -1;
1565 static int hf_ccp_opt_supported_bits_l = -1;
1566 static int hf_ccp_opt_supported_bits_d = -1;
1567 static int hf_ccp_opt_supported_bits_c = -1;
1568 static int hf_ccp_opt_history = -1;
1569 static int hf_ccp_opt_version = -1;
1570 static int hf_ccp_opt_vd = -1;
1571 static int hf_ccp_opt_vd_vers = -1;
1572 static int hf_ccp_opt_vd_dict = -1;
1573 static int hf_ccp_opt_check_mode = -1;
1574 static int hf_ccp_opt_process_mode = -1;
1575 static int hf_ccp_opt_fe = -1;
1576 static int hf_ccp_opt_p = -1;
1577 static int hf_ccp_opt_History = -1; /* Different than hf_ccp_opt_history */
1578 static int hf_ccp_opt_contexts = -1;
1579 static int hf_ccp_opt_mode = -1;
1580 static int hf_ccp_opt_window = -1;
1581 static int hf_ccp_opt_method = -1;
1582 static int hf_ccp_opt_mbz = -1;
1583 static int hf_ccp_opt_chk = -1;
1584 static int hf_ccp_opt_mode_dictcount = -1;
1585 static int hf_ccp_opt_dict_size = -1;
1586 static int hf_ccp_opt_history_length = -1;
1587
1588 /*
1589 * Options. (CBCP)
1590 */
1591 #define CI_CBCP_NO_CALLBACK 1 /* No callback */
1592 #define CI_CBCP_CB_USER 2 /* Callback to a user-specified number */
1593 #define CI_CBCP_CB_PRE 3 /* Callback to a pre-specified or
1594 administrator specified number */
1595 #define CI_CBCP_CB_ANY 4 /* Callback to any of a list of numbers */
1596
1597 /*
1598 * Options. (BACP)
1599 */
1600 #define CI_BACP_FAVORED_PEER 1 /* Favored-Peer */
1601
1602 /*
1603 * Options. (BAP)
1604 */
1605 #define CI_BAP_LINK_TYPE 1 /* Link Type */
1606 #define CI_BAP_PHONE_DELTA 2 /* Phone-Delta */
1607 #define CI_BAP_NO_PHONE_NUM_NEEDED 3 /* No Phone Number Needed */
1608 #define CI_BAP_REASON 4 /* Reason */
1609 #define CI_BAP_LINK_DISC 5 /* Link Discriminator */
1610 #define CI_BAP_CALL_STATUS 6 /* Call Status */
1611
1612 static int dissect_ppp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data);
1613
1614 static const value_string pap_vals[] = {
1615 {CONFREQ, "Authenticate-Request"},
1616 {CONFACK, "Authenticate-Ack"},
1617 {CONFNAK, "Authenticate-Nak"},
1618 {0, NULL}
1619 };
1620
1621 #define CHAP_CHAL 1 /* CHAP Challenge */
1622 #define CHAP_RESP 2 /* CHAP Response */
1623 #define CHAP_SUCC 3 /* CHAP Success */
1624 #define CHAP_FAIL 4 /* CHAP Failure */
1625
1626 static const value_string chap_vals[] = {
1627 {CHAP_CHAL, "Challenge"},
1628 {CHAP_RESP, "Response"},
1629 {CHAP_SUCC, "Success"},
1630 {CHAP_FAIL, "Failure"},
1631 {0, NULL}
1632 };
1633
1634 static const value_string pppmuxcp_vals[] = {
1635 {CONFREQ, "Configuration Request"},
1636 {CONFACK, "Configuration Ack"},
1637 {0, NULL}
1638 };
1639
1640 /*
1641 * PPPMuxCP options
1642 */
1643
1644 #define CI_DEFAULT_PID 1
1645
1646 static const true_false_string tfs_pppmux_length_field = { "2 bytes", "1 byte" };
1647
1648 /*
1649 * Options. (IPv6CP)
1650 */
1651 #define CI_IPV6CP_IF_ID 1 /* Interface Identifier (RFC 2472) */
1652 #define CI_IPV6CP_COMPRESSTYPE 2 /* Compression Type (RFC 2472) */
1653
1654 /*
1655 *******************************************************************************
1656 * DETAILS : Calculate a new FCS-16 given the current FCS-16 and the new data.
1657 *******************************************************************************
1658 */
1659 static guint16
fcs16(tvbuff_t * tvbuff)1660 fcs16(tvbuff_t *tvbuff)
1661 {
1662 guint len = tvb_reported_length(tvbuff) - 2;
1663
1664 /* Check for Invalid Length */
1665 if (len == 0)
1666 return (0x0000);
1667 return crc16_ccitt_tvb(tvbuff, len);
1668 }
1669
1670 /*
1671 *******************************************************************************
1672 * DETAILS : Calculate a new FCS-32 given the current FCS-32 and the new data.
1673 *******************************************************************************
1674 */
1675 static guint32
fcs32(tvbuff_t * tvbuff)1676 fcs32(tvbuff_t *tvbuff)
1677 {
1678 guint len = tvb_reported_length(tvbuff) - 4;
1679
1680 /* Check for invalid Length */
1681 if (len == 0)
1682 return (0x00000000);
1683 return crc32_ccitt_tvb(tvbuff, len);
1684 }
1685
1686 tvbuff_t *
decode_fcs(tvbuff_t * tvb,packet_info * pinfo,proto_tree * fh_tree,int fcs_decode,int proto_offset)1687 decode_fcs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *fh_tree, int fcs_decode, int proto_offset)
1688 {
1689 tvbuff_t *next_tvb;
1690 gint len, reported_len;
1691
1692 /*
1693 * Remove the FCS, if any, from the packet data.
1694 */
1695 switch (fcs_decode) {
1696
1697 case NO_FCS:
1698 next_tvb = tvb_new_subset_remaining(tvb, proto_offset);
1699 break;
1700
1701 case FCS_16:
1702 /*
1703 * Do we have the entire packet, and does it include a 2-byte FCS?
1704 */
1705 len = tvb_captured_length_remaining(tvb, proto_offset);
1706 reported_len = tvb_reported_length_remaining(tvb, proto_offset);
1707 if (reported_len < 2 || len < 0) {
1708 /*
1709 * The packet is claimed not to even have enough data for a 2-byte
1710 * FCS, or we're already past the end of the captured data.
1711 * Don't slice anything off.
1712 */
1713 next_tvb = tvb_new_subset_remaining(tvb, proto_offset);
1714 } else if (len < reported_len) {
1715 /*
1716 * The packet is claimed to have enough data for a 2-byte FCS, but
1717 * we didn't capture all of the packet.
1718 * Slice off the 2-byte FCS from the reported length, and trim the
1719 * captured length so it's no more than the reported length; that
1720 * will slice off what of the FCS, if any, is in the captured
1721 * length.
1722 */
1723 reported_len -= 2;
1724 if (len > reported_len)
1725 len = reported_len;
1726 next_tvb = tvb_new_subset_length_caplen(tvb, proto_offset, len, reported_len);
1727 } else {
1728 /*
1729 * We have the entire packet, and it includes a 2-byte FCS.
1730 * Slice it off.
1731 */
1732 len -= 2;
1733 reported_len -= 2;
1734 next_tvb = tvb_new_subset_length_caplen(tvb, proto_offset, len, reported_len);
1735
1736 /*
1737 * Compute the FCS and put it into the tree.
1738 */
1739 proto_tree_add_checksum(fh_tree, tvb, proto_offset + len, hf_ppp_fcs_16, hf_ppp_fcs_status, &ei_ppp_fcs, pinfo, fcs16(tvb),
1740 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
1741 }
1742 break;
1743
1744 case FCS_32:
1745 /*
1746 * Do we have the entire packet, and does it include a 4-byte FCS?
1747 */
1748 len = tvb_captured_length_remaining(tvb, proto_offset);
1749 reported_len = tvb_reported_length_remaining(tvb, proto_offset);
1750 if (reported_len < 4) {
1751 /*
1752 * The packet is claimed not to even have enough data for a 4-byte
1753 * FCS. Just pass on the tvbuff as is.
1754 */
1755 next_tvb = tvb_new_subset_remaining(tvb, proto_offset);
1756 } else if (len < reported_len) {
1757 /*
1758 * The packet is claimed to have enough data for a 4-byte FCS, but
1759 * we didn't capture all of the packet.
1760 * Slice off the 4-byte FCS from the reported length, and trim the
1761 * captured length so it's no more than the reported length; that
1762 * will slice off what of the FCS, if any, is in the captured
1763 * length.
1764 */
1765 reported_len -= 4;
1766 if (len > reported_len)
1767 len = reported_len;
1768 next_tvb = tvb_new_subset_length_caplen(tvb, proto_offset, len, reported_len);
1769 } else {
1770 /*
1771 * We have the entire packet, and it includes a 4-byte FCS.
1772 * Slice it off.
1773 */
1774 len -= 4;
1775 reported_len -= 4;
1776 next_tvb = tvb_new_subset_length_caplen(tvb, proto_offset, len, reported_len);
1777
1778 /*
1779 * Compute the FCS and put it into the tree.
1780 */
1781 proto_tree_add_checksum(fh_tree, tvb, proto_offset + len, hf_ppp_fcs_32, hf_ppp_fcs_status, &ei_ppp_fcs, pinfo, fcs32(tvb),
1782 ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
1783 }
1784 break;
1785
1786 default:
1787 DISSECTOR_ASSERT_NOT_REACHED();
1788 next_tvb = NULL;
1789 break;
1790 }
1791
1792 return next_tvb;
1793 }
1794
1795 static gboolean
capture_ppp_hdlc(const guchar * pd,int offset,int len,capture_packet_info_t * cpinfo,const union wtap_pseudo_header * pseudo_header _U_)1796 capture_ppp_hdlc(const guchar *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_)
1797 {
1798 if (!BYTES_ARE_IN_FRAME(offset, len, 2))
1799 return FALSE;
1800
1801 if (pd[0] == CHDLC_ADDR_UNICAST || pd[0] == CHDLC_ADDR_MULTICAST)
1802 return call_capture_dissector(chdlc_cap_handle, pd, offset, len, cpinfo, pseudo_header);
1803
1804 if (!BYTES_ARE_IN_FRAME(offset, len, 4))
1805 return FALSE;
1806
1807 return try_capture_dissector("ppp_hdlc", pntoh16(&pd[offset + 2]), pd, offset + 4, len, cpinfo, pseudo_header);
1808 }
1809
1810 static int
dissect_lcp_vendor_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1811 dissect_lcp_vendor_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1812 {
1813 proto_tree *field_tree;
1814 proto_item *ti;
1815 int offset = 0;
1816 int len = tvb_reported_length(tvb);
1817
1818 if (!dissect_lcp_var_opt(tvb, pinfo, tree, proto_lcp_option_vendor, ett_lcp_vendor_opt, 6,
1819 &field_tree, &ti))
1820 return tvb_captured_length(tvb);
1821
1822 proto_tree_add_item(field_tree, hf_lcp_opt_oui, tvb, offset + 2, 3, ENC_BIG_ENDIAN);
1823
1824 proto_tree_add_item(field_tree, hf_lcp_opt_kind, tvb, offset + 5, 1,
1825 ENC_BIG_ENDIAN);
1826 if (len > 6) {
1827 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset + 6,
1828 len - 6, ENC_NA);
1829 }
1830
1831 return tvb_captured_length(tvb);
1832 }
1833
1834 static int
dissect_lcp_mru_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1835 dissect_lcp_mru_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1836 {
1837 proto_tree *field_tree;
1838 proto_item *ti;
1839 guint32 mru;
1840 int offset = 0;
1841
1842 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
1843 proto_lcp_option_mru, ett_lcp_mru_opt, 4,
1844 &field_tree, &ti))
1845 return tvb_captured_length(tvb);
1846
1847 proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_mru, tvb, offset + 2, 2,
1848 ENC_BIG_ENDIAN, &mru);
1849 proto_item_append_text(ti, ": %u", mru);
1850 return tvb_captured_length(tvb);
1851 }
1852
1853 static int
dissect_lcp_async_map_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1854 dissect_lcp_async_map_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1855 {
1856 proto_tree *field_tree;
1857 proto_item *tf, *ti;
1858 int offset = 0;
1859 static int * const asyncmap_fields[] = {
1860 &hf_lcp_opt_asyncmap_us, &hf_lcp_opt_asyncmap_rs,
1861 &hf_lcp_opt_asyncmap_gs, &hf_lcp_opt_asyncmap_fs,
1862 &hf_lcp_opt_asyncmap_esc, &hf_lcp_opt_asyncmap_sub,
1863 &hf_lcp_opt_asyncmap_em, &hf_lcp_opt_asyncmap_can,
1864 &hf_lcp_opt_asyncmap_etb, &hf_lcp_opt_asyncmap_syn,
1865 &hf_lcp_opt_asyncmap_nak, &hf_lcp_opt_asyncmap_dc4,
1866 &hf_lcp_opt_asyncmap_dc3, &hf_lcp_opt_asyncmap_dc2,
1867 &hf_lcp_opt_asyncmap_dc1, &hf_lcp_opt_asyncmap_dle,
1868 &hf_lcp_opt_asyncmap_si, &hf_lcp_opt_asyncmap_so,
1869 &hf_lcp_opt_asyncmap_cr, &hf_lcp_opt_asyncmap_ff,
1870 &hf_lcp_opt_asyncmap_vt, &hf_lcp_opt_asyncmap_lf,
1871 &hf_lcp_opt_asyncmap_ht, &hf_lcp_opt_asyncmap_bs,
1872 &hf_lcp_opt_asyncmap_bel, &hf_lcp_opt_asyncmap_ack,
1873 &hf_lcp_opt_asyncmap_enq, &hf_lcp_opt_asyncmap_eot,
1874 &hf_lcp_opt_asyncmap_etx, &hf_lcp_opt_asyncmap_stx,
1875 &hf_lcp_opt_asyncmap_soh, &hf_lcp_opt_asyncmap_nul,
1876 NULL
1877 };
1878
1879 static const char *ctrlchars[32] = {
1880 "NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL",
1881 "BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI",
1882 "DLE", "DC1 (XON)", "DC2", "DC3 (XOFF)", "DC4", "NAK", "SYN", "ETB",
1883 "CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US"
1884 };
1885
1886 guint32 map;
1887 gboolean anyctrlchars;
1888 int i;
1889
1890 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
1891 proto_lcp_option_async_map, ett_lcp_asyncmap_opt, 6,
1892 &field_tree, &tf))
1893 return tvb_captured_length(tvb);
1894
1895 map = tvb_get_ntohl(tvb, offset + 2);
1896 proto_item_append_text(tf, ": 0x%08x", map);
1897
1898 ti = proto_tree_add_bitmask(field_tree, tvb, offset + 2,
1899 hf_lcp_opt_asyncmap, ett_lcp_asyncmap_opt, asyncmap_fields,
1900 ENC_BIG_ENDIAN);
1901
1902 if (map == 0x00000000) {
1903 proto_item_append_text(tf, " (None)");
1904 proto_item_append_text(ti, " (None)");
1905 } else if (map == 0xffffffff) {
1906 proto_item_append_text(tf, " (All)");
1907 proto_item_append_text(ti, " (All)");
1908 } else {
1909 for (anyctrlchars = FALSE, i = 31; i >= 0; i--) {
1910 if (map & (1 << i)) {
1911 if (anyctrlchars)
1912 proto_item_append_text(tf, ", %s", ctrlchars[i]);
1913 else {
1914 anyctrlchars = TRUE;
1915 proto_item_append_text(tf, "%s", ctrlchars[i]);
1916 }
1917 }
1918 }
1919 proto_item_append_text(tf, ")");
1920 }
1921
1922 return tvb_captured_length(tvb);
1923 }
1924
1925 static int
dissect_lcp_authprot_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1926 dissect_lcp_authprot_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1927 {
1928 proto_tree *field_tree;
1929 proto_item *ti;
1930 guint32 protocol;
1931 int offset = 0;
1932 int length = tvb_reported_length(tvb);
1933
1934 if (!dissect_lcp_var_opt(tvb, pinfo, tree, proto_lcp_option_authprot, ett_lcp_authprot_opt, 4,
1935 &field_tree, &ti))
1936 return tvb_captured_length(tvb);
1937
1938 proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_auth_protocol, tvb, offset + 2,
1939 2, ENC_BIG_ENDIAN, &protocol);
1940 proto_item_append_text(ti, ": %s (0x%02x)", val_to_str_ext_const(protocol, &ppp_vals_ext, "Unknown"),
1941 protocol);
1942
1943 if (length > 4) {
1944 offset += 4;
1945 length -= 4;
1946 if (protocol == PPP_CHAP) {
1947 proto_tree_add_item(field_tree, hf_lcp_opt_algorithm, tvb, offset,
1948 1, ENC_BIG_ENDIAN);
1949 if (length > 1) {
1950 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb,
1951 offset + 1, length - 1, ENC_NA);
1952 }
1953 } else {
1954 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
1955 length, ENC_NA);
1956 }
1957 }
1958
1959 return tvb_captured_length(tvb);
1960 }
1961
1962 static int
dissect_lcp_qualprot_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1963 dissect_lcp_qualprot_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1964 {
1965 proto_tree *field_tree;
1966 proto_item *ti;
1967 guint32 protocol;
1968 int offset = 0;
1969 int length = tvb_reported_length(tvb);
1970
1971 if (!dissect_lcp_var_opt(tvb, pinfo, tree, proto_lcp_option_qualprot, ett_lcp_qualprot_opt, 4,
1972 &field_tree, &ti))
1973 return tvb_captured_length(tvb);
1974
1975 proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_quality_protocol, tvb, offset + 2,
1976 2, ENC_BIG_ENDIAN, &protocol);
1977 proto_item_append_text(ti, ": %s (0x%02x)", val_to_str_ext_const(protocol, &ppp_vals_ext, "Unknown"),
1978 protocol);
1979
1980 if (length > 4) {
1981 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset + 4,
1982 length + 4, ENC_NA);
1983 }
1984
1985 return tvb_captured_length(tvb);
1986 }
1987
1988 static int
dissect_lcp_magicnumber_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1989 dissect_lcp_magicnumber_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
1990 {
1991 proto_tree *field_tree;
1992 proto_item *ti;
1993 guint32 magic_number;
1994 int offset = 0;
1995
1996 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
1997 proto_lcp_option_magicnumber, ett_lcp_magicnumber_opt, 6,
1998 &field_tree, &ti))
1999 return tvb_captured_length(tvb);
2000
2001 proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_magic_number, tvb, offset + 2,
2002 4, ENC_BIG_ENDIAN, &magic_number);
2003 proto_item_append_text(ti, ": 0x%08x", magic_number);
2004
2005 return tvb_captured_length(tvb);
2006 }
2007
2008 static int
dissect_lcp_linkqualmon_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2009 dissect_lcp_linkqualmon_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2010 {
2011 proto_tree *field_tree;
2012 proto_item *ti, *tf;
2013 guint32 reportingperiod;
2014 int offset = 0;
2015
2016 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
2017 proto_lcp_option_linkqualmon, ett_lcp_linkqualmon_opt, 6,
2018 &field_tree, &tf))
2019 return tvb_captured_length(tvb);
2020
2021 ti = proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_reportingperiod,
2022 tvb, offset + 2, 4, ENC_BIG_ENDIAN, &reportingperiod);
2023 proto_item_append_text(tf, ": %u microsecond%s", reportingperiod, plurality(reportingperiod, "", "s"));
2024 if (reportingperiod == 0)
2025 {
2026 proto_item_append_text(ti, " [illegal]");
2027 proto_item_append_text(tf, " [illegal]");
2028 }
2029
2030 return tvb_captured_length(tvb);
2031 }
2032
2033 static int
dissect_lcp_field_compress(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2034 dissect_lcp_field_compress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2035 {
2036 return dissect_lcp_simple_opt(tvb, pinfo, tree, proto_lcp_option_field_compress, ett_lcp_pcomp_opt);
2037 }
2038
2039 static int
dissect_lcp_addr_field_compress(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2040 dissect_lcp_addr_field_compress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2041 {
2042 return dissect_lcp_simple_opt(tvb, pinfo, tree, proto_lcp_option_addr_field_compress, ett_lcp_acccomp_opt);
2043 }
2044
2045 static int
dissect_lcp_fcs_alternatives_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2046 dissect_lcp_fcs_alternatives_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2047 {
2048 proto_tree *field_tree;
2049 proto_item *tf;
2050 int offset = 0;
2051 static int * const fcs_alternatives_fields[] = {
2052 &hf_lcp_opt_fcs_alternatives_ccitt32,
2053 &hf_lcp_opt_fcs_alternatives_ccitt16,
2054 &hf_lcp_opt_fcs_alternatives_null,
2055 NULL
2056 };
2057
2058 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
2059 proto_lcp_option_fcs_alternatives, ett_lcp_fcs_alternatives_opt, 3,
2060 &field_tree, &tf))
2061 return tvb_captured_length(tvb);
2062
2063 proto_tree_add_bitmask(field_tree, tvb, offset + 2,
2064 hf_lcp_opt_fcs_alternatives, ett_lcp_fcs_alternatives_opt,
2065 fcs_alternatives_fields, ENC_NA);
2066 proto_item_append_text(tf, ": 0x%02x", tvb_get_guint8(tvb, offset + 2));
2067 return tvb_captured_length(tvb);
2068 }
2069
2070 static int
dissect_lcp_self_describing_pad_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2071 dissect_lcp_self_describing_pad_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2072 {
2073 proto_tree *field_tree;
2074 proto_item *tf, *ti;
2075 guint32 maximum;
2076 int offset = 0;
2077
2078 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
2079 proto_lcp_option_self_desc_pad, ett_lcp_self_desc_pad_opt, 3,
2080 &field_tree, &tf))
2081 return tvb_captured_length(tvb);
2082
2083 ti = proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_maximum, tvb,
2084 offset + 2, 1, ENC_BIG_ENDIAN, &maximum);
2085 proto_item_append_text(tf, ": %u octet%s", maximum, plurality(maximum, "", "s"));
2086 if (maximum == 0)
2087 {
2088 proto_item_append_text(ti, " [invalid]");
2089 proto_item_append_text(tf, " [invalid]");
2090 }
2091
2092 return tvb_captured_length(tvb);
2093 }
2094
2095 static int
dissect_lcp_numbered_mode_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2096 dissect_lcp_numbered_mode_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2097 {
2098 proto_tree *field_tree;
2099 proto_item *tf, *ti;
2100 guint32 window;
2101 int offset = 0;
2102 int length = tvb_reported_length(tvb);
2103
2104 if (!dissect_lcp_var_opt(tvb, pinfo, tree, proto_lcp_option_numbered_mode, ett_lcp_numbered_mode_opt, 3,
2105 &field_tree, &tf))
2106 return tvb_captured_length(tvb);
2107
2108 ti = proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_window, tvb,
2109 offset + 2, 1, ENC_BIG_ENDIAN, &window);
2110 proto_item_append_text(tf, ": %u frame%s", window, plurality(window, "", "s"));
2111 if (window == 0 || window > 127)
2112 {
2113 proto_item_append_text(ti, " [invalid]");
2114 proto_item_append_text(tf, " [invalid]");
2115 }
2116 if (length > 3) {
2117 proto_tree_add_item(field_tree, hf_lcp_opt_hdlc_address, tvb,
2118 offset + 3, length - 3, ENC_NA);
2119 }
2120
2121 return tvb_captured_length(tvb);
2122 }
2123
2124 /* https://tools.ietf.org/html/rfc1570#section-2.3 only lists 0-4, but
2125 * https://tools.ietf.org/html/draft-ietf-pppext-callback-ds-02 lists 5 as
2126 * "E.165 number", rather than "unassigned", and
2127 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cbcp/efee6372-3251-471e-a141-71d1e7fef21f
2128 * does indicate 6 as below. Since 5 is only mentioned in the draft, leave it
2129 * as "unassigned"?
2130 */
2131 static const value_string callback_op_vals[] = {
2132 {0, "Location is determined by user authentication"},
2133 {1, "Message is dialing string"},
2134 {2, "Message is location identifier"},
2135 {3, "Message is E.164"},
2136 {4, "Message is distinguished name"},
2137 {5, "unassigned"}, /* "Message is E.165"? */
2138 {6, "Location is determined during CBCP negotiation"},
2139 {0, NULL}
2140 };
2141
2142 static int
dissect_lcp_callback_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2143 dissect_lcp_callback_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2144 {
2145 proto_tree *field_tree;
2146 proto_item *tf;
2147 guint32 operation;
2148 int offset = 0;
2149 int length = tvb_reported_length(tvb);
2150
2151 if (!dissect_lcp_var_opt(tvb, pinfo, tree, proto_lcp_option_callback, ett_lcp_callback_opt, 3,
2152 &field_tree, &tf))
2153 return tvb_captured_length(tvb);
2154
2155 proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_operation, tvb, offset + 2, 1,
2156 ENC_BIG_ENDIAN, &operation);
2157 proto_item_append_text(tf, ": %s", val_to_str_const(operation, callback_op_vals, "Unknown"));
2158
2159 if (length > 3) {
2160 proto_tree_add_item(field_tree, hf_lcp_opt_message, tvb, offset + 3,
2161 length - 3, ENC_NA);
2162 }
2163 return tvb_captured_length(tvb);
2164 }
2165
2166 static int
dissect_lcp_compound_frames_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2167 dissect_lcp_compound_frames_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2168 {
2169 return dissect_lcp_simple_opt(tvb, pinfo, tree, proto_lcp_option_compound_frames, ett_lcp_compound_frames_opt);
2170 }
2171
2172 static int
dissect_lcp_nomdataencap_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2173 dissect_lcp_nomdataencap_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2174 {
2175 return dissect_lcp_simple_opt(tvb, pinfo, tree, proto_lcp_option_nomdataencap, ett_lcp_nomdataencap_opt);
2176 }
2177
2178 /* https://tools.ietf.org/html/rfc1990#section-5.1.1 */
2179 static int
dissect_lcp_multilink_mrru_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2180 dissect_lcp_multilink_mrru_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2181 {
2182 proto_tree *field_tree;
2183 proto_item *tf;
2184 guint32 mrru;
2185 int offset = 0;
2186
2187 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
2188 proto_lcp_option_multilink_mrru, ett_lcp_multilink_mrru_opt, 4,
2189 &field_tree, &tf))
2190 return tvb_captured_length(tvb);
2191
2192 proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_mrru, tvb, offset + 2, 2,
2193 ENC_BIG_ENDIAN, &mrru);
2194 proto_item_append_text(tf, ": %u", mrru);
2195 return tvb_captured_length(tvb);
2196 }
2197
2198 static int
dissect_lcp_multilink_ssnh_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2199 dissect_lcp_multilink_ssnh_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2200 {
2201 return dissect_lcp_simple_opt(tvb, pinfo, tree, proto_lcp_option_multilink_ssnh, ett_lcp_multilink_ssnh_opt);
2202 }
2203
2204 #define CLASS_NULL 0
2205 #define CLASS_LOCAL 1
2206 #define CLASS_IP 2
2207 #define CLASS_IEEE_802_1 3
2208 #define CLASS_PPP_MAGIC_NUMBER 4
2209 #define CLASS_PSDN_DIRECTORY_NUMBER 5
2210
2211 static const value_string multilink_ep_disc_class_vals[] = {
2212 {CLASS_NULL, "Null"},
2213 {CLASS_LOCAL, "Locally assigned address"},
2214 {CLASS_IP, "Internet Protocol (IP) address"},
2215 {CLASS_IEEE_802_1, "IEEE 802.1 globally assigned MAC address"},
2216 {CLASS_PPP_MAGIC_NUMBER, "PPP magic-number block"},
2217 {CLASS_PSDN_DIRECTORY_NUMBER, "Public switched network directory number"},
2218 {0, NULL}
2219 };
2220
2221 static int
dissect_lcp_multilink_ep_disc_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2222 dissect_lcp_multilink_ep_disc_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2223 {
2224 proto_tree *field_tree, *magic_tree;
2225 proto_item *tf, *tm;
2226 guint32 ep_disc_class;
2227 int offset = 0;
2228 int length = tvb_reported_length(tvb);
2229
2230 if (!dissect_lcp_var_opt(tvb, pinfo, tree, proto_lcp_option_multilink_ep_disc, ett_lcp_multilink_ep_disc_opt, 3,
2231 &field_tree, &tf))
2232 return tvb_captured_length(tvb);
2233
2234 proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_ep_disc_class, tvb, offset + 2,
2235 1, ENC_BIG_ENDIAN, &ep_disc_class);
2236 proto_item_append_text(tf, ": Class: %s", val_to_str_const(ep_disc_class, multilink_ep_disc_class_vals, "Unknown"));
2237
2238 if (length <= 3)
2239 return tvb_captured_length(tvb);
2240
2241 length -= 3;
2242 offset += 3;
2243 switch (ep_disc_class) {
2244 case CLASS_NULL:
2245 break;
2246
2247 case CLASS_LOCAL:
2248 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2249 length <= 20 ? length : 20, ENC_NA);
2250 break;
2251
2252 case CLASS_IP:
2253 if (length >= 4) {
2254 proto_tree_add_item(field_tree, hf_lcp_opt_ip_address, tvb, offset,
2255 4, ENC_BIG_ENDIAN);
2256 } else {
2257 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2258 length, ENC_NA);
2259 }
2260 break;
2261
2262 case CLASS_IEEE_802_1:
2263 if (length >= 6) {
2264 proto_tree_add_item(field_tree, hf_lcp_opt_802_1_address, tvb,
2265 offset, 6, ENC_NA);
2266 } else {
2267 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2268 length, ENC_NA);
2269 }
2270 break;
2271
2272 case CLASS_PPP_MAGIC_NUMBER:
2273 if (length % 4) {
2274 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2275 length, ENC_NA);
2276 } else {
2277 tm = proto_tree_add_item(field_tree, hf_lcp_opt_magic_block, tvb,
2278 offset, length <= 20 ? length : 20, ENC_NA);
2279 magic_tree = proto_item_add_subtree(tm, ett_lcp_magic_block);
2280 for ( ; length >= 4; length -= 4, offset += 4) {
2281 proto_tree_add_item(magic_tree, hf_lcp_opt_magic_number, tvb,
2282 offset, 4, ENC_BIG_ENDIAN);
2283 }
2284 }
2285 break;
2286
2287 case CLASS_PSDN_DIRECTORY_NUMBER:
2288 proto_tree_add_item(field_tree, hf_lcp_opt_psndn, tvb, offset,
2289 length > 15 ? 15 : length, ENC_NA);
2290 break;
2291
2292 default:
2293 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset, length,
2294 ENC_NA);
2295 break;
2296 }
2297 return tvb_captured_length(tvb);
2298 }
2299
2300 static const value_string dce_id_mode_vals[] = {
2301 {1, "Mode-1 (No Additional Negotiation)"},
2302 {2, "Mode-2 (Full PPP Negotiation and State Machine)"},
2303 {0, NULL}
2304 };
2305
2306 static int
dissect_lcp_dce_identifier_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2307 dissect_lcp_dce_identifier_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2308 {
2309 proto_tree *field_tree;
2310 proto_item *tf;
2311 int offset = 0;
2312 guint32 mode;
2313
2314 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
2315 proto_lcp_option_dce_identifier, ett_lcp_dce_identifier_opt, 3,
2316 &field_tree, &tf))
2317 return tvb_captured_length(tvb);
2318
2319 proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_mode, tvb, offset + 2, 1,
2320 ENC_BIG_ENDIAN, &mode);
2321 proto_item_append_text(tf, ": %s", val_to_str_const(mode, dce_id_mode_vals, "Unknown"));
2322
2323 return tvb_captured_length(tvb);
2324 }
2325
2326 static int
dissect_lcp_multilink_pp_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2327 dissect_lcp_multilink_pp_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2328 {
2329 proto_tree *field_tree;
2330 proto_item *tf;
2331 int offset = 0;
2332
2333 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
2334 proto_lcp_option_multilink_pp, ett_lcp_multilink_pp_opt, 4,
2335 &field_tree, &tf))
2336 return tvb_captured_length(tvb);
2337
2338 proto_tree_add_item(field_tree, hf_lcp_opt_unused, tvb, offset + 2, 2, ENC_NA);
2339 return tvb_captured_length(tvb);
2340 }
2341
2342 static int
dissect_lcp_bacp_link_discriminator_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2343 dissect_lcp_bacp_link_discriminator_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2344 {
2345 proto_tree *field_tree;
2346 proto_item *tf;
2347 int offset = 0;
2348 guint32 link_discrim;
2349
2350 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
2351 proto_lcp_option_link_discrim, ett_lcp_bacp_link_discrim_opt, 4,
2352 &field_tree, &tf))
2353 return tvb_captured_length(tvb);
2354
2355 proto_tree_add_item_ret_uint(field_tree, hf_lcp_opt_link_discrim, tvb, offset + 2,
2356 2, ENC_BIG_ENDIAN, &link_discrim);
2357 proto_item_append_text(tf, ": %u (0x%04x)", link_discrim, link_discrim);
2358 return tvb_captured_length(tvb);
2359 }
2360
2361 /* Assuming it's this one:
2362 * https://tools.ietf.org/html/draft-ietf-pppext-link-negot-00
2363 */
2364 static int
dissect_lcp_auth_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2365 dissect_lcp_auth_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2366 {
2367 proto_tree *field_tree;
2368 proto_item *tf;
2369 guint32 id_len;
2370 int offset = 0;
2371 int length;
2372
2373 if (!dissect_lcp_var_opt(tvb, pinfo, tree, proto_lcp_option_auth, ett_lcp_auth_opt, 3,
2374 &field_tree, &tf))
2375 return tvb_captured_length(tvb);
2376
2377 offset += 2;
2378 proto_tree_add_item_ret_length(field_tree, hf_lcp_opt_id, tvb, offset, 1, ENC_BIG_ENDIAN, &id_len);
2379
2380 length = tvb_reported_length_remaining(tvb, offset);
2381 if ((int)id_len < length) {
2382 length -= id_len;
2383 offset += id_len;
2384 proto_tree_add_item(field_tree, hf_lcp_opt_data, tvb, offset,
2385 length, ENC_NA);
2386 }
2387 return tvb_captured_length(tvb);
2388 }
2389
2390 /* Assuming it's this one:
2391 * https://tools.ietf.org/html/draft-ietf-pppext-cobs-00
2392 */
2393 static int
dissect_lcp_cobs_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2394 dissect_lcp_cobs_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2395 {
2396 proto_tree *field_tree;
2397 proto_item *tf;
2398 int offset = 0;
2399 static int * const cobs_flags_fields[] = {
2400 &hf_lcp_opt_cobs_flags_res,
2401 &hf_lcp_opt_cobs_flags_pre,
2402 &hf_lcp_opt_cobs_flags_zxe,
2403 NULL
2404 };
2405
2406 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
2407 proto_lcp_option_cobs, ett_lcp_cobs_opt, 3,
2408 &field_tree, &tf))
2409 return tvb_captured_length(tvb);
2410
2411 proto_tree_add_bitmask(field_tree, tvb, offset + 2, hf_lcp_opt_cobs_flags,
2412 ett_lcp_cobs_opt, cobs_flags_fields, ENC_NA);
2413 return tvb_captured_length(tvb);
2414 }
2415
2416 static int
dissect_lcp_prefix_elision_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2417 dissect_lcp_prefix_elision_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2418 {
2419 proto_tree *field_tree;
2420 proto_item *tf;
2421 guint8 pre_len;
2422 int offset = 0;
2423 int length = tvb_reported_length(tvb);
2424
2425 if (!dissect_lcp_var_opt(tvb, pinfo, tree, proto_lcp_option_prefix_elision, ett_lcp_prefix_elision_opt, 2,
2426 &field_tree, &tf))
2427 return tvb_captured_length(tvb);
2428
2429 if (length > 2) {
2430 length -= 2;
2431 offset += 2;
2432 while (length >= 2) {
2433 proto_tree_add_item(field_tree, hf_lcp_opt_class, tvb, offset, 1,
2434 ENC_BIG_ENDIAN);
2435 pre_len = tvb_get_guint8(tvb, offset + 1);
2436 if (pre_len + 2 <= length) {
2437 proto_tree_add_item(field_tree, hf_lcp_opt_prefix, tvb,
2438 offset + 2, 1, ENC_NA);
2439 length -= (2 + pre_len);
2440 } else {
2441 /* Prefix length doesn't make sense, so bail out */
2442 length = 0;
2443 }
2444 }
2445 }
2446
2447 return tvb_captured_length(tvb);
2448 }
2449
2450 static const value_string ml_hdr_fmt_code_vals[] = {
2451 {2, "Long sequence number fragment format with classes"},
2452 {6, "Short sequence number fragment format with classes"},
2453 {0, NULL}
2454 };
2455
2456 static int
dissect_lcp_multilink_hdr_fmt_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2457 dissect_lcp_multilink_hdr_fmt_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2458 {
2459 proto_tree *field_tree;
2460 proto_item *tf;
2461 int offset = 0;
2462
2463 if (!dissect_lcp_fixed_opt(tvb, pinfo, tree,
2464 proto_lcp_option_multilink_hdr_fmt, ett_multilink_hdr_fmt_opt, 4,
2465 &field_tree, &tf))
2466 return tvb_captured_length(tvb);
2467
2468 proto_tree_add_item(field_tree, hf_lcp_opt_code, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
2469 proto_tree_add_item(field_tree, hf_lcp_opt_max_susp_classes, tvb,
2470 offset + 3, 1, ENC_BIG_ENDIAN);
2471 return tvb_captured_length(tvb);
2472 }
2473
2474
2475 /* Character sets from https://www.iana.org/assignments/character-sets. */
2476 static const value_string charset_vals[] = {
2477 {3, "ANSI_X3.4-1968"},
2478 {4, "ISO_8859-1:1987"},
2479 {5, "ISO_8859-2:1987"},
2480 {6, "ISO_8859-3:1988"},
2481 {7, "ISO_8859-4:1988"},
2482 {8, "ISO_8859-5:1988"},
2483 {9, "ISO_8859-6:1987"},
2484 {10, "ISO_8859-7:1987"},
2485 {11, "ISO_8859-8:1988"},
2486 {12, "ISO_8859-9:1989"},
2487 {13, "ISO-8859-10"},
2488 {14, "ISO_6937-2-add"},
2489 {15, "JIS_X0201"},
2490 {16, "JIS_Encoding"},
2491 {17, "Shift_JIS"},
2492 {18, "Extended_UNIX_Code_Packed_Format_for_Japanese"},
2493 {19, "Extended_UNIX_Code_Fixed_Width_for_Japanese"},
2494 {20, "BS_4730"},
2495 {21, "SEN_850200_C"},
2496 {22, "IT"},
2497 {23, "ES"},
2498 {24, "DIN_66003"},
2499 {25, "NS_4551-1"},
2500 {26, "NF_Z_62-010"},
2501 {27, "ISO-10646-UTF-1"},
2502 {28, "ISO_646.basic:1983"},
2503 {29, "INVARIANT"},
2504 {30, "ISO_646.irv:1983"},
2505 {31, "NATS-SEFI"},
2506 {32, "NATS-SEFI-ADD"},
2507 {33, "NATS-DANO"},
2508 {34, "NATS-DANO-ADD"},
2509 {35, "SEN_850200_B"},
2510 {36, "KS_C_5601-1987"},
2511 {37, "ISO-2022-KR"},
2512 {38, "EUC-KR"},
2513 {39, "ISO-2022-JP"},
2514 {40, "ISO-2022-JP-2"},
2515 {41, "JIS_C6220-1969-jp"},
2516 {42, "JIS_C6220-1969-ro"},
2517 {43, "PT"},
2518 {44, "greek7-old"},
2519 {45, "latin-greek"},
2520 {46, "NF_Z_62-010_(1973)"},
2521 {47, "Latin-greek-1"},
2522 {48, "ISO_5427"},
2523 {49, "JIS_C6226-1978"},
2524 {50, "BS_viewdata"},
2525 {51, "INIS"},
2526 {52, "INIS-8"},
2527 {53, "INIS-cyrillic"},
2528 {54, "ISO_5427:1981"},
2529 {55, "ISO_5428:1980"},
2530 {56, "GB_1988-80"},
2531 {57, "GB_2312-80"},
2532 {58, "NS_4551-2"},
2533 {59, "videotex-suppl"},
2534 {60, "PT2"},
2535 {61, "ES2"},
2536 {62, "MSZ_7795.3"},
2537 {63, "JIS_C6226-1983"},
2538 {64, "greek7"},
2539 {65, "ASMO_449"},
2540 {66, "iso-ir-90"},
2541 {67, "JIS_C6229-1984-a"},
2542 {68, "JIS_C6229-1984-b"},
2543 {69, "JIS_C6229-1984-b-add"},
2544 {70, "JIS_C6229-1984-hand"},
2545 {71, "JIS_C6229-1984-hand-add"},
2546 {72, "JIS_C6229-1984-kana"},
2547 {73, "ISO_2033-1983"},
2548 {74, "ANSI_X3.110-1983"},
2549 {75, "T.61-7bit"},
2550 {76, "T.61-8bit"},
2551 {77, "ECMA-cyrillic"},
2552 {78, "CSA_Z243.4-1985-1"},
2553 {79, "CSA_Z243.4-1985-2"},
2554 {80, "CSA_Z243.4-1985-gr"},
2555 {81, "ISO_8859-6-E"},
2556 {82, "ISO_8859-6-I"},
2557 {83, "T.101-G2"},
2558 {84, "ISO_8859-8-E"},
2559 {85, "ISO_8859-8-I"},
2560 {86, "CSN_369103"},
2561 {87, "JUS_I.B1.002"},
2562 {88, "IEC_P27-1"},
2563 {89, "JUS_I.B1.003-serb"},
2564 {90, "JUS_I.B1.003-mac"},
2565 {91, "greek-ccitt"},
2566 {92, "NC_NC00-10:81"},
2567 {93, "ISO_6937-2-25"},
2568 {94, "GOST_19768-74"},
2569 {95, "ISO_8859-supp"},
2570 {96, "ISO_10367-box"},
2571 {97, "latin-lap"},
2572 {98, "JIS_X0212-1990"},
2573 {99, "DS_2089"},
2574 {100, "us-dk"},
2575 {101, "dk-us"},
2576 {102, "KSC5636"},
2577 {103, "UNICODE-1-1-UTF-7"},
2578 {104, "ISO-2022-CN"},
2579 {105, "ISO-2022-CN-EXT"},
2580 {106, "UTF-8"},
2581 {109, "ISO-8859-13"},
2582 {110, "ISO-8859-14"},
2583 {111, "ISO-8859-15"},
2584 {112, "ISO-8859-16"},
2585 {113, "GBK"},
2586 {114, "GB18030"},
2587 {115, "OSD_EBCDIC_DF04_15"},
2588 {116, "OSD_EBCDIC_DF03_IRV"},
2589 {117, "OSD_EBCDIC_DF04_1"},
2590 {118, "ISO-11548-1"},
2591 {119, "KZ-1048"},
2592 {1000, "ISO-10646-UCS-2"},
2593 {1001, "ISO-10646-UCS-4"},
2594 {1002, "ISO-10646-UCS-Basic"},
2595 {1003, "ISO-10646-Unicode-Latin1"},
2596 {1004, "ISO-10646-J-1"},
2597 {1005, "ISO-Unicode-IBM-1261"},
2598 {1006, "ISO-Unicode-IBM-1268"},
2599 {1007, "ISO-Unicode-IBM-1276"},
2600 {1008, "ISO-Unicode-IBM-1264"},
2601 {1009, "ISO-Unicode-IBM-1265"},
2602 {1010, "UNICODE-1-1"},
2603 {1011, "SCSU"},
2604 {1012, "UTF-7"},
2605 {1013, "UTF-16BE"},
2606 {1014, "UTF-16LE"},
2607 {1015, "UTF-16"},
2608 {1016, "CESU-8"},
2609 {1017, "UTF-32"},
2610 {1018, "UTF-32BE"},
2611 {1019, "UTF-32LE"},
2612 {1020, "BOCU-1"},
2613 {2000, "ISO-8859-1-Windows-3.0-Latin-1"},
2614 {2001, "ISO-8859-1-Windows-3.1-Latin-1"},
2615 {2002, "ISO-8859-2-Windows-Latin-2"},
2616 {2003, "ISO-8859-9-Windows-Latin-5"},
2617 {2004, "hp-roman8"},
2618 {2005, "Adobe-Standard-Encoding"},
2619 {2006, "Ventura-US"},
2620 {2007, "Ventura-International"},
2621 {2008, "DEC-MCS"},
2622 {2009, "IBM850"},
2623 {2010, "IBM852"},
2624 {2011, "IBM437"},
2625 {2012, "PC8-Danish-Norwegian"},
2626 {2013, "IBM862"},
2627 {2014, "PC8-Turkish"},
2628 {2015, "IBM-Symbols"},
2629 {2016, "IBM-Thai"},
2630 {2017, "HP-Legal"},
2631 {2018, "HP-Pi-font"},
2632 {2019, "HP-Math8"},
2633 {2020, "Adobe-Symbol-Encoding"},
2634 {2021, "HP-DeskTop"},
2635 {2022, "Ventura-Math"},
2636 {2023, "Microsoft-Publishing"},
2637 {2024, "Windows-31J"},
2638 {2025, "GB2312"},
2639 {2026, "Big5"},
2640 {2027, "macintosh"},
2641 {2028, "IBM037"},
2642 {2029, "IBM038"},
2643 {2030, "IBM273"},
2644 {2031, "IBM274"},
2645 {2032, "IBM275"},
2646 {2033, "IBM277"},
2647 {2034, "IBM278"},
2648 {2035, "IBM280"},
2649 {2036, "IBM281"},
2650 {2037, "IBM284"},
2651 {2038, "IBM285"},
2652 {2039, "IBM290"},
2653 {2040, "IBM297"},
2654 {2041, "IBM420"},
2655 {2042, "IBM423"},
2656 {2043, "IBM424"},
2657 {2044, "IBM500"},
2658 {2045, "IBM851"},
2659 {2046, "IBM855"},
2660 {2047, "IBM857"},
2661 {2048, "IBM860"},
2662 {2049, "IBM861"},
2663 {2050, "IBM863"},
2664 {2051, "IBM864"},
2665 {2052, "IBM865"},
2666 {2053, "IBM868"},
2667 {2054, "IBM869"},
2668 {2055, "IBM870"},
2669 {2056, "IBM871"},
2670 {2057, "IBM880"},
2671 {2058, "IBM891"},
2672 {2059, "IBM903"},
2673 {2060, "IBM904"},
2674 {2061, "IBM905"},
2675 {2062, "IBM918"},
2676 {2063, "IBM1026"},
2677 {2064, "EBCDIC-AT-DE"},
2678 {2065, "EBCDIC-AT-DE-A"},
2679 {2066, "EBCDIC-CA-FR"},
2680 {2067, "EBCDIC-DK-NO"},
2681 {2068, "EBCDIC-DK-NO-A"},
2682 {2069, "EBCDIC-FI-SE"},
2683 {2070, "EBCDIC-FI-SE-A"},
2684 {2071, "EBCDIC-FR"},
2685 {2072, "EBCDIC-IT"},
2686 {2073, "EBCDIC-PT"},
2687 {2074, "EBCDIC-ES"},
2688 {2075, "EBCDIC-ES-A"},
2689 {2076, "EBCDIC-ES-S"},
2690 {2077, "EBCDIC-UK"},
2691 {2078, "EBCDIC-US"},
2692 {2079, "UNKNOWN-8BIT"},
2693 {2080, "MNEMONIC"},
2694 {2081, "MNEM"},
2695 {2082, "VISCII"},
2696 {2083, "VIQR"},
2697 {2084, "KOI8-R"},
2698 {2085, "HZ-GB-2312"},
2699 {2086, "IBM866"},
2700 {2087, "IBM775"},
2701 {2088, "KOI8-U"},
2702 {2089, "IBM00858"},
2703 {2090, "IBM00924"},
2704 {2091, "IBM01140"},
2705 {2092, "IBM01141"},
2706 {2093, "IBM01142"},
2707 {2094, "IBM01143"},
2708 {2095, "IBM01144"},
2709 {2096, "IBM01145"},
2710 {2097, "IBM01146"},
2711 {2098, "IBM01147"},
2712 {2099, "IBM01148"},
2713 {2100, "IBM01149"},
2714 {2101, "Big5-HKSCS"},
2715 {2102, "IBM1047"},
2716 {2103, "PTCP154"},
2717 {2104, "Amiga-1251"},
2718 {2105, "KOI7-switched"},
2719 {2106, "BRF"},
2720 {2107, "TSCII"},
2721 {2108, "CP51932"},
2722 {2109, "windows-874"},
2723 {2250, "windows-1250"},
2724 {2251, "windows-1251"},
2725 {2252, "windows-1252"},
2726 {2253, "windows-1253"},
2727 {2254, "windows-1254"},
2728 {2255, "windows-1255"},
2729 {2256, "windows-1256"},
2730 {2257, "windows-1257"},
2731 {2258, "windows-1258"},
2732 {2259, "TIS-620"},
2733 {2260, "CP50220"},
2734 {0, NULL}
2735 };
2736 static value_string_ext charset_vals_ext = VALUE_STRING_EXT_INIT(charset_vals);
2737
2738 static int
dissect_lcp_internationalization_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2739 dissect_lcp_internationalization_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2740 {
2741 proto_tree *field_tree;
2742 proto_item *tf;
2743 int offset = 0;
2744 int length = tvb_reported_length(tvb);
2745
2746 if (!dissect_lcp_var_opt(tvb, pinfo, tree, proto_lcp_option_internationalization, ett_lcp_internationalization_opt, 7,
2747 &field_tree, &tf))
2748 return tvb_captured_length(tvb);
2749
2750 proto_tree_add_item(field_tree, hf_lcp_opt_MIBenum, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
2751 proto_tree_add_item(field_tree, hf_lcp_opt_language_tag, tvb, offset + 6,
2752 length - 6, ENC_ASCII|ENC_NA);
2753
2754 return tvb_captured_length(tvb);
2755 }
2756
2757 static int
dissect_lcp_sonet_sdh_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2758 dissect_lcp_sonet_sdh_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2759 {
2760 return dissect_lcp_simple_opt(tvb, pinfo, tree, proto_lcp_option_sonet_sdh, ett_lcp_sonet_sdh_opt);
2761 }
2762
2763 static void
dissect_ipcp_opt_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)2764 dissect_ipcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
2765 const char *name)
2766 {
2767 guint8 type;
2768
2769 type = tvb_get_guint8(tvb, offset);
2770 proto_tree_add_uint_format_value(tree, hf_ipcp_opt_type, tvb, offset, 1,
2771 type, "%s (%u)", name, type);
2772 proto_tree_add_item(tree, hf_ipcp_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
2773 }
2774
2775 static gboolean
dissect_ipcp_fixed_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)2776 dissect_ipcp_fixed_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2777 int proto, int ett, int expected_length,
2778 proto_tree** ret_tree, proto_item** ret_item)
2779 {
2780 if (!ppp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), expected_length))
2781 return FALSE;
2782
2783 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, expected_length, ENC_NA);
2784 *ret_tree = proto_item_add_subtree(*ret_item, ett);
2785
2786 dissect_ipcp_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
2787 return TRUE;
2788 }
2789
2790 /* https://tools.ietf.org/html/rfc1172#section-5.1 */
2791 static int
dissect_ipcp_addrs_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2792 dissect_ipcp_addrs_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2793 {
2794 proto_tree *field_tree;
2795 proto_item *tf;
2796 int offset = 0;
2797
2798 if (!dissect_ipcp_fixed_opt(tvb, pinfo, tree, proto_ipcp_option_addrs , ett_ipcp_ipaddrs_opt, 10,
2799 &field_tree, &tf))
2800 return tvb_captured_length(tvb);
2801
2802 proto_tree_add_item(field_tree, hf_ipcp_opt_src_address, tvb, offset + 2,
2803 4, ENC_BIG_ENDIAN);
2804 proto_tree_add_item(field_tree, hf_ipcp_opt_dst_address, tvb, offset + 6,
2805 4, ENC_BIG_ENDIAN);
2806 return tvb_captured_length(tvb);
2807 }
2808
2809 static const true_false_string tfs_comp_slot_id = {
2810 "The slot identifier may be compressed",
2811 "The slot identifier must not be compressed"
2812 };
2813
2814 /* https://tools.ietf.org/html/rfc1332#section-3.2 */
2815 static int
dissect_ipcp_compress_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2816 dissect_ipcp_compress_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2817 {
2818 proto_tree *field_tree;
2819 proto_item *tf;
2820 int offset = 0;
2821 int length = tvb_reported_length(tvb);
2822 guint16 us;
2823
2824 tf = proto_tree_add_item(tree, proto_ipcp_option_compress, tvb, 0, length, ENC_NA);
2825 field_tree = proto_item_add_subtree(tf, ett_ipcp_compress_opt);
2826
2827 dissect_ipcp_opt_type_len(tvb, 0, field_tree, proto_registrar_get_name(proto_ipcp_option_compress));
2828 proto_tree_add_item(field_tree, hf_ipcp_opt_compress_proto, tvb,
2829 offset + 2, 2, ENC_BIG_ENDIAN);
2830 us = tvb_get_ntohs(tvb, offset + 2);
2831 switch (us) {
2832 case IPCP_ROHC:
2833 proto_tree_add_item(field_tree, hf_ipcp_opt_max_cid, tvb, offset + 4,
2834 2, ENC_BIG_ENDIAN);
2835 proto_tree_add_item(field_tree, hf_ipcp_opt_mrru, tvb, offset + 6, 2,
2836 ENC_BIG_ENDIAN);
2837 proto_tree_add_item(field_tree, hf_ipcp_opt_max_header, tvb,
2838 offset + 8, 2, ENC_BIG_ENDIAN);
2839
2840 if (length > 10) {
2841 proto_tree *subopt_tree;
2842
2843 /* suboptions */
2844 offset += 10;
2845 length -= 10;
2846 subopt_tree = proto_tree_add_subtree_format(field_tree, tvb, offset, length,
2847 ett_ipcp_compress_opt, NULL, "Suboptions: (%u byte%s)", length, plurality(length, "", "s"));
2848
2849 ppp_dissect_options(tvb, offset, length, ipcp_rohc_suboption_table, pinfo, subopt_tree);
2850 }
2851 break;
2852
2853 case IPCP_COMPRESS_VJ_1172:
2854 case IPCP_COMPRESS_VJ:
2855 proto_tree_add_item(field_tree, hf_ipcp_opt_max_slot_id, tvb,
2856 offset + 4, 1, ENC_BIG_ENDIAN);
2857 proto_tree_add_item(field_tree, hf_ipcp_opt_comp_slot_id, tvb,
2858 offset + 5, 1, ENC_NA);
2859 break;
2860
2861 case IPCP_COMPRESS_IPHC:
2862 proto_tree_add_item(field_tree, hf_ipcp_opt_tcp_space, tvb, offset + 4,
2863 2, ENC_BIG_ENDIAN);
2864 proto_tree_add_item(field_tree, hf_ipcp_opt_non_tcp_space, tvb,
2865 offset + 6, 2, ENC_BIG_ENDIAN);
2866 us = tvb_get_ntohs(tvb, offset + 8);
2867 proto_tree_add_uint_format_value(field_tree, hf_ipcp_opt_f_max_period,
2868 tvb, offset + 8, 2, us, "%u%s", us,
2869 (us == 0) ? " (infinity)" : "");
2870 us = tvb_get_ntohs(tvb, offset + 10);
2871 proto_tree_add_uint_format_value(field_tree, hf_ipcp_opt_f_max_time,
2872 tvb, offset + 10, 2, us, "%u%s", us,
2873 (us == 0) ? " (infinity)" : "");
2874 proto_tree_add_item(field_tree, hf_ipcp_opt_max_header, tvb,
2875 offset + 12, 2, ENC_BIG_ENDIAN);
2876
2877 if ( length > 14 ) {
2878 proto_tree *subopt_tree;
2879
2880 /* suboptions */
2881 offset += 14;
2882 length -= 14;
2883 subopt_tree = proto_tree_add_subtree_format(field_tree, tvb, offset, length,
2884 ett_ipcp_compress_opt, NULL, "Suboptions: (%u byte%s)", length, plurality(length, "", "s"));
2885 ppp_dissect_options(tvb, offset, length, ipcp_iphc_suboption_table, pinfo, subopt_tree);
2886 }
2887 break;
2888
2889 default:
2890 if (length > 4) {
2891 proto_tree_add_item(field_tree, hf_ipcp_data, tvb, offset + 4,
2892 length - 4, ENC_NA);
2893 }
2894 break;
2895 }
2896
2897 return tvb_captured_length(tvb);
2898 }
2899
2900 static void
dissect_ipcp_opt_rohc_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)2901 dissect_ipcp_opt_rohc_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
2902 const char *name)
2903 {
2904 guint8 type;
2905
2906 type = tvb_get_guint8(tvb, offset);
2907 proto_tree_add_uint_format_value(tree, hf_ipcp_opt_rohc_type, tvb, offset,
2908 1, type, "%s (%u)", name, type);
2909 proto_tree_add_item(tree, hf_ipcp_opt_rohc_length, tvb, offset + 1, 1,
2910 ENC_BIG_ENDIAN);
2911 }
2912
2913 static int
dissect_ipcp_rohc_profiles_opt(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)2914 dissect_ipcp_rohc_profiles_opt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
2915 {
2916 proto_tree *field_tree;
2917 proto_item *tf;
2918 int length = tvb_reported_length(tvb);
2919 int offset = 0;
2920
2921 tf = proto_tree_add_item(tree, proto_ipcp_rohc_option_profiles, tvb, offset, length, ENC_NA);
2922 field_tree = proto_item_add_subtree(tf, ett_ipcp_rohc_profiles_opt);
2923
2924 dissect_ipcp_opt_rohc_type_len(tvb, offset, field_tree, proto_registrar_get_name(proto_ipcp_rohc_option_profiles));
2925 if (length <= 2)
2926 return tvb_captured_length(tvb);
2927
2928 for (offset += 2, length -= 2; length >= 2; length -= 2, offset += 2) {
2929 proto_tree_add_item(field_tree, hf_ipcp_opt_rohc_profile, tvb,
2930 offset, 2, ENC_BIG_ENDIAN);
2931 }
2932 return tvb_captured_length(tvb);
2933 }
2934
2935 static void
dissect_ipcp_opt_iphc_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)2936 dissect_ipcp_opt_iphc_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
2937 const char *name)
2938 {
2939 guint8 type;
2940
2941 type = tvb_get_guint8(tvb, offset);
2942 proto_tree_add_uint_format_value(tree, hf_ipcp_opt_iphc_type, tvb, offset,
2943 1, type, "%s (%u)", name, type);
2944 proto_tree_add_item(tree, hf_ipcp_opt_iphc_length, tvb, offset + 1, 1,
2945 ENC_BIG_ENDIAN);
2946 }
2947
2948 static gboolean
dissect_ipcp_iphc_fixed_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)2949 dissect_ipcp_iphc_fixed_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
2950 int proto, int ett, int expected_length,
2951 proto_tree** ret_tree, proto_item** ret_item)
2952 {
2953 if (!ppp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), expected_length))
2954 return FALSE;
2955
2956 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, expected_length, ENC_NA);
2957 *ret_tree = proto_item_add_subtree(*ret_item, ett);
2958
2959 dissect_ipcp_opt_iphc_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
2960 return TRUE;
2961 }
2962
2963 static int
dissect_ipcp_iphc_rtp_compress(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2964 dissect_ipcp_iphc_rtp_compress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2965 {
2966 proto_tree *field_tree;
2967 proto_item *tf;
2968
2969 dissect_ipcp_iphc_fixed_opt(tvb, pinfo, tree, proto_ipcp_iphc_option_rtp_compress, ett_ipcp_iphc_rtp_compress_opt, 2,
2970 &field_tree, &tf);
2971 return tvb_captured_length(tvb);
2972 }
2973
2974 static int
dissect_ipcp_iphc_enhanced_rtp_compress(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2975 dissect_ipcp_iphc_enhanced_rtp_compress(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2976 {
2977 proto_tree *field_tree;
2978 proto_item *tf;
2979
2980 dissect_ipcp_iphc_fixed_opt(tvb, pinfo, tree, proto_ipcp_iphc_option_enhanced_rtp_compress, ett_ipcp_iphc_enhanced_rtp_compress_opt, 2,
2981 &field_tree, &tf);
2982 return tvb_captured_length(tvb);
2983 }
2984
2985 static int
dissect_ipcp_iphc_neghdrcomp_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2986 dissect_ipcp_iphc_neghdrcomp_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
2987 {
2988 proto_tree *field_tree;
2989 proto_item *tf;
2990 int offset = 0;
2991
2992 if (!dissect_ipcp_iphc_fixed_opt(tvb, pinfo, tree, proto_ipcp_iphc_option_neghdrcomp, ett_ipcp_iphc_neghdrcomp_opt, 3,
2993 &field_tree, &tf))
2994 return tvb_captured_length(tvb);
2995
2996 proto_tree_add_item(field_tree, hf_ipcp_opt_iphc_param, tvb, offset + 2, 1,
2997 ENC_BIG_ENDIAN);
2998 return tvb_captured_length(tvb);
2999 }
3000
3001 static int
dissect_ipcp_addr_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3002 dissect_ipcp_addr_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3003 {
3004 proto_tree *field_tree;
3005 proto_item *tf;
3006 int offset = 0;
3007
3008 if (!dissect_ipcp_fixed_opt(tvb, pinfo, tree, proto_ipcp_option_addr, ett_ipcp_ipaddr_opt, 6,
3009 &field_tree, &tf))
3010 return tvb_captured_length(tvb);
3011
3012 proto_tree_add_item(field_tree, hf_ipcp_opt_ip_address, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
3013 return tvb_captured_length(tvb);
3014 }
3015
3016 static int
dissect_ipcp_mobileipv4_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3017 dissect_ipcp_mobileipv4_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3018 {
3019 proto_tree *field_tree;
3020 proto_item *tf;
3021 int offset = 0;
3022
3023 if (!dissect_ipcp_fixed_opt(tvb, pinfo, tree, proto_ipcp_option_mobileipv4, ett_ipcp_mobileipv4_opt, 6,
3024 &field_tree, &tf))
3025 return tvb_captured_length(tvb);
3026
3027 proto_tree_add_item(field_tree, hf_ipcp_opt_mobilenodehomeaddr, tvb,
3028 offset + 2, 4, ENC_BIG_ENDIAN);
3029 return tvb_captured_length(tvb);
3030 }
3031
3032 static int
dissect_ipcp_pri_dns_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3033 dissect_ipcp_pri_dns_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3034 {
3035 proto_tree *field_tree;
3036 proto_item *tf;
3037 int offset = 0;
3038
3039 if (!dissect_ipcp_fixed_opt(tvb, pinfo, tree, proto_ipcp_option_pri_dns, ett_ipcp_pridns_opt, 6,
3040 &field_tree, &tf))
3041 return tvb_captured_length(tvb);
3042
3043 proto_tree_add_item(field_tree, hf_ipcp_opt_pri_dns_address, tvb,
3044 offset + 2, 4, ENC_BIG_ENDIAN);
3045 return tvb_captured_length(tvb);
3046 }
3047
3048 static int
dissect_ipcp_pri_nbns_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3049 dissect_ipcp_pri_nbns_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3050 {
3051 proto_tree *field_tree;
3052 proto_item *tf;
3053 int offset = 0;
3054
3055 if (!dissect_ipcp_fixed_opt(tvb, pinfo, tree, proto_ipcp_option_pri_nbns, ett_ipcp_prinbns_opt, 6,
3056 &field_tree, &tf))
3057 return tvb_captured_length(tvb);
3058
3059 proto_tree_add_item(field_tree, hf_ipcp_opt_pri_nbns_address, tvb,
3060 offset + 2, 4, ENC_BIG_ENDIAN);
3061 return tvb_captured_length(tvb);
3062 }
3063
3064 static int
dissect_ipcp_sec_dns_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3065 dissect_ipcp_sec_dns_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3066 {
3067 proto_tree *field_tree;
3068 proto_item *tf;
3069 int offset = 0;
3070
3071 if (!dissect_ipcp_fixed_opt(tvb, pinfo, tree, proto_ipcp_option_sec_dns, ett_ipcp_secdns_opt, 6,
3072 &field_tree, &tf))
3073 return tvb_captured_length(tvb);
3074
3075 proto_tree_add_item(field_tree, hf_ipcp_opt_sec_dns_address, tvb,
3076 offset + 2, 4, ENC_BIG_ENDIAN);
3077 return tvb_captured_length(tvb);
3078 }
3079
3080 static int
dissect_ipcp_sec_nbns_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3081 dissect_ipcp_sec_nbns_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3082 {
3083 proto_tree *field_tree;
3084 proto_item *tf;
3085 int offset = 0;
3086
3087 if (!dissect_ipcp_fixed_opt(tvb, pinfo, tree, proto_ipcp_option_sec_nbns, ett_ipcp_secnbns_opt, 6,
3088 &field_tree, &tf))
3089 return tvb_captured_length(tvb);
3090
3091 proto_tree_add_item(field_tree, hf_ipcp_opt_sec_nbns_address, tvb,
3092 offset + 2, 4, ENC_BIG_ENDIAN);
3093 return tvb_captured_length(tvb);
3094 }
3095
3096 static void
dissect_bcp_ncp_opt_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)3097 dissect_bcp_ncp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
3098 const char *name)
3099 {
3100 guint8 type;
3101
3102 type = tvb_get_guint8(tvb, offset);
3103 proto_tree_add_uint_format_value(tree, hf_bcp_ncp_opt_type, tvb, offset, 1,
3104 type, "%s (%u)", name, type);
3105 offset++;
3106 proto_tree_add_item(tree, hf_bcp_ncp_opt_length, tvb, offset, 1,
3107 ENC_BIG_ENDIAN);
3108 }
3109
3110 static gboolean
dissect_bcp_ncp_fixed_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)3111 dissect_bcp_ncp_fixed_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3112 int proto, int ett, int expected_length,
3113 proto_tree** ret_tree, proto_item** ret_item)
3114 {
3115 if (!ppp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), expected_length))
3116 return FALSE;
3117
3118 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, expected_length, ENC_NA);
3119 *ret_tree = proto_item_add_subtree(*ret_item, ett);
3120
3121 dissect_bcp_ncp_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
3122 return TRUE;
3123 }
3124
3125 /*
3126 0 1 2 3
3127 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
3128 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3129 | Type | Length | LAN Segment Number |Bridge#|
3130 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3131
3132 */
3133 static int
dissect_bcp_ncp_bridge_id(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3134 dissect_bcp_ncp_bridge_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3135 {
3136 proto_tree* field_tree;
3137 proto_item* tf;
3138 int offset = 0;
3139
3140 if (!dissect_bcp_ncp_fixed_opt(tvb, pinfo, tree, proto_bcp_ncp_option_bridge_id, ett_bcp_ncp_bridge_id_opt, 4,
3141 &field_tree, &tf))
3142 return tvb_captured_length(tvb);
3143
3144 proto_tree_add_item(field_tree, hf_bcp_ncp_lan_seg_no, tvb, offset+2, 2, ENC_BIG_ENDIAN);
3145 proto_tree_add_item(field_tree, hf_bcp_ncp_bridge_no, tvb, offset+2, 2, ENC_BIG_ENDIAN);
3146
3147 return tvb_captured_length(tvb);
3148 }
3149
3150 /*
3151 0 1 2 3
3152 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
3153 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3154 | Type | Length | LAN Segment Number |Bridge#|
3155 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3156 */
3157 static int
dissect_bcp_ncp_line_id(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3158 dissect_bcp_ncp_line_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3159 {
3160 proto_tree* field_tree;
3161 proto_item* tf;
3162 int offset = 0;
3163
3164 if (!dissect_bcp_ncp_fixed_opt(tvb, pinfo, tree, proto_bcp_ncp_option_line_id, ett_bcp_ncp_line_id_opt, 4,
3165 &field_tree, &tf))
3166 return tvb_captured_length(tvb);
3167
3168 proto_tree_add_item(field_tree, hf_bcp_ncp_lan_seg_no, tvb, offset+2, 2, ENC_BIG_ENDIAN);
3169 proto_tree_add_item(field_tree, hf_bcp_ncp_bridge_no, tvb, offset+2, 2, ENC_BIG_ENDIAN);
3170 return tvb_captured_length(tvb);
3171 }
3172
3173 /*
3174 0 1 2
3175 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
3176 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3177 | Type | Length | MAC Type |
3178 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3179
3180 MAC Type
3181 0: reserved
3182 1: IEEE 802.3/Ethernet with canonical addresses
3183 2: IEEE 802.4 with canonical addresses
3184 3: IEEE 802.5 with non-canonical addresses
3185 4: FDDI with non-canonical addresses
3186 5-10: reserved
3187 11: IEEE 802.5 with canonical addresses
3188 12: FDDI with canonical addresses
3189
3190 */
3191 static int
dissect_bcp_ncp_mac_sup(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3192 dissect_bcp_ncp_mac_sup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3193 {
3194 proto_tree* field_tree;
3195 proto_item* tf;
3196 int offset = 0;
3197
3198 if (!dissect_bcp_ncp_fixed_opt(tvb, pinfo, tree, proto_bcp_ncp_option_mac_sup, ett_bcp_ncp_mac_sup_opt, 3,
3199 &field_tree, &tf))
3200 return tvb_captured_length(tvb);
3201
3202 proto_tree_add_item(field_tree, hf_bcp_bpdu_mac_type, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3203 return tvb_captured_length(tvb);
3204 }
3205
3206 /*
3207 0 1 2
3208 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
3209 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3210 | Type | Length | Enable/Disable|
3211 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3212
3213 */
3214 static int
dissect_bcp_ncp_tinygram_comp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3215 dissect_bcp_ncp_tinygram_comp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3216 {
3217 proto_tree* field_tree;
3218 proto_item* tf;
3219 int offset = 0;
3220
3221 if (!dissect_bcp_ncp_fixed_opt(tvb, pinfo, tree, proto_bcp_ncp_option_tinygram_comp, ett_bcp_ncp_tinygram_comp_opt, 3,
3222 &field_tree, &tf))
3223 return tvb_captured_length(tvb);
3224
3225 proto_tree_add_item(field_tree, hf_bcp_ncp_tinygram_comp, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3226 return tvb_captured_length(tvb);
3227 }
3228
3229 static int
dissect_bcp_ncp_lan_id(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3230 dissect_bcp_ncp_lan_id(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3231 {
3232 proto_tree* field_tree;
3233 proto_item* tf;
3234
3235 dissect_bcp_ncp_fixed_opt(tvb, pinfo, tree, proto_bcp_ncp_option_lan_id, ett_bcp_ncp_lan_id_opt, 3,
3236 &field_tree, &tf);
3237 /* XXX - missing a field? */
3238 return tvb_captured_length(tvb);
3239 }
3240
3241 /*
3242 0 1 2 3
3243 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
3244 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3245 | Type | Length |MAC byte 1 |L|M| MAC byte 2 |
3246 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3247 | MAC byte 3 | MAC byte 4 | MAC byte 5 | MAC byte 6 |
3248 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3249 */
3250 static int
dissect_bcp_ncp_mac_addr(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3251 dissect_bcp_ncp_mac_addr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3252 {
3253 proto_tree* field_tree;
3254 proto_item* tf;
3255 int offset = 0;
3256
3257 if (!dissect_bcp_ncp_fixed_opt(tvb, pinfo, tree, proto_bcp_ncp_option_mac_addr, ett_bcp_ncp_mac_addr_opt, 8,
3258 &field_tree, &tf))
3259 return tvb_captured_length(tvb);
3260
3261 proto_tree_add_item(field_tree, hf_bcp_ncp_mac, tvb, offset+2, 6, ENC_NA);
3262 proto_tree_add_item(field_tree, hf_bcp_ncp_mac_l, tvb, offset+2, 6, ENC_BIG_ENDIAN);
3263 proto_tree_add_item(field_tree, hf_bcp_ncp_mac_m, tvb, offset+2, 6, ENC_BIG_ENDIAN);
3264 return tvb_captured_length(tvb);
3265 }
3266
3267 /*
3268 0 1 2 3
3269 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
3270 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
3271 | Type | Length | Protocol 1 | Protocol 2 | ..
3272 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
3273
3274 */
3275
3276 static const value_string bcp_ncp_stp_prot_vals[] = {
3277 { 0, "Null (no Spanning Tree protocol supported)" },
3278 { 1, "IEEE 802.1D spanning tree" },
3279 { 2, "IEEE 802.1G extended spanning tree protocol" },
3280 { 3, "IBM Source Route Spanning tree protocol" },
3281 { 4, "DEC LANbridge 100 Spanning tree protocol" },
3282 { 0, NULL }
3283 };
3284
3285 static int
dissect_bcp_ncp_stp(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)3286 dissect_bcp_ncp_stp(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
3287 {
3288 proto_tree *field_tree;
3289 proto_item *tf;
3290 int offset = 0;
3291 int length = tvb_reported_length(tvb);
3292
3293 tf = proto_tree_add_item(tree, proto_bcp_ncp_option_stp, tvb, offset, length, ENC_NA);
3294 field_tree = proto_item_add_subtree(tf, ett_bcp_ncp_stp_opt);
3295
3296 dissect_bcp_ncp_opt_type_len(tvb, offset, field_tree, proto_registrar_get_name(proto_bcp_ncp_option_stp));
3297 offset += 2;
3298 length -= 2;
3299
3300 while (length != 0) {
3301 proto_tree_add_item(field_tree, hf_bcp_ncp_stp_prot, tvb, offset, 1, ENC_BIG_ENDIAN);
3302 length--;
3303 offset++;
3304 }
3305 return tvb_captured_length(tvb);
3306 }
3307
3308 /*
3309 0 1 2
3310 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
3311 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3312 | Type | Length | Enable/Disable|
3313 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3314
3315 */
3316 static int
dissect_bcp_ncp_ieee_802_tagged_frame(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3317 dissect_bcp_ncp_ieee_802_tagged_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3318 {
3319 proto_tree* field_tree;
3320 proto_item* tf;
3321 int offset = 0;
3322
3323 if (!dissect_bcp_ncp_fixed_opt(tvb, pinfo, tree, proto_bcp_ncp_option_ieee_802_tagged_frame,
3324 ett_bcp_ncp_ieee_802_tagged_frame_opt, 3, &field_tree, &tf))
3325 return tvb_captured_length(tvb);
3326
3327 proto_tree_add_item(field_tree, hf_bcp_ncp_ieee_802_tagged_frame, tvb, offset+2, 1, ENC_BIG_ENDIAN);
3328 return tvb_captured_length(tvb);
3329 }
3330
3331 /*
3332 0 1
3333 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
3334 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3335 | Type | Length |
3336 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3337
3338 */
3339 static int
dissect_bcp_ncp_management_inline(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3340 dissect_bcp_ncp_management_inline(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3341 {
3342 proto_tree* field_tree;
3343 proto_item* tf;
3344
3345 dissect_bcp_ncp_fixed_opt(tvb, pinfo, tree, proto_bcp_ncp_option_management_inline, ett_bcp_ncp_management_inline_opt, 3,
3346 &field_tree, &tf);
3347 return tvb_captured_length(tvb);
3348 }
3349
3350 /*
3351 0 1
3352 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
3353 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3354 | Type | Length |
3355 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
3356
3357 */
3358 static int
dissect_bcp_ncp_bcp_ncp_bcp_ind(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3359 dissect_bcp_ncp_bcp_ncp_bcp_ind(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3360 {
3361 proto_tree* field_tree;
3362 proto_item* tf;
3363
3364 dissect_bcp_ncp_fixed_opt(tvb, pinfo, tree, proto_bcp_ncp_option_bcp_ind, ett_bcp_ncp_bcp_ind_opt, 3,
3365 &field_tree, &tf);
3366 return tvb_captured_length(tvb);
3367 }
3368
3369
3370 static void
dissect_osinlcp_opt_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)3371 dissect_osinlcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
3372 const char *name)
3373 {
3374 guint8 type;
3375
3376 type = tvb_get_guint8(tvb, offset);
3377 proto_tree_add_uint_format_value(tree, hf_osinlcp_opt_type, tvb, offset, 1,
3378 type, "%s (%u)", name, type);
3379 proto_tree_add_item(tree, hf_osinlcp_opt_length, tvb, offset + 1, 1,
3380 ENC_BIG_ENDIAN);
3381 }
3382
3383 static gboolean
dissect_osinlcp_fixed_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)3384 dissect_osinlcp_fixed_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3385 int proto, int ett, int expected_length,
3386 proto_tree** ret_tree, proto_item** ret_item)
3387 {
3388 if (!ppp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), expected_length))
3389 return FALSE;
3390
3391 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, expected_length, ENC_NA);
3392 *ret_tree = proto_item_add_subtree(*ret_item, ett);
3393
3394 dissect_osinlcp_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
3395 return TRUE;
3396 }
3397
3398 static int
dissect_osinlcp_align_npdu_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3399 dissect_osinlcp_align_npdu_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3400 {
3401 proto_tree *field_tree;
3402 proto_item *tf;
3403 int offset = 0;
3404
3405 if (!dissect_osinlcp_fixed_opt(tvb, pinfo, tree, proto_osinlcp_option_align_npdu, ett_osinlcp_align_npdu_opt, 3,
3406 &field_tree, &tf))
3407 return tvb_captured_length(tvb);
3408
3409 proto_tree_add_item(field_tree, hf_osinlcp_opt_alignment, tvb, offset + 2,
3410 1, ENC_BIG_ENDIAN);
3411 return tvb_captured_length(tvb);
3412 }
3413
3414 static void
dissect_pppmuxcp_opt_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)3415 dissect_pppmuxcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
3416 const char *name)
3417 {
3418 guint8 type;
3419
3420 type = tvb_get_guint8(tvb, offset);
3421 proto_tree_add_uint_format_value(tree, hf_pppmuxcp_opt_type, tvb, offset, 1,
3422 type, "%s (%u)", name, type);
3423 proto_tree_add_item(tree, hf_pppmuxcp_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
3424 }
3425
3426 static gboolean
dissect_pppmuxcp_fixed_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)3427 dissect_pppmuxcp_fixed_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3428 int proto, int ett, int expected_length,
3429 proto_tree** ret_tree, proto_item** ret_item)
3430 {
3431 if (!ppp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), expected_length))
3432 return FALSE;
3433
3434 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, expected_length, ENC_NA);
3435 *ret_tree = proto_item_add_subtree(*ret_item, ett);
3436
3437 dissect_pppmuxcp_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
3438 return TRUE;
3439 }
3440
3441 static int
dissect_pppmuxcp_def_pid_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3442 dissect_pppmuxcp_def_pid_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3443 {
3444 proto_tree* field_tree;
3445 proto_item* tf;
3446 int offset = 0;
3447
3448 if (!dissect_pppmuxcp_fixed_opt(tvb, pinfo, tree, proto_pppmuxcp_option_def_pid, ett_pppmuxcp_def_pid_opt, 4,
3449 &field_tree, &tf))
3450 return tvb_captured_length(tvb);
3451
3452 proto_tree_add_item_ret_uint(tree, hf_pppmux_def_prot_id, tvb, offset + 2, 2, ENC_BIG_ENDIAN, &pppmux_def_prot_id);
3453 return tvb_captured_length(tvb);
3454 }
3455
3456
3457 static void
dissect_ccp_opt_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)3458 dissect_ccp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
3459 const char *name)
3460 {
3461 guint8 type;
3462
3463 type = tvb_get_guint8(tvb, offset);
3464 proto_tree_add_uint_format_value(tree, hf_ccp_opt_type, tvb, offset, 1,
3465 type, "%s (%u)", name, type);
3466 proto_tree_add_item(tree, hf_ccp_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
3467 }
3468
3469 static gboolean
dissect_ccp_fixed_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)3470 dissect_ccp_fixed_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3471 int proto, int ett, int expected_length,
3472 proto_tree** ret_tree, proto_item** ret_item)
3473 {
3474 if (!ppp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), expected_length))
3475 return FALSE;
3476
3477 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, expected_length, ENC_NA);
3478 *ret_tree = proto_item_add_subtree(*ret_item, ett);
3479
3480 dissect_ccp_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
3481 return TRUE;
3482 }
3483
3484 static gboolean
dissect_ccp_var_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)3485 dissect_ccp_var_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
3486 int proto, int ett, int expected_length,
3487 proto_tree** ret_tree, proto_item** ret_item)
3488 {
3489 int len = tvb_reported_length(tvb);
3490
3491 if (len < expected_length) {
3492 /* Bogus - option length isn't what it's supposed to be for this option. */
3493 proto_tree_add_expert_format(tree, pinfo, &ei_ppp_opt_len_invalid, tvb, 0, len,
3494 "%s (with option length = %u byte%s; should be at least %u)",
3495 proto_get_protocol_short_name(find_protocol_by_id(proto)),
3496 len, plurality(len, "", "s"), expected_length);
3497 return FALSE;
3498 }
3499
3500 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, -1, ENC_NA);
3501 *ret_tree = proto_item_add_subtree(*ret_item, ett);
3502
3503 dissect_ccp_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
3504 return TRUE;
3505 }
3506
3507
3508 /* https://tools.ietf.org/html/rfc1962 */
dissect_ccp_oui_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3509 static int dissect_ccp_oui_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3510 {
3511 proto_tree *field_tree;
3512 proto_item *tf;
3513 int offset = 0;
3514 int length = tvb_reported_length(tvb);
3515
3516 if (!dissect_ccp_var_opt(tvb, pinfo, tree, proto_ccp_option_oui, ett_ccp_oui_opt, 6,
3517 &field_tree, &tf))
3518 return tvb_captured_length(tvb);
3519
3520 proto_tree_add_item(field_tree, hf_ccp_opt_oui, tvb, offset + 2, 3, ENC_BIG_ENDIAN);
3521
3522 proto_tree_add_item(field_tree, hf_ccp_opt_subtype, tvb, offset + 5, 1,
3523 ENC_BIG_ENDIAN);
3524 if (length > 6) {
3525 proto_tree_add_item(field_tree, hf_ccp_opt_data, tvb, offset + 6,
3526 length - 6, ENC_NA);
3527 }
3528 return tvb_captured_length(tvb);
3529 }
3530
3531 /* The following configuration option types are mentioned at
3532 * https://www.iana.org/assignments/ppp-numbers/ppp-numbers.xhtml as referencing RFC1962; however,
3533 * RFC1962 only mentions Proprietary Compression OUI in section 4.1. These
3534 * others are therefore being treated as section 4.2 "Other Compression Types",
3535 * in terms of how they are dissected:
3536 * 1) Predictor type 1
3537 * 2) Predictor type 2
3538 * 3) Puddle Jumper
3539 * 16) Hewlett-Packard PPC
3540 * 20) V.42bis compression
3541 */
dissect_ccp_other_opt(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,int proto,int ett)3542 static int dissect_ccp_other_opt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int proto, int ett)
3543 {
3544 proto_tree *field_tree;
3545 proto_item *tf;
3546 int offset = 0;
3547 int length = tvb_reported_length(tvb);
3548
3549 tf = proto_tree_add_item(tree, proto, tvb, 0, length, ENC_NA);
3550 field_tree = proto_item_add_subtree(tf, ett);
3551
3552 dissect_ccp_opt_type_len(tvb, offset, field_tree, proto_registrar_get_name(proto));
3553
3554 if (length > 2) {
3555 proto_tree_add_item(field_tree, hf_ccp_opt_data, tvb, offset + 2,
3556 length - 2, ENC_NA);
3557 }
3558
3559 return tvb_captured_length(tvb);
3560 }
3561
dissect_ccp_predict1_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3562 static int dissect_ccp_predict1_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3563 {
3564 return dissect_ccp_other_opt(tvb, pinfo, tree, proto_ccp_option_predict1, ett_ccp_predict1_opt);
3565 }
3566
dissect_ccp_predict2_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3567 static int dissect_ccp_predict2_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3568 {
3569 return dissect_ccp_other_opt(tvb, pinfo, tree, proto_ccp_option_predict2, ett_ccp_predict2_opt);
3570 }
3571
dissect_ccp_puddle_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3572 static int dissect_ccp_puddle_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3573 {
3574 return dissect_ccp_other_opt(tvb, pinfo, tree, proto_ccp_option_puddle, ett_ccp_puddle_opt);
3575 }
3576
dissect_ccp_hpppc_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3577 static int dissect_ccp_hpppc_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3578 {
3579 return dissect_ccp_other_opt(tvb, pinfo, tree, proto_ccp_option_hpppc, ett_ccp_hpppc_opt);
3580 }
3581
3582 /* https://tools.ietf.org/html/rfc1974 */
3583 static int
dissect_ccp_stac_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3584 dissect_ccp_stac_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3585 {
3586 proto_tree *field_tree;
3587 proto_item *tf;
3588 int offset = 0;
3589 int length = tvb_reported_length(tvb);
3590 static int * const check_mode_fields[] = {
3591 &hf_ccp_opt_cm_reserved,
3592 &hf_ccp_opt_cm_check_mode,
3593 NULL
3594 };
3595
3596 /* In RFC 1974, this is a fixed-length field of size 5, but in
3597 * Ascend Proprietary STAC compression this field is 6 octets. */
3598
3599 if (!dissect_ccp_var_opt(tvb, pinfo, tree,
3600 (length == 6) ? proto_ccp_option_stac_ascend : proto_ccp_option_stac,
3601 ett_ccp_stac_opt, 5, &field_tree, &tf))
3602 return tvb_captured_length(tvb);
3603
3604
3605 if (length == 6) {
3606 /* We don't know how to decode the following 4 octets, since
3607 there are no public documents that describe their usage. */
3608 proto_tree_add_item(field_tree, hf_ccp_opt_data, tvb, offset + 2,
3609 length - 2, ENC_NA);
3610 } else {
3611 proto_tree_add_item(field_tree, hf_ccp_opt_history_count, tvb,
3612 offset + 2, 2, ENC_BIG_ENDIAN);
3613 proto_tree_add_bitmask(field_tree, tvb, offset + 4, hf_ccp_opt_cm,
3614 ett_ccp_stac_opt_check_mode, check_mode_fields, ENC_NA);
3615 }
3616 return tvb_captured_length(tvb);
3617 }
3618
3619 /*
3620 * Microsoft Point-To-Point Compression (MPPC) and Encryption (MPPE)
3621 * supported bits.
3622 */
3623 #define MPPC_SUPPORTED_BITS_C 0x00000001 /* MPPC negotiation */
3624 #define MPPE_SUPPORTED_BITS_D 0x00000010 /* Obsolete */
3625 #define MPPE_SUPPORTED_BITS_L 0x00000020 /* 40-bit encryption */
3626 #define MPPE_SUPPORTED_BITS_S 0x00000040 /* 128-bit encryption */
3627 #define MPPE_SUPPORTED_BITS_M 0x00000080 /* 56-bit encryption */
3628 #define MPPE_SUPPORTED_BITS_H 0x01000000 /* stateless mode */
3629
3630 static const true_false_string ccp_mppe_h_tfs = {
3631 "Stateless mode ON",
3632 "Stateless mode OFF"
3633 };
3634 static const true_false_string ccp_mppe_m_tfs = {
3635 "56-bit encryption ON",
3636 "56-bit encryption OFF"
3637 };
3638 static const true_false_string ccp_mppe_s_tfs = {
3639 "128-bit encryption ON",
3640 "128-bit encryption OFF"
3641 };
3642 static const true_false_string ccp_mppe_l_tfs = {
3643 "40-bit encryption ON",
3644 "40-bit encryption OFF"
3645 };
3646 static const true_false_string ccp_mppe_d_tfs = {
3647 "Obsolete (should NOT be 1)",
3648 "Obsolete (should ALWAYS be 0)"
3649 };
3650 static const true_false_string ccp_mppe_c_tfs = {
3651 "Desire to negotiate MPPC",
3652 "No desire to negotiate MPPC"
3653 };
3654
3655 /* https://tools.ietf.org/html/rfc2118,
3656 * https://tools.ietf.org/html/rfc3078 */
3657 static int
dissect_ccp_mppe_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3658 dissect_ccp_mppe_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3659 {
3660 proto_tree *field_tree;
3661 proto_item *tf;
3662 int offset = 0;
3663 static int * const supported_bits_fields[] = {
3664 &hf_ccp_opt_supported_bits_h,
3665 &hf_ccp_opt_supported_bits_m,
3666 &hf_ccp_opt_supported_bits_s,
3667 &hf_ccp_opt_supported_bits_l,
3668 &hf_ccp_opt_supported_bits_d,
3669 &hf_ccp_opt_supported_bits_c,
3670 NULL
3671 };
3672
3673 if (!dissect_ccp_fixed_opt(tvb, pinfo, tree, proto_ccp_option_mppe, ett_ccp_mppe_opt, 6,
3674 &field_tree, &tf))
3675 return tvb_captured_length(tvb);
3676
3677 proto_tree_add_bitmask(field_tree, tvb, offset + 2,
3678 hf_ccp_opt_supported_bits, ett_ccp_mppe_opt_supp_bits,
3679 supported_bits_fields, ENC_BIG_ENDIAN);
3680 return tvb_captured_length(tvb);
3681 }
3682
3683 /* https://tools.ietf.org/html/rfc1993 */
dissect_ccp_gfza_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3684 static int dissect_ccp_gfza_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3685 {
3686 proto_tree *field_tree;
3687 proto_item *tf;
3688 int offset = 0;
3689 int length = tvb_reported_length(tvb);
3690
3691 if (!dissect_ccp_var_opt(tvb, pinfo, tree, proto_ccp_option_gfza, ett_ccp_gfza_opt, 3,
3692 &field_tree, &tf))
3693 return tvb_captured_length(tvb);
3694
3695 proto_tree_add_item(field_tree, hf_ccp_opt_history, tvb, offset + 2, 1,
3696 ENC_BIG_ENDIAN);
3697
3698 if (length > 3) {
3699 proto_tree_add_item(field_tree, hf_ccp_opt_version, tvb, offset + 3,
3700 length - 3, ENC_NA);
3701 }
3702 return tvb_captured_length(tvb);
3703 }
3704
dissect_ccp_v42bis_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3705 static int dissect_ccp_v42bis_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3706 {
3707 return dissect_ccp_other_opt(tvb, pinfo, tree, proto_ccp_option_v42bis, ett_ccp_v42bis_opt);
3708 }
3709
3710 /* https://tools.ietf.org/html/rfc1977 */
3711 static int
dissect_ccp_bsdcomp_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3712 dissect_ccp_bsdcomp_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3713 {
3714 proto_tree *field_tree;
3715 proto_item *tf;
3716 int offset = 0;
3717 static int * const vd_fields[] = {
3718 &hf_ccp_opt_vd_vers,
3719 &hf_ccp_opt_vd_dict,
3720 NULL
3721 };
3722
3723 if (!dissect_ccp_fixed_opt(tvb, pinfo, tree, proto_ccp_option_bsdcomp, ett_ccp_bsdcomp_opt, 3,
3724 &field_tree, &tf))
3725 return tvb_captured_length(tvb);
3726
3727 proto_tree_add_bitmask(field_tree, tvb, offset + 2, hf_ccp_opt_vd,
3728 ett_ccp_bsdcomp_opt, vd_fields, ENC_BIG_ENDIAN);
3729 return tvb_captured_length(tvb);
3730 }
3731
3732 /* https://tools.ietf.org/html/rfc1967 */
3733 static int
dissect_ccp_lzsdcp_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3734 dissect_ccp_lzsdcp_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3735 {
3736 proto_tree *field_tree;
3737 proto_item *tf;
3738 int offset = 0;
3739
3740 if (!dissect_ccp_fixed_opt(tvb, pinfo, tree, proto_ccp_option_lzsdcp, ett_ccp_lzsdcp_opt, 6,
3741 &field_tree, &tf))
3742 return tvb_captured_length(tvb);
3743
3744 proto_tree_add_item(field_tree, hf_ccp_opt_history_count, tvb,
3745 offset + 2, 2, ENC_BIG_ENDIAN);
3746 proto_tree_add_item(field_tree, hf_ccp_opt_check_mode, tvb, offset + 4, 1,
3747 ENC_BIG_ENDIAN);
3748 proto_tree_add_item(field_tree, hf_ccp_opt_process_mode, tvb, offset + 5,
3749 1, ENC_BIG_ENDIAN);
3750 return tvb_captured_length(tvb);
3751 }
3752
3753 /* https://tools.ietf.org/html/rfc1975 */
3754 static int
dissect_ccp_mvrca_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3755 dissect_ccp_mvrca_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3756 {
3757 proto_tree *field_tree;
3758 proto_item *tf;
3759 int offset = 0;
3760
3761 if (!dissect_ccp_fixed_opt(tvb, pinfo, tree, proto_ccp_option_mvrca, ett_ccp_mvrca_opt, 4,
3762 &field_tree, &tf))
3763 return tvb_captured_length(tvb);
3764
3765 proto_tree_add_item(field_tree, hf_ccp_opt_fe, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
3766 proto_tree_add_item(field_tree, hf_ccp_opt_p, tvb, offset + 2, 1, ENC_NA);
3767 proto_tree_add_item(field_tree, hf_ccp_opt_History, tvb, offset + 2, 1,
3768 ENC_BIG_ENDIAN);
3769 proto_tree_add_item(field_tree, hf_ccp_opt_contexts, tvb, offset + 3, 1,
3770 ENC_BIG_ENDIAN);
3771 return tvb_captured_length(tvb);
3772 }
3773
3774 /* https://tools.ietf.org/html/rfc1976 */
3775 static int
dissect_ccp_dce_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3776 dissect_ccp_dce_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3777 {
3778 proto_tree *field_tree;
3779 proto_item *tf;
3780 int offset = 0;
3781
3782 if (!dissect_ccp_fixed_opt(tvb, pinfo, tree, proto_ccp_option_dce, ett_ccp_dce_opt, 3,
3783 &field_tree, &tf))
3784 return tvb_captured_length(tvb);
3785
3786 proto_tree_add_item(field_tree, hf_ccp_opt_mode, tvb, offset + 2, 1,
3787 ENC_BIG_ENDIAN);
3788 return tvb_captured_length(tvb);
3789 }
3790
3791 static const value_string deflate_method_vals[] = {
3792 {8, "zlib compression"},
3793 {0, NULL}
3794 };
3795
3796 static const value_string deflate_chk_vals[] = {
3797 {0, "sequence number check method"},
3798 {0, NULL}
3799 };
3800
3801 /* https://tools.ietf.org/html/rfc1979 */
3802 static int
dissect_ccp_deflate_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3803 dissect_ccp_deflate_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3804 {
3805 proto_tree *field_tree;
3806 proto_item *tf;
3807 int offset = 0;
3808 guint8 window;
3809
3810 /* RFC1979 says the length is 3 but it's actually 4. */
3811 if (!dissect_ccp_fixed_opt(tvb, pinfo, tree, proto_ccp_option_deflate, ett_ccp_deflate_opt, 4,
3812 &field_tree, &tf))
3813 return tvb_captured_length(tvb);
3814
3815 window = tvb_get_guint8(tvb, offset + 2);
3816 proto_tree_add_uint_format_value(field_tree, hf_ccp_opt_window, tvb,
3817 offset + 2, 1, window, "%u", 1 << (hi_nibble(window) + 8));
3818 proto_tree_add_item(field_tree, hf_ccp_opt_method, tvb, offset + 2, 1,
3819 ENC_BIG_ENDIAN);
3820 proto_tree_add_item(field_tree, hf_ccp_opt_mbz, tvb, offset + 3, 1,
3821 ENC_BIG_ENDIAN);
3822 proto_tree_add_item(field_tree, hf_ccp_opt_chk, tvb, offset + 3, 1,
3823 ENC_BIG_ENDIAN);
3824 return tvb_captured_length(tvb);
3825 }
3826
3827 static const range_string v44lzjh_mode_dict_rvals[] = {
3828 {0, 0, "Datagram Mode (one dictionary and no history)"},
3829 {1, 1, "Multi-Datagram Mode (one dictionary with history)"},
3830 {2, G_MAXUINT16, "Individual Link Mode" /* "(and proposed number of
3831 dictionaries each with a
3832 corresponding history" */},
3833 {0, 0, NULL}
3834 };
3835
3836 /* https://tools.ietf.org/html/draft-heath-ppp-v44-01 */
dissect_ccp_v44lzjh_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3837 static int dissect_ccp_v44lzjh_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3838 {
3839 proto_tree *field_tree;
3840 proto_item *tf;
3841 int offset = 0;
3842 int length = tvb_reported_length(tvb);
3843
3844 if (!dissect_ccp_var_opt(tvb, pinfo, tree, proto_ccp_option_v44lzjh, ett_ccp_v44lzjh_opt, 4,
3845 &field_tree, &tf))
3846 return tvb_captured_length(tvb);
3847
3848 proto_tree_add_item(field_tree, hf_ccp_opt_mode_dictcount, tvb, offset + 2,
3849 2, ENC_BIG_ENDIAN);
3850
3851 if (length > 4) {
3852 proto_tree_add_item(field_tree, hf_ccp_opt_dict_size, tvb, offset + 4,
3853 2, ENC_BIG_ENDIAN);
3854 if (length > 6) {
3855 proto_tree_add_item(field_tree, hf_ccp_opt_history_length, tvb,
3856 offset + 6, 2, ENC_BIG_ENDIAN);
3857 }
3858 }
3859 return tvb_captured_length(tvb);
3860 }
3861
3862 static int
dissect_cbcp_callback_opt_common(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int offset,int length)3863 dissect_cbcp_callback_opt_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int length)
3864 {
3865 proto_tree *addr_tree;
3866 proto_item *ti;
3867 guint8 addr_type;
3868 guint addr_len;
3869
3870 proto_tree_add_item(tree, hf_cbcp_callback_delay, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
3871 offset += 3;
3872 length -= 3;
3873
3874 while (length > 0) {
3875 addr_tree = proto_tree_add_subtree(tree, tvb, offset, length,
3876 ett_cbcp_callback_opt_addr, NULL, "Callback Address");
3877 addr_type = tvb_get_guint8(tvb, offset);
3878 ti = proto_tree_add_uint_format_value(addr_tree, hf_cbcp_address_type, tvb, offset, 1, addr_type,
3879 "%s (%u)", ((addr_type == 1) ? "PSTN/ISDN" : "Other"), addr_type);
3880 offset++;
3881 length--;
3882 addr_len = tvb_strsize(tvb, offset);
3883 if (addr_len > (guint)length) {
3884 expert_add_info(pinfo, ti, &ei_cbcp_address);
3885 break;
3886 }
3887 proto_tree_add_item(addr_tree, hf_cbcp_address, tvb, offset, addr_len, ENC_NA|ENC_ASCII);
3888 offset += addr_len;
3889 length -= addr_len;
3890 }
3891
3892 return tvb_captured_length(tvb);
3893 }
3894
3895 static void
dissect_cbcp_opt_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)3896 dissect_cbcp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
3897 const char *name)
3898 {
3899 guint8 type;
3900
3901 type = tvb_get_guint8(tvb, offset);
3902 proto_tree_add_uint_format_value(tree, hf_cbcp_opt_type, tvb, offset, 1,
3903 type, "%s (%u)", name, type);
3904 proto_tree_add_item(tree, hf_cbcp_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
3905 }
3906
3907 static int
dissect_cbcp_no_callback_opt(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)3908 dissect_cbcp_no_callback_opt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
3909 {
3910 proto_tree* field_tree;
3911 proto_item* tf;
3912 int offset = 0;
3913 int length = tvb_reported_length(tvb);
3914
3915 tf = proto_tree_add_item(tree, proto_cbcp_option_no_callback, tvb, offset, length, ENC_NA);
3916 field_tree = proto_item_add_subtree(tf, ett_cbcp_no_callback);
3917
3918 dissect_cbcp_opt_type_len(tvb, offset, field_tree, proto_registrar_get_name(proto_cbcp_option_no_callback));
3919 proto_tree_add_item(field_tree, hf_cbcp_no_callback, tvb, offset+2, length-2, ENC_NA);
3920
3921 return tvb_captured_length(tvb);
3922 }
3923
3924 static int
dissect_cbcp_callback_user_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3925 dissect_cbcp_callback_user_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3926 {
3927 proto_tree* field_tree;
3928 proto_item* tf;
3929 int offset = 0;
3930 int length = tvb_reported_length(tvb);
3931
3932 if (length < 4) {
3933 /* Bogus - option length isn't what it's supposed to be for this option. */
3934 proto_tree_add_expert_format(tree, pinfo, &ei_ppp_opt_len_invalid, tvb, 0, length,
3935 "%s (with option length = %u byte%s; should be at least %u)",
3936 proto_get_protocol_short_name(find_protocol_by_id(proto_cbcp_option_callback_user)),
3937 length, plurality(length, "", "s"), 4);
3938 return tvb_captured_length(tvb);
3939 }
3940
3941 tf = proto_tree_add_item(tree, proto_cbcp_option_callback_user, tvb, offset, length, ENC_NA);
3942 field_tree = proto_item_add_subtree(tf, ett_cbcp_callback_user);
3943
3944 dissect_cbcp_opt_type_len(tvb, offset, field_tree, proto_registrar_get_name(proto_cbcp_option_callback_user));
3945
3946 return dissect_cbcp_callback_opt_common(tvb, pinfo, tree, 0, tvb_reported_length(tvb));
3947 }
3948
3949 static int
dissect_cbcp_callback_admin_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3950 dissect_cbcp_callback_admin_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3951 {
3952 proto_tree* field_tree;
3953 proto_item* tf;
3954 int offset = 0;
3955
3956 if (!ppp_option_len_check(tree, pinfo, tvb, proto_cbcp_option_callback_admin, tvb_reported_length(tvb), 4))
3957 return tvb_captured_length(tvb);
3958
3959 tf = proto_tree_add_item(tree, proto_cbcp_option_callback_admin, tvb, offset, -1, ENC_NA);
3960 field_tree = proto_item_add_subtree(tf, ett_cbcp_callback_admin);
3961
3962 dissect_cbcp_opt_type_len(tvb, offset, field_tree, proto_registrar_get_name(proto_cbcp_option_callback_admin));
3963
3964 return dissect_cbcp_callback_opt_common(tvb, pinfo, tree, 0, tvb_reported_length(tvb));
3965 }
3966
3967 static int
dissect_cbcp_callback_list_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)3968 dissect_cbcp_callback_list_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
3969 {
3970 proto_tree* field_tree;
3971 proto_item* tf;
3972 int offset = 0;
3973 int length = tvb_reported_length(tvb);
3974
3975 if (length < 4) {
3976 /* Bogus - option length isn't what it's supposed to be for this option. */
3977 proto_tree_add_expert_format(tree, pinfo, &ei_ppp_opt_len_invalid, tvb, 0, length,
3978 "%s (with option length = %u byte%s; should be at least %u)",
3979 proto_get_protocol_short_name(find_protocol_by_id(proto_cbcp_option_callback_list)),
3980 length, plurality(length, "", "s"), 4);
3981 return tvb_captured_length(tvb);
3982 }
3983
3984 tf = proto_tree_add_item(tree, proto_cbcp_option_callback_list, tvb, offset, length, ENC_NA);
3985 field_tree = proto_item_add_subtree(tf, ett_cbcp_callback_list);
3986
3987 dissect_cbcp_opt_type_len(tvb, offset, field_tree, proto_registrar_get_name(proto_cbcp_option_callback_list));
3988
3989 return dissect_cbcp_callback_opt_common(tvb, pinfo, tree, 0, tvb_reported_length(tvb));
3990 }
3991
3992 static void
dissect_bacp_opt_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)3993 dissect_bacp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
3994 const char *name)
3995 {
3996 guint8 type;
3997
3998 type = tvb_get_guint8(tvb, offset);
3999 proto_tree_add_uint_format_value(tree, hf_bacp_opt_type, tvb, offset, 1,
4000 type, "%s (%u)", name, type);
4001 proto_tree_add_item(tree, hf_bacp_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4002 }
4003
4004 static gboolean
dissect_bacp_fixed_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)4005 dissect_bacp_fixed_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4006 int proto, int ett, int expected_length,
4007 proto_tree** ret_tree, proto_item** ret_item)
4008 {
4009 if (!ppp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), expected_length))
4010 return FALSE;
4011
4012 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, expected_length, ENC_NA);
4013 *ret_tree = proto_item_add_subtree(*ret_item, ett);
4014
4015 dissect_bacp_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
4016 return TRUE;
4017 }
4018
4019 static int
dissect_bacp_favored_peer_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4020 dissect_bacp_favored_peer_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4021 {
4022 proto_tree* field_tree;
4023 proto_item* tf;
4024 int offset = 0;
4025
4026 if (!dissect_bacp_fixed_opt(tvb, pinfo, tree, proto_bacp_option_favored_peer, ett_bacp_favored_peer_opt, 6,
4027 &field_tree, &tf))
4028 return tvb_captured_length(tvb);
4029
4030 proto_tree_add_item(field_tree, hf_bacp_magic_number, tvb, offset + 2, 4, ENC_BIG_ENDIAN);
4031 return tvb_captured_length(tvb);
4032 }
4033
4034 static void
dissect_bap_opt_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)4035 dissect_bap_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
4036 const char *name)
4037 {
4038 guint8 type;
4039
4040 type = tvb_get_guint8(tvb, offset);
4041 proto_tree_add_uint_format_value(tree, hf_bap_opt_type, tvb, offset, 1,
4042 type, "%s (%u)", name, type);
4043 proto_tree_add_item(tree, hf_bap_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4044 }
4045
4046 static gboolean
dissect_bap_fixed_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)4047 dissect_bap_fixed_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4048 int proto, int ett, int expected_length,
4049 proto_tree** ret_tree, proto_item** ret_item)
4050 {
4051 if (!ppp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), expected_length))
4052 return FALSE;
4053
4054 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, expected_length, ENC_NA);
4055 *ret_tree = proto_item_add_subtree(*ret_item, ett);
4056
4057 dissect_bap_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
4058 return TRUE;
4059 }
4060
4061 static gboolean
dissect_bap_var_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)4062 dissect_bap_var_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4063 int proto, int ett, int expected_length,
4064 proto_tree** ret_tree, proto_item** ret_item)
4065 {
4066 int len = tvb_reported_length(tvb);
4067
4068 if (len < expected_length) {
4069 /* Bogus - option length isn't what it's supposed to be for this option. */
4070 proto_tree_add_expert_format(tree, pinfo, &ei_ppp_opt_len_invalid, tvb, 0, len,
4071 "%s (with option length = %u byte%s; should be at least %u)",
4072 proto_get_protocol_short_name(find_protocol_by_id(proto)),
4073 len, plurality(len, "", "s"), expected_length);
4074 return FALSE;
4075 }
4076
4077 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, -1, ENC_NA);
4078 *ret_tree = proto_item_add_subtree(*ret_item, ett);
4079
4080 dissect_bap_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
4081 return TRUE;
4082 }
4083
4084 static int
dissect_bap_link_type_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4085 dissect_bap_link_type_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4086 {
4087 proto_tree* field_tree;
4088 proto_item* tf;
4089 int offset = 0;
4090
4091 if (!dissect_bap_fixed_opt(tvb, pinfo, tree, proto_bap_option_link_type, ett_bap_link_type_opt, 5,
4092 &field_tree, &tf))
4093 return tvb_captured_length(tvb);
4094
4095 proto_tree_add_item(field_tree, hf_bacp_link_speed, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
4096 proto_tree_add_item(field_tree, hf_bacp_link_type, tvb, offset + 4, 1, ENC_BIG_ENDIAN);
4097 return tvb_captured_length(tvb);
4098 }
4099
4100 static int
dissect_bap_phone_delta_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4101 dissect_bap_phone_delta_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4102 {
4103 proto_tree *field_tree;
4104 proto_tree *suboption_tree;
4105 proto_item *tf, *ti;
4106 int offset = 0;
4107 int length = tvb_reported_length(tvb);
4108 guint8 subopt_type;
4109 guint8 subopt_len;
4110
4111 if (!dissect_bap_var_opt(tvb, pinfo, tree, proto_bap_option_phone_delta, ett_bap_phone_delta_opt, 4,
4112 &field_tree, &tf))
4113 return tvb_captured_length(tvb);
4114
4115 offset += 2;
4116 length -= 2;
4117
4118 while (length > 0) {
4119 subopt_type = tvb_get_guint8(tvb, offset);
4120 subopt_len = tvb_get_guint8(tvb, offset + 1);
4121 suboption_tree = proto_tree_add_subtree_format(field_tree, tvb, offset, subopt_len,
4122 ett_bap_phone_delta_subopt, NULL, "Sub-Option (%u byte%s)", subopt_len,
4123 plurality(subopt_len, "", "s"));
4124
4125 proto_tree_add_item(suboption_tree, hf_bap_sub_option_type, tvb, offset, 1, ENC_BIG_ENDIAN);
4126 ti = proto_tree_add_item(suboption_tree, hf_bap_sub_option_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4127
4128 if (subopt_len < 2) {
4129 expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
4130 "Sub-Option Length invalid, must be >= 2");
4131 break;
4132 }
4133 if (subopt_len > length) {
4134 expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
4135 "Sub-Option Length invalid, must be <= length remaining in option %u)", length);
4136 break;
4137 }
4138
4139 switch (subopt_type) {
4140 case BAP_PHONE_DELTA_SUBOPT_UNIQ_DIGIT:
4141 if (subopt_len == 3) {
4142 proto_tree_add_item(suboption_tree, hf_bap_unique_digit, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
4143 } else {
4144 expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
4145 "Invalid suboption length: %u (must be == 3)", subopt_len);
4146 }
4147 break;
4148 case BAP_PHONE_DELTA_SUBOPT_SUBSC_NUM:
4149 if (subopt_len > 2) {
4150 proto_tree_add_item(suboption_tree, hf_bap_subscriber_number, tvb, offset + 2, subopt_len - 2, ENC_NA|ENC_ASCII);
4151 } else {
4152 expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
4153 "Invalid suboption length: %u (must be > 2)", subopt_len);
4154 }
4155 break;
4156 case BAP_PHONE_DELTA_SUBOPT_PHONENUM_SUBADDR:
4157 if (subopt_len > 2) {
4158 proto_tree_add_item(suboption_tree, hf_bap_phone_number_sub_address, tvb, offset + 2, subopt_len - 2, ENC_NA|ENC_ASCII);
4159 } else {
4160 expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
4161 "Invalid suboption length: %u (must be > 2)", subopt_len);
4162 }
4163 break;
4164 default:
4165 if (subopt_len > 2) {
4166 proto_tree_add_item(suboption_tree, hf_bap_unknown_option_data, tvb, offset + 2, subopt_len - 2, ENC_NA);
4167 } else {
4168 expert_add_info_format(pinfo, ti, &ei_bap_sub_option_length,
4169 "Invalid suboption length: %u (must be > 2)", subopt_len);
4170 }
4171 break;
4172 }
4173 offset += subopt_len;
4174 length -= subopt_len;
4175 }
4176 return tvb_captured_length(tvb);
4177 }
4178
4179 static int
dissect_bap_no_phone_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4180 dissect_bap_no_phone_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4181 {
4182 proto_tree* field_tree;
4183 proto_item* tf;
4184
4185 dissect_bap_fixed_opt(tvb, pinfo, tree, proto_bap_option_no_phone, ett_bap_no_phone_opt, 2,
4186 &field_tree, &tf);
4187 return tvb_captured_length(tvb);
4188 }
4189
4190 static int
dissect_bap_reason_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4191 dissect_bap_reason_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4192 {
4193 proto_tree* field_tree;
4194 proto_item* tf;
4195 int offset = 0;
4196 int length = tvb_reported_length(tvb);
4197
4198 if (!dissect_bap_var_opt(tvb, pinfo, tree, proto_bap_option_reason, ett_bap_reason_opt, 2,
4199 &field_tree, &tf))
4200 return tvb_captured_length(tvb);
4201
4202 proto_tree_add_item(field_tree, hf_bap_reason, tvb, offset+2, length-2, ENC_NA|ENC_ASCII);
4203 return tvb_captured_length(tvb);
4204 }
4205
4206 static int
dissect_bap_link_disc_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4207 dissect_bap_link_disc_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4208 {
4209 proto_tree* field_tree;
4210 proto_item* tf;
4211 int offset = 0;
4212
4213 if (!dissect_bap_fixed_opt(tvb, pinfo, tree, proto_bap_option_link_disc, ett_bap_link_disc_opt, 4,
4214 &field_tree, &tf))
4215 return tvb_captured_length(tvb);
4216
4217 proto_tree_add_item(field_tree, hf_bap_link_discriminator, tvb, offset+2, 2, ENC_BIG_ENDIAN);
4218 return tvb_captured_length(tvb);
4219 }
4220
4221 static int
dissect_bap_call_status_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4222 dissect_bap_call_status_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4223 {
4224 proto_tree* field_tree;
4225 proto_item* tf;
4226 int offset = 0;
4227
4228 if (!dissect_bap_fixed_opt(tvb, pinfo, tree, proto_bap_option_call_status, ett_bap_call_status_opt, 4,
4229 &field_tree, &tf))
4230 return tvb_captured_length(tvb);
4231
4232 proto_tree_add_item(field_tree, hf_bap_call_status, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
4233 proto_tree_add_item(field_tree, hf_bap_call_action, tvb, offset + 3, 1, ENC_BIG_ENDIAN);
4234 return tvb_captured_length(tvb);
4235 }
4236
4237 static void
dissect_vsncp_opt_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)4238 dissect_vsncp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
4239 const char *name)
4240 {
4241 guint8 type;
4242
4243 type = tvb_get_guint8(tvb, offset);
4244 proto_tree_add_uint_format_value(tree, hf_vsncp_opt_type, tvb, offset, 1,
4245 type, "%s (%u)", name, type);
4246 proto_tree_add_item(tree, hf_vsncp_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
4247 }
4248
4249 static gboolean
dissect_vsncp_fixed_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)4250 dissect_vsncp_fixed_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4251 int proto, int ett, int expected_length,
4252 proto_tree** ret_tree, proto_item** ret_item)
4253 {
4254 if (!ppp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), expected_length))
4255 return FALSE;
4256
4257 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, expected_length, ENC_NA);
4258 *ret_tree = proto_item_add_subtree(*ret_item, ett);
4259
4260 dissect_vsncp_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
4261 return TRUE;
4262 }
4263
4264 static int
dissect_vsncp_pdnid_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4265 dissect_vsncp_pdnid_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4266 {
4267 proto_tree *field_tree;
4268 proto_item *tf;
4269 int offset = 0;
4270
4271 if (!dissect_vsncp_fixed_opt(tvb, pinfo, tree,
4272 proto_vsncp_option_pdnid, ett_vsncp_pdnid_opt, 3,
4273 &field_tree, &tf))
4274 return tvb_captured_length(tvb);
4275
4276 proto_tree_add_item(field_tree, hf_vsncp_pdn_identifier, tvb, offset+2, 1, ENC_BIG_ENDIAN);
4277 return tvb_captured_length(tvb);
4278 }
4279
4280 static const value_string vsncp_attach_vals[] = {
4281 {1, "Initial Attach"},
4282 {3, "Handover Attach"},
4283 {0, NULL}
4284 };
4285
4286 static int
dissect_vsncp_attachtype_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4287 dissect_vsncp_attachtype_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4288 {
4289 proto_tree *field_tree;
4290 proto_item *tf;
4291 int offset = 0;
4292
4293 if (!dissect_vsncp_fixed_opt(tvb, pinfo, tree,
4294 proto_vsncp_option_attachtype, ett_vsncp_attachtype_opt, 3,
4295 &field_tree, &tf))
4296 return tvb_captured_length(tvb);
4297
4298 proto_tree_add_item(field_tree, hf_vsncp_attach_type, tvb, offset+2, 1, ENC_BIG_ENDIAN);
4299 return tvb_captured_length(tvb);
4300 }
4301
4302 static const value_string vsncp_pdntype_vals[] = {
4303 {0, "Initial Request by UE"},
4304 {1, "IPv4"},
4305 {2, "IPv6"},
4306 {3, "IPv6/IPv4"},
4307 {0, NULL}
4308 };
4309
4310 static int
dissect_vsncp_pdntype_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4311 dissect_vsncp_pdntype_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4312 {
4313 proto_tree *field_tree;
4314 proto_item *tf;
4315 int offset = 0;
4316
4317 if (!dissect_vsncp_fixed_opt(tvb, pinfo, tree,
4318 proto_vsncp_option_pdntype, ett_vsncp_pdntype_opt, 3,
4319 &field_tree, &tf))
4320 return tvb_captured_length(tvb);
4321
4322 proto_tree_add_item(field_tree, hf_vsncp_pdn_type, tvb, offset+2, 1, ENC_BIG_ENDIAN);
4323 return tvb_captured_length(tvb);
4324 }
4325
4326 static const value_string vsncp_errorcode_vals[] = {
4327 {0, "General Error"},
4328 {1, "Unauthorized APN"},
4329 {2, "PDN Limit Exceeded"},
4330 {3, "NO PG-W Available"},
4331 {4, "P-GW Unreachable"},
4332 {5, "P-GW Reject"},
4333 {6, "Insufficient Parameters"},
4334 {7, "Resource Unavailable"},
4335 {8, "Admin Prohibited"},
4336 {9, "PDN-ID Already in Use"},
4337 {10, "Subscription Limitation"},
4338 {11, "PDN connection already exists for APN"},
4339 {12, "Emergency services not supported"},
4340 {13, "Reconnect to this APN not allowed"},
4341 {14, "APN congested"},
4342 {0, NULL}
4343 };
4344
4345 static int
dissect_vsncp_errorcode_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4346 dissect_vsncp_errorcode_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4347 {
4348 proto_tree *field_tree;
4349 proto_item *tf;
4350 int offset = 0;
4351 int length = tvb_reported_length(tvb);
4352
4353 if (length < 3) {
4354 /* Bogus - option length isn't what it's supposed to be for this option. */
4355 proto_tree_add_expert_format(tree, pinfo, &ei_ppp_opt_len_invalid, tvb, 0, length,
4356 "%s (with option length = %u byte%s; should be at least %u)",
4357 proto_get_protocol_short_name(find_protocol_by_id(proto_vsncp_option_errorcode )),
4358 length, plurality(length, "", "s"), 3);
4359 return tvb_captured_length(tvb);
4360 }
4361
4362 tf = proto_tree_add_item(tree, proto_vsncp_option_errorcode, tvb, 0, length, ENC_NA);
4363 field_tree = proto_item_add_subtree(tf, ett_vsncp_errorcode_opt);
4364
4365 dissect_vsncp_opt_type_len(tvb, 0, field_tree, proto_registrar_get_name(proto_vsncp_option_pdnaddress));
4366
4367 proto_tree_add_item(field_tree, hf_vsncp_error_code, tvb, offset+2, 1, ENC_BIG_ENDIAN);
4368 return tvb_captured_length(tvb);
4369 }
4370
4371 static int
dissect_vsncp_pdnaddress_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4372 dissect_vsncp_pdnaddress_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4373 {
4374 proto_tree *field_tree;
4375 proto_item *tf;
4376 int offset = 0;
4377 int length = tvb_reported_length(tvb);
4378 guint32 pdnaddtype;
4379
4380 if (length < 3) {
4381 /* Bogus - option length isn't what it's supposed to be for this option. */
4382 proto_tree_add_expert_format(tree, pinfo, &ei_ppp_opt_len_invalid, tvb, 0, length,
4383 "%s (with option length = %u byte%s; should be at least %u)",
4384 proto_get_protocol_short_name(find_protocol_by_id(proto_vsncp_option_pdnaddress )),
4385 length, plurality(length, "", "s"), 3);
4386 return tvb_captured_length(tvb);
4387 }
4388
4389 tf = proto_tree_add_item(tree, proto_vsncp_option_pdnaddress, tvb, 0, length, ENC_NA);
4390 field_tree = proto_item_add_subtree(tf, ett_vsncp_pdnaddress_opt);
4391
4392 dissect_vsncp_opt_type_len(tvb, 0, field_tree, proto_registrar_get_name(proto_vsncp_option_pdnaddress));
4393
4394 proto_tree_add_item_ret_uint(field_tree, hf_vsncp_pdn_type, tvb, offset + 2, 1, ENC_BIG_ENDIAN, &pdnaddtype);
4395
4396 switch (pdnaddtype) {
4397 case 1:
4398 proto_tree_add_ipv4_format(field_tree, hf_vsncp_pdn_ipv4, tvb, offset + 3, 4,
4399 tvb_get_ntohl(tvb, offset + 3), "%s: %s",
4400 val_to_str_const(pdnaddtype, vsncp_pdntype_vals, "Unknown"),
4401 tvb_ip_to_str(pinfo->pool, tvb, offset + 3));
4402 break;
4403
4404 case 2:
4405 {
4406 ws_in6_addr *ad = wmem_new0(pinfo->pool,ws_in6_addr);
4407 address addr;
4408
4409 tvb_memcpy(tvb, &ad->bytes[8], offset + 3, 8);
4410 set_address(&addr, AT_IPv6, 16, ad->bytes);
4411 proto_tree_add_ipv6_format(field_tree, hf_vsncp_pdn_ipv6, tvb, offset + 3, length - 3, ad,
4412 "%s: %s", val_to_str_const(pdnaddtype, vsncp_pdntype_vals, "Unknown"),
4413 address_to_str(pinfo->pool, &addr));
4414 break;
4415 }
4416
4417 case 3:
4418 {
4419 ws_in6_addr *ad = wmem_new0(pinfo->pool, ws_in6_addr);
4420 address addr;
4421
4422 tvb_memcpy(tvb, &ad->bytes[8], offset + 3, 8);
4423 set_address(&addr, AT_IPv6, 16, ad->bytes);
4424 proto_tree_add_ipv6_format(field_tree, hf_vsncp_pdn_ipv6, tvb, offset + 3, length - 3, ad,
4425 "%s: %s", val_to_str_const(pdnaddtype, vsncp_pdntype_vals, "Unknown"),
4426 address_to_str(pinfo->pool, &addr));
4427 proto_tree_add_ipv4_format(field_tree, hf_vsncp_pdn_ipv4, tvb, offset + 11, length - 11,
4428 tvb_get_ntohl(tvb, offset + 11), "%s: %s", val_to_str_const(pdnaddtype, vsncp_pdntype_vals, "Unknown"),
4429 tvb_ip_to_str(pinfo->pool, tvb, offset + 11));
4430 break;
4431 }
4432
4433 default:
4434 break;
4435 }
4436
4437 return tvb_captured_length(tvb);
4438 }
4439
4440 static int
dissect_vsncp_ipv4address_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4441 dissect_vsncp_ipv4address_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4442 {
4443 proto_tree *field_tree;
4444 proto_item *tf;
4445 int offset = 0;
4446
4447 if (!dissect_vsncp_fixed_opt(tvb, pinfo, tree,
4448 proto_vsncp_option_ipv4address, ett_vsncp_ipv4address_opt, 6,
4449 &field_tree, &tf))
4450 return tvb_captured_length(tvb);
4451
4452 proto_tree_add_item(field_tree, hf_vsncp_default_router_address, tvb, offset+2, 4, ENC_BIG_ENDIAN);
4453 return tvb_captured_length(tvb);
4454 }
4455
4456 static int
dissect_vsncp_apname_opt(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)4457 dissect_vsncp_apname_opt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
4458 {
4459 proto_tree *field_tree;
4460 proto_item *tf;
4461 int offset = 0;
4462 int length = tvb_reported_length(tvb);
4463
4464 tf = proto_tree_add_item(tree, proto_vsncp_option_apname, tvb, 0, length, ENC_NA);
4465 field_tree = proto_item_add_subtree(tf, ett_vsncp_apname_opt);
4466
4467 dissect_vsncp_opt_type_len(tvb, 0, field_tree, proto_registrar_get_name(proto_vsncp_option_apname));
4468
4469 if (length > 2) {
4470 guint8 i = 0;
4471 guint8 j = 1;
4472 guint8 lengthofapn;
4473 int off = offset + 2;
4474
4475 while (i < (length - 2)) {
4476 lengthofapn = tvb_get_guint8(tvb, off++);
4477 proto_tree_add_string_format(field_tree, hf_vsncp_access_point_name, tvb, off, lengthofapn,
4478 tvb_get_string_enc(pinfo->pool, tvb, off, lengthofapn, ENC_ASCII),
4479 "Label%d (%d byte%s): %s", j++, lengthofapn,
4480 plurality(lengthofapn, "", "s"),
4481 tvb_format_text(pinfo->pool, tvb, off, lengthofapn));
4482 off += lengthofapn;
4483 i += lengthofapn + 1;
4484 }
4485 }
4486 return tvb_captured_length(tvb);
4487 }
4488
4489 static const value_string vsncp_alloc_vals[] = {
4490 {0, "Null Value (Attach or Handover)"},
4491 {18, "New PDN type due to network preference"},
4492 {255, "Success"},
4493 {0, NULL}
4494 };
4495
4496 static int
dissect_vsncp_addressalloc_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4497 dissect_vsncp_addressalloc_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4498 {
4499 proto_tree *field_tree;
4500 proto_item *tf;
4501 int offset = 0;
4502
4503 if (!dissect_vsncp_fixed_opt(tvb, pinfo, tree,
4504 proto_vsncp_option_addressalloc, ett_vsncp_addressalloc_opt, 3,
4505 &field_tree, &tf))
4506 return tvb_captured_length(tvb);
4507
4508 proto_tree_add_item(field_tree, hf_vsncp_address_allocation_cause, tvb, offset+2, 1, ENC_BIG_ENDIAN);
4509 return tvb_captured_length(tvb);
4510 }
4511
4512 static int
dissect_vsncp_apn_ambr_opt(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)4513 dissect_vsncp_apn_ambr_opt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
4514 {
4515 proto_tree *field_tree;
4516 proto_item *tf;
4517 int offset = 0;
4518 int length = tvb_reported_length(tvb);
4519
4520 tf = proto_tree_add_item(tree, proto_vsncp_option_apn_ambr, tvb, 0, length, ENC_NA);
4521 field_tree = proto_item_add_subtree(tf, ett_vsncp_apn_ambr_opt);
4522
4523 dissect_vsncp_opt_type_len(tvb, 0, field_tree, proto_registrar_get_name(proto_vsncp_option_apn_ambr ));
4524 proto_tree_add_item(field_tree, hf_vsncp_ambr_data, tvb, offset+2, length-2, ENC_NA);
4525
4526 return tvb_captured_length(tvb);
4527 }
4528
4529 static int
dissect_vsncp_ipv6_hsgw_lla_iid_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4530 dissect_vsncp_ipv6_hsgw_lla_iid_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4531 {
4532 proto_tree *field_tree;
4533 proto_item *tf;
4534 int offset = 0;
4535
4536 if (!dissect_vsncp_fixed_opt(tvb, pinfo, tree,
4537 proto_vsncp_option_ipv6_hsgw_lla_iid, ett_vsncp_ipv6_hsgw_lla_iid_opt, 10,
4538 &field_tree, &tf))
4539 return tvb_captured_length(tvb);
4540
4541 proto_tree_add_item(field_tree, hf_vsncp_ipv6_interface_identifier, tvb, offset+2, 8, ENC_NA);
4542 return tvb_captured_length(tvb);
4543 }
4544
4545 /* Ch 10.5.6.3 3GPP TS 24.008 version 11.5.0 Release 11 */
4546 static const value_string vsncp_pco_vals[] = {
4547 {0x8021, "IPCP (DNS Address Request)"},
4548 {0x0001, "P-CSCF Address Request (IPv6)"},
4549 {0x0005, "MS Support of Network Requested Bearer Control indicator"},
4550 {0x0003, "DNS Server Address (IPv6)"},
4551 {0x000A, "IP address allocation via NAS signalling"},
4552 {0x000B, "IPv4 address allocation via DHCPv4"},
4553 {0x000D, "DNS Server IPv4 Address Request"},
4554 {0, NULL}
4555 };
4556
4557 static int
dissect_vsncp_pco_opt(tvbuff_t * tvb,packet_info * pinfo _U_,proto_tree * tree,void * data _U_)4558 dissect_vsncp_pco_opt(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, void* data _U_)
4559 {
4560 guint8 len;
4561 proto_tree *field_tree;
4562 proto_item *tf;
4563 int length = tvb_reported_length(tvb);
4564 int offset = 3;
4565 guint8 i = 0;
4566
4567 tf = proto_tree_add_item(tree, proto_vsncp_option_pco, tvb, 0, length, ENC_NA);
4568 field_tree = proto_item_add_subtree(tf, ett_vsncp_pco_opt);
4569
4570 dissect_vsncp_opt_type_len(tvb, 0, field_tree, proto_registrar_get_name(proto_vsncp_option_pco));
4571
4572 while (i < (length - 3)) {
4573 len = tvb_get_guint8(tvb, (offset + 2));
4574 proto_tree_add_item(field_tree, hf_vsncp_protocol, tvb, offset, 2, ENC_BIG_ENDIAN);
4575 proto_tree_add_item(field_tree, hf_vsncp_protocol_configuration_length, tvb, offset + 2, 1, ENC_BIG_ENDIAN);
4576 if (len > 0) {
4577 proto_tree_add_item(field_tree, hf_vsncp_protocol_configuration_data, tvb, offset + 3, len, ENC_NA);
4578 }
4579
4580 offset += 3 + len;
4581 i += 3 + len;
4582 }
4583
4584 return tvb_captured_length(tvb);
4585 }
4586
4587 static void
dissect_cp(tvbuff_t * tvb,int proto_id,int proto_subtree_index,const value_string * proto_vals,int options_subtree_index,dissector_table_t option_table,packet_info * pinfo,proto_tree * tree)4588 dissect_cp(tvbuff_t *tvb, int proto_id, int proto_subtree_index,
4589 const value_string *proto_vals, int options_subtree_index,
4590 dissector_table_t option_table, packet_info *pinfo, proto_tree *tree)
4591 {
4592 proto_item *ti;
4593 proto_tree *fh_tree;
4594 guint8 code;
4595 int length, offset;
4596 guint32 oui;
4597 const gchar *manuf;
4598 guint32 secs_remaining;
4599
4600 code = tvb_get_guint8(tvb, 0);
4601 length = tvb_get_ntohs(tvb, 2);
4602
4603 col_set_str(pinfo->cinfo, COL_PROTOCOL,
4604 proto_get_protocol_short_name(find_protocol_by_id(proto_id)));
4605 col_set_str(pinfo->cinfo, COL_INFO,
4606 val_to_str_const(code, proto_vals, "Unknown"));
4607
4608 ti = proto_tree_add_item(tree, proto_id, tvb, 0, length, ENC_NA);
4609 fh_tree = proto_item_add_subtree(ti, proto_subtree_index);
4610 proto_tree_add_uint_format_value(fh_tree, hf_ppp_code, tvb, 0, 1, code,
4611 "%s (%u)", val_to_str_const(code, proto_vals, "Unknown"), code);
4612 proto_tree_add_item(fh_tree, hf_ppp_identifier, tvb, 1, 1, ENC_BIG_ENDIAN);
4613 proto_tree_add_item(fh_tree, hf_ppp_length, tvb, 2, 2, ENC_BIG_ENDIAN);
4614
4615 offset = 4;
4616 length -= 4;
4617
4618 switch (code) {
4619 case VNDRSPCFC:
4620 proto_tree_add_item(fh_tree, hf_ppp_magic_number, tvb, offset, 4,
4621 ENC_BIG_ENDIAN);
4622 oui = tvb_get_ntoh24(tvb, offset + 4);
4623 ti = proto_tree_add_uint_format_value(fh_tree, hf_ppp_oui, tvb,
4624 offset + 4, 3, oui, "%02x:%02x:%02x", (oui >> 16) & 0xff,
4625 (oui >> 8) & 0xff, oui & 0xff);
4626 manuf = uint_get_manuf_name_if_known(oui);
4627 if (manuf){
4628 proto_item_append_text(ti, "(%s)", manuf);
4629 }
4630 proto_tree_add_item(fh_tree, hf_ppp_kind, tvb, offset + 7, 1,
4631 ENC_BIG_ENDIAN);
4632 if (length > 8) {
4633 proto_tree_add_item(fh_tree, hf_ppp_data, tvb, offset + 8,
4634 length - 8, ENC_NA);
4635 }
4636 break;
4637
4638 case CONFREQ:
4639 case CONFACK:
4640 case CONFNAK:
4641 case CONFREJ:
4642 if (length > 0) {
4643 proto_tree *field_tree;
4644
4645 field_tree = proto_tree_add_subtree_format(fh_tree, tvb, offset, length,
4646 options_subtree_index, NULL, "Options: (%d byte%s)", length, plurality(length, "", "s"));
4647 ppp_dissect_options(tvb, offset, length, option_table, pinfo, field_tree);
4648 }
4649 break;
4650
4651 case CODEREJ:
4652 if (length > 0) {
4653 /* TODO: Decode the rejected packet here ... but wait until we have
4654 * a valid capture file with a CODEREJ, since the only capture file
4655 * with CODEREJ packets in it that I know of is pppoe.dump.gz from
4656 * the menagerie, and that file appears to have malformed CODEREJ
4657 * packets as they don't include the Code, Identifier or Length
4658 * fields so it's impossible to do the decode. */
4659 proto_tree_add_bytes_format(fh_tree, hf_ppp_data, tvb, offset,
4660 length, NULL, "Rejected Packet (%d byte%s): %s", length,
4661 plurality(length, "", "s"),
4662 tvb_bytes_to_str(pinfo->pool, tvb, offset, length));
4663 }
4664 break;
4665
4666 case PROTREJ: /* LCP only: RFC 1661 */
4667 proto_tree_add_item(fh_tree, hf_lcp_rej_proto, tvb, offset, 2,
4668 ENC_BIG_ENDIAN);
4669 if (length > 2) {
4670 gboolean save_in_error_pkt;
4671 tvbuff_t *next_tvb;
4672 guint16 protocol;
4673
4674 protocol = tvb_get_ntohs(tvb, offset);
4675 offset += 2;
4676 length -= 2;
4677
4678 /*
4679 * Save the current value of the "we're inside an error packet"
4680 * flag, and set that flag; subdissectors may treat packets that
4681 * are the payload of error packets differently from "real"
4682 * packets.
4683 */
4684 save_in_error_pkt = pinfo->flags.in_error_pkt;
4685 pinfo->flags.in_error_pkt = TRUE;
4686
4687 /* Decode the rejected packet. */
4688 next_tvb = tvb_new_subset_length(tvb, offset, length);
4689 if (!dissector_try_uint(ppp_subdissector_table, protocol, next_tvb,
4690 pinfo, fh_tree)) {
4691 call_data_dissector(next_tvb, pinfo, fh_tree);
4692 }
4693
4694 /* Restore the "we're inside an error packet" flag. */
4695 pinfo->flags.in_error_pkt = save_in_error_pkt;
4696 }
4697 break;
4698
4699 case ECHOREQ: /* All 3 are LCP only: RFC 1661 */
4700 case ECHOREP:
4701 case DISCREQ:
4702 proto_tree_add_item(fh_tree, hf_lcp_magic_number, tvb, offset, 4,
4703 ENC_BIG_ENDIAN);
4704 if (length > 4) {
4705 proto_tree_add_item(fh_tree, hf_lcp_data, tvb, offset + 4,
4706 length - 4, ENC_NA);
4707 }
4708 break;
4709
4710 case IDENT: /* LCP only: RFC 1570 */
4711 proto_tree_add_item(fh_tree, hf_lcp_magic_number, tvb, offset, 4,
4712 ENC_BIG_ENDIAN);
4713 if (length > 4) {
4714 proto_tree_add_item(fh_tree, hf_lcp_message, tvb, offset + 4,
4715 length - 4, ENC_ASCII|ENC_NA);
4716 }
4717 break;
4718
4719 case TIMEREMAIN: /* LCP only: RFC 1570 */
4720 proto_tree_add_item(fh_tree, hf_lcp_magic_number, tvb, offset, 4,
4721 ENC_BIG_ENDIAN);
4722 secs_remaining = tvb_get_ntohl(tvb, offset + 4);
4723 proto_tree_add_uint_format_value(fh_tree, hf_lcp_secs_remaining,
4724 tvb, offset + 4, 4, secs_remaining, "%u %s", secs_remaining,
4725 (secs_remaining == 0xffffffff) ? "(forever)" : "seconds");
4726 if (length > 8) {
4727 proto_tree_add_item(fh_tree, hf_lcp_message, tvb, offset + 8,
4728 length - 8, ENC_ASCII|ENC_NA);
4729 }
4730 break;
4731
4732 case TERMREQ:
4733 case TERMACK:
4734 case RESETREQ: /* RESETREQ and RESETACK are CCP only: RFC 1962 */
4735 case RESETACK:
4736 default:
4737 if (length > 0) {
4738 proto_tree_add_item(fh_tree, hf_ppp_data, tvb, offset, length,
4739 ENC_NA);
4740 }
4741 break;
4742 }
4743 }
4744
4745 /* Protocol field compression */
4746 #define PFC_BIT 0x01
4747
4748 static void
dissect_ppp_common(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,proto_tree * fh_tree,proto_item * ti,int proto_offset)4749 dissect_ppp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
4750 proto_tree *fh_tree, proto_item *ti, int proto_offset)
4751 {
4752 guint16 ppp_prot;
4753 int proto_len;
4754 tvbuff_t *next_tvb;
4755
4756 /* Make direction information filterable */
4757 if (pinfo->p2p_dir == P2P_DIR_RECV || pinfo->p2p_dir == P2P_DIR_SENT) {
4758 proto_item *direction_ti = proto_tree_add_uint(fh_tree, hf_ppp_direction,
4759 tvb, 0, 0, pinfo->p2p_dir);
4760 proto_item_set_generated(direction_ti);
4761 }
4762
4763 ppp_prot = tvb_get_guint8(tvb, 0);
4764 if (ppp_prot & PFC_BIT) {
4765 /* Compressed protocol field - just the byte we fetched. */
4766 proto_len = 1;
4767 } else {
4768 /* Uncompressed protocol field - fetch all of it. */
4769 ppp_prot = tvb_get_ntohs(tvb, 0);
4770 proto_len = 2;
4771 }
4772
4773 /* If "ti" is not null, it refers to the top-level "proto_ppp" item
4774 for PPP, and proto_offset is the length of any stuff in the header
4775 preceding the protocol type, e.g. an HDLC header; add the length
4776 of the protocol type field to it, and set the length of that item
4777 to the result. */
4778 proto_item_set_len(ti, proto_offset + proto_len);
4779
4780 proto_tree_add_uint(fh_tree, hf_ppp_protocol, tvb, 0, proto_len,
4781 ppp_prot);
4782
4783 next_tvb = tvb_new_subset_remaining(tvb, proto_len);
4784
4785 /* do lookup with the subdissector table */
4786 if (!dissector_try_uint(ppp_subdissector_table, ppp_prot, next_tvb, pinfo,
4787 tree)) {
4788 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", ppp_prot);
4789 col_add_fstr(pinfo->cinfo, COL_INFO, "PPP %s (0x%04x)",
4790 val_to_str_ext_const(ppp_prot, &ppp_vals_ext, "Unknown"),
4791 ppp_prot);
4792 call_data_dissector(next_tvb, pinfo, tree);
4793 }
4794 }
4795
4796 static int
dissect_lcp_options(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4797 dissect_lcp_options(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4798 {
4799 ppp_dissect_options(tvb, 0, tvb_reported_length(tvb), lcp_option_table, pinfo, tree);
4800 return tvb_captured_length(tvb);
4801 }
4802
4803 /*
4804 * RFC's 1661, 2153 and 1570.
4805 */
4806 static int
dissect_lcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4807 dissect_lcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4808 {
4809 dissect_cp(tvb, proto_lcp, ett_lcp, lcp_vals, ett_lcp_options, lcp_option_table, pinfo, tree);
4810 return tvb_captured_length(tvb);
4811 }
4812
4813 static int
dissect_vsncp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4814 dissect_vsncp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4815 {
4816 proto_item *ti;
4817 proto_tree *fh_tree;
4818 proto_tree *field_tree;
4819 guint8 code;
4820 int length, offset;
4821
4822 code = tvb_get_guint8(tvb, 0);
4823 length = tvb_get_ntohs(tvb, 2);
4824
4825 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSNCP");
4826 col_set_str(pinfo->cinfo, COL_INFO,
4827 val_to_str_const(code, cp_vals, "Unknown"));
4828
4829 ti = proto_tree_add_item(tree, proto_vsncp, tvb, 0, length, ENC_NA);
4830 fh_tree = proto_item_add_subtree(ti, ett_vsncp);
4831 proto_tree_add_item(fh_tree, hf_vsncp_code, tvb, 0, 1, ENC_BIG_ENDIAN);
4832 proto_tree_add_item(fh_tree, hf_vsncp_identifier, tvb, 1, 1, ENC_BIG_ENDIAN);
4833 proto_tree_add_item(fh_tree, hf_vsncp_length, tvb, 2, 2, ENC_BIG_ENDIAN);
4834 proto_tree_add_item(fh_tree, hf_ppp_oui, tvb, 4, 3, ENC_BIG_ENDIAN);
4835
4836 offset = 7;
4837 length -= 7;
4838
4839 switch (code) {
4840 case CONFREQ:
4841 case CONFACK:
4842 case CONFNAK:
4843 case CONFREJ:
4844 case TERMREQ:
4845 case TERMACK:
4846 if (length > 0) {
4847 field_tree = proto_tree_add_subtree_format(fh_tree, tvb, offset, length,
4848 ett_vsncp_options, NULL, "Options: (%d byte%s)", length,
4849 plurality(length, "", "s"));
4850 ppp_dissect_options(tvb, offset, length, vsncp_option_table, pinfo, field_tree);
4851 }
4852 break;
4853
4854 default:
4855 /* TODO? */
4856 break;
4857 }
4858 return tvb_captured_length(tvb);
4859 }
4860
4861 static int
dissect_vsnp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4862 dissect_vsnp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4863 {
4864 proto_item *vsnp_item;
4865 proto_tree *vsnp_tree;
4866 tvbuff_t *next_tvb;
4867
4868 col_set_str(pinfo->cinfo, COL_PROTOCOL, "VSNP");
4869
4870 vsnp_item = proto_tree_add_item(tree, proto_vsnp, tvb, 0, -1, ENC_NA);
4871 vsnp_tree = proto_item_add_subtree(vsnp_item, ett_vsnp);
4872 proto_tree_add_item(vsnp_tree, hf_vsnp_pdnid, tvb, 0, 1,
4873 ENC_BIG_ENDIAN);
4874
4875 next_tvb = tvb_new_subset_remaining(tvb, 1);
4876 if (!dissector_try_uint(ppp_subdissector_table, PPP_IP, next_tvb, pinfo,
4877 tree)) {
4878 col_add_fstr(pinfo->cinfo, COL_PROTOCOL, "0x%04x", PPP_IP);
4879 col_add_fstr(pinfo->cinfo, COL_INFO, "PPP %s (0x%04x)",
4880 val_to_str_ext_const(PPP_IP, &ppp_vals_ext, "Unknown"), PPP_IP);
4881 call_data_dissector(next_tvb, pinfo, tree);
4882 }
4883 return tvb_captured_length(tvb);
4884 }
4885
4886 /*
4887 * RFC 1332.
4888 */
4889 static int
dissect_ipcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4890 dissect_ipcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4891 {
4892 dissect_cp(tvb, proto_ipcp, ett_ipcp, cp_vals, ett_ipcp_options, ipcp_option_table,
4893 pinfo, tree);
4894 return tvb_captured_length(tvb);
4895 }
4896
4897 /*
4898 * RFC 3518
4899 */
4900 #define BCP_FCS_PRESENT 0x80
4901 #define BCP_ZEROPAD 0x20
4902 #define BCP_IS_BCONTROL 0x10
4903 #define BCP_PADS_MASK 0x0f
4904
4905 #define BCP_MACT_ETHERNET 1
4906 #define BCP_MACT_802_4 2
4907 #define BCP_MACT_802_5_NONCANON 3
4908 #define BCP_MACT_FDDI_NONCANON 4
4909 #define BCP_MACT_802_5_CANON 11
4910 #define BCP_MACT_FDDI_CANON 12
4911
4912 static const value_string bcp_bpdu_mac_type_vals[] = {
4913 {BCP_MACT_ETHERNET, "IEEE 802.3/Ethernet"},
4914 {BCP_MACT_802_4, "IEEE 802.4"},
4915 {BCP_MACT_802_5_NONCANON, "IEEE 802.5, non-canonical addresses"},
4916 {BCP_MACT_FDDI_NONCANON, "FDDI, non-canonical addresses"},
4917 {BCP_MACT_802_5_CANON, "IEEE 802.5, canonical addresses"},
4918 {BCP_MACT_FDDI_CANON, "FDDI, canonical addresses"},
4919 {0, NULL}
4920 };
4921
4922 static int
dissect_bcp_bpdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)4923 dissect_bcp_bpdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
4924 {
4925 proto_item *ti;
4926 proto_tree *bcp_bpdu_tree;
4927 int offset = 0;
4928 guint8 flags;
4929 guint8 mac_type;
4930 gint captured_length, reported_length, pad_length;
4931 tvbuff_t *next_tvb;
4932 static int * const bcp_bpdu_flags[] = {
4933 &hf_bcp_bpdu_fcs_present,
4934 &hf_bcp_bpdu_zeropad,
4935 &hf_bcp_bpdu_bcontrol,
4936 &hf_bcp_bpdu_pads,
4937 NULL
4938 };
4939
4940 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP BCP");
4941 col_clear(pinfo->cinfo, COL_INFO);
4942
4943 ti = proto_tree_add_item(tree, proto_bcp_bpdu, tvb, 0, -1, ENC_NA);
4944 bcp_bpdu_tree = proto_item_add_subtree(ti, ett_bcp_bpdu);
4945
4946 flags = tvb_get_guint8(tvb, offset);
4947 if (flags & BCP_IS_BCONTROL) {
4948 col_set_str(pinfo->cinfo, COL_INFO, "Bridge control");
4949 }
4950
4951 proto_tree_add_bitmask(bcp_bpdu_tree, tvb, offset, hf_bcp_bpdu_flags, ett_bcp_bpdu_flags, bcp_bpdu_flags, ENC_NA);
4952 offset++;
4953
4954 mac_type = tvb_get_guint8(tvb, offset);
4955 if (!(flags & BCP_IS_BCONTROL)) {
4956 col_add_str(pinfo->cinfo, COL_INFO,
4957 val_to_str(mac_type, bcp_bpdu_mac_type_vals,
4958 "Unknown MAC type %u"));
4959 }
4960 proto_tree_add_uint(bcp_bpdu_tree, hf_bcp_bpdu_mac_type, tvb, offset, 1, mac_type);
4961 offset++;
4962
4963 switch (mac_type) {
4964
4965 case BCP_MACT_802_4:
4966 case BCP_MACT_802_5_NONCANON:
4967 case BCP_MACT_FDDI_NONCANON:
4968 case BCP_MACT_802_5_CANON:
4969 case BCP_MACT_FDDI_CANON:
4970 proto_tree_add_item(bcp_bpdu_tree, hf_bcp_bpdu_pad, tvb, offset, 1, ENC_NA);
4971 offset++;
4972 break;
4973
4974 default:
4975 /* TODO? */
4976 break;
4977 }
4978
4979 proto_item_set_len(ti, offset);
4980
4981 if (!(flags & BCP_IS_BCONTROL)) {
4982 captured_length = tvb_captured_length_remaining(tvb, offset);
4983 reported_length = tvb_reported_length_remaining(tvb, offset);
4984 pad_length = flags & BCP_PADS_MASK;
4985 if (reported_length >= pad_length) {
4986 reported_length -= pad_length;
4987 if (captured_length > reported_length)
4988 captured_length = reported_length;
4989 next_tvb = tvb_new_subset_length_caplen(tvb, offset, captured_length,
4990 reported_length);
4991 switch (mac_type) {
4992
4993 case BCP_MACT_ETHERNET:
4994 if (flags & BCP_FCS_PRESENT) {
4995 call_dissector(eth_withfcs_handle, next_tvb, pinfo, tree);
4996 } else {
4997 call_dissector(eth_withoutfcs_handle, next_tvb, pinfo,
4998 tree);
4999 }
5000 break;
5001
5002 case BCP_MACT_802_4:
5003 case BCP_MACT_802_5_NONCANON:
5004 case BCP_MACT_FDDI_NONCANON:
5005 case BCP_MACT_802_5_CANON:
5006 case BCP_MACT_FDDI_CANON:
5007 break;
5008
5009 default:
5010 call_data_dissector(next_tvb, pinfo, tree);
5011 break;
5012 }
5013 }
5014 }
5015 return tvb_captured_length(tvb);
5016 }
5017
5018 /* RFC 3518
5019 * 4. A PPP Network Control Protocol for Bridging
5020 * :
5021 * The Bridging Control Protocol is exactly the same as the Link Control
5022 * Protocol [6] with the following exceptions...
5023 * :
5024 * ---the PPP Protocol field indicates type hex 8031 (BCP).
5025 */
5026 static int
dissect_bcp_ncp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5027 dissect_bcp_ncp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5028 {
5029 dissect_cp(tvb, proto_bcp_ncp, ett_bcp_ncp, lcp_vals, ett_bcp_ncp_options,
5030 bcp_ncp_option_table, pinfo, tree);
5031 return tvb_captured_length(tvb);
5032 }
5033
5034 /*
5035 * RFC 1377.
5036 */
5037 static int
dissect_osinlcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5038 dissect_osinlcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5039 {
5040 dissect_cp(tvb, proto_osinlcp, ett_osinlcp, cp_vals, ett_osinlcp_options, osinlcp_option_table,
5041 pinfo, tree);
5042 return tvb_captured_length(tvb);
5043 }
5044
5045 /*
5046 * RFC 1962.
5047 */
5048 static int
dissect_ccp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5049 dissect_ccp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5050 {
5051 dissect_cp(tvb, proto_ccp, ett_ccp, ccp_vals, ett_ccp_options, ccp_option_table, pinfo, tree);
5052 return tvb_captured_length(tvb);
5053 }
5054
5055 /*
5056 * Callback Control Protocol - see
5057 *
5058 * https://tools.ietf.org/html/draft-gidwani-ppp-callback-cp-00
5059 */
5060 static int
dissect_cbcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5061 dissect_cbcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5062 {
5063 dissect_cp(tvb, proto_cbcp, ett_cbcp, cbcp_vals, ett_cbcp_options,
5064 cbcp_option_table, pinfo, tree);
5065 return tvb_captured_length(tvb);
5066 }
5067
5068 /*
5069 * RFC 2125 (BACP and BAP).
5070 */
5071 static int
dissect_bacp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5072 dissect_bacp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5073 {
5074 dissect_cp(tvb, proto_bacp, ett_bacp, cp_vals, ett_bacp_options, bacp_option_table,
5075 pinfo, tree);
5076 return tvb_captured_length(tvb);
5077 }
5078
5079 static int
dissect_bap(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5080 dissect_bap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5081 {
5082 proto_item *ti;
5083 proto_tree *fh_tree;
5084 proto_tree *field_tree;
5085 guint8 type;
5086 int length, offset;
5087
5088 type = tvb_get_guint8(tvb, 0);
5089 length = tvb_get_ntohs(tvb, 2);
5090
5091 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP BAP");
5092 col_set_str(pinfo->cinfo, COL_INFO,
5093 val_to_str_const(type, bap_vals, "Unknown"));
5094
5095 ti = proto_tree_add_item(tree, proto_bap, tvb, 0, length, ENC_NA);
5096 fh_tree = proto_item_add_subtree(ti, ett_bap_options);
5097 proto_tree_add_item(fh_tree, hf_bap_type, tvb, 0, 1, ENC_BIG_ENDIAN);
5098 proto_tree_add_item(fh_tree, hf_bap_identifier, tvb, 1, 1, ENC_BIG_ENDIAN);
5099 proto_tree_add_item(fh_tree, hf_bap_length, tvb, 2, 2, ENC_BIG_ENDIAN);
5100
5101 offset = 4;
5102 length -= 4;
5103
5104 if (type == BAP_CRES || type == BAP_CBRES ||
5105 type == BAP_LDQRES || type == BAP_CSRES) {
5106 proto_tree_add_item(fh_tree, hf_bap_response_code, tvb, offset, 1, ENC_BIG_ENDIAN);
5107 offset++;
5108 length--;
5109 }
5110
5111 if (length > 0) {
5112 field_tree = proto_tree_add_subtree_format(fh_tree, tvb, offset, length,
5113 ett_bap_options, NULL, "Data (%d byte%s)", length, plurality(length, "", "s"));
5114 ppp_dissect_options(tvb, offset, length, bap_option_table, pinfo, field_tree);
5115 }
5116 return tvb_captured_length(tvb);
5117 }
5118
5119 #if 0 /* TODO? */
5120 static int
5121 dissect_comp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5122 {
5123 proto_item *ti;
5124 proto_tree *comp_data_tree;
5125
5126 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP Comp");
5127 col_set_str(pinfo->cinfo, COL_INFO, "Compressed data");
5128
5129 ti = proto_tree_add_item(tree, proto_comp_data, tvb, 0, -1, ENC_NA);
5130 comp_data_tree = proto_item_add_subtree(ti, ett_comp_data);
5131
5132 return tvb_captured_length(tvb);
5133 }
5134 #else
5135 static int
dissect_comp_data(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5136 dissect_comp_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5137 {
5138 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP Comp");
5139 col_set_str(pinfo->cinfo, COL_INFO, "Compressed data");
5140
5141 proto_tree_add_item(tree, proto_comp_data, tvb, 0, -1, ENC_NA);
5142 return tvb_captured_length(tvb);
5143 }
5144 #endif
5145
5146 /*
5147 * RFC 3153 (both PPPMuxCP and PPPMux).
5148 */
5149 static int
dissect_pppmuxcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5150 dissect_pppmuxcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5151 {
5152 dissect_cp(tvb, proto_pppmuxcp, ett_pppmuxcp, pppmuxcp_vals,
5153 ett_pppmuxcp_options, pppmuxcp_option_table, pinfo, tree);
5154 return tvb_captured_length(tvb);
5155 }
5156
5157 #define PPPMUX_FLAGS_MASK 0xc0
5158 #define PPPMUX_PFF_BIT_SET 0x80
5159 #define PPPMUX_LXT_BIT_SET 0x40
5160
5161 static int
dissect_pppmux(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5162 dissect_pppmux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5163 {
5164 proto_tree *mux_tree, *hdr_tree, *sub_tree;
5165 proto_tree *info_tree;
5166 proto_item *ti = NULL;
5167 guint8 flags, byte;
5168 guint16 length;
5169 static guint16 pid;
5170 tvbuff_t *next_tvb;
5171 int offset = 0, length_remaining;
5172 int length_field = 0, pid_field = 0, hdr_length = 0;
5173 static int * const subframe_flags[] = {
5174 &hf_pppmux_flags_pid,
5175 &hf_pppmux_flags_field_length,
5176 NULL
5177 };
5178
5179 col_set_str(pinfo->cinfo,COL_PROTOCOL, "PPP PPPMux");
5180 col_set_str(pinfo->cinfo, COL_INFO, "PPP Multiplexing");
5181
5182 length_remaining = tvb_reported_length(tvb);
5183
5184 ti = proto_tree_add_item(tree, proto_pppmux, tvb, 0, -1, ENC_NA);
5185 mux_tree = proto_item_add_subtree(ti, ett_pppmux);
5186
5187 while (length_remaining > 0) {
5188 flags = tvb_get_guint8(tvb,offset) & PPPMUX_FLAGS_MASK;
5189
5190 if (flags & PPPMUX_LXT_BIT_SET) {
5191 length = tvb_get_ntohs(tvb,offset) & 0x3fff;
5192 length_field = 2;
5193 } else {
5194 length = tvb_get_guint8(tvb,offset) & 0x3f;
5195 length_field = 1;
5196 }
5197
5198 if (flags & PPPMUX_PFF_BIT_SET) {
5199 byte = tvb_get_guint8(tvb,offset + length_field);
5200 if (byte & PFC_BIT) { /* Compressed PID field */
5201 pid = byte;
5202 pid_field = 1;
5203 } else { /* PID field is 2 bytes */
5204 pid = tvb_get_ntohs(tvb,offset + length_field);
5205 pid_field = 2;
5206 }
5207 } else {
5208 pid_field = 0; /* PID field is 0 bytes */
5209 if (!pid) { /* No Last PID, hence use the default */
5210 if (pppmux_def_prot_id)
5211 pid = pppmux_def_prot_id;
5212 }
5213 }
5214
5215 hdr_length = length_field + pid_field;
5216
5217 sub_tree = proto_tree_add_subtree(mux_tree, tvb, offset, length + length_field,
5218 ett_pppmux_subframe, NULL, "PPPMux Sub-frame");
5219 hdr_tree = proto_tree_add_subtree(sub_tree, tvb, offset, hdr_length,
5220 ett_pppmux_subframe_hdr, NULL, "Header field");
5221
5222 proto_tree_add_bitmask(tree, tvb, offset, hf_pppmux_flags, ett_pppmux_subframe_flags, subframe_flags, ENC_BIG_ENDIAN);
5223 proto_tree_add_uint(hdr_tree, hf_pppmux_sub_frame_length, tvb,offset, length_field, length);
5224
5225 ti = proto_tree_add_uint(hdr_tree, hf_pppmux_protocol, tvb,
5226 offset + length_field, pid_field, pid);
5227
5228 /* if protocol is not present in the sub-frame */
5229 if (!(flags & PPPMUX_PFF_BIT_SET)) {
5230 /* mark this item as generated */
5231 proto_item_set_generated(ti);
5232 }
5233
5234 offset += hdr_length;
5235 length_remaining -= hdr_length;
5236 length -= pid_field;
5237
5238 tvb_ensure_bytes_exist (tvb, offset, length);
5239 info_tree = proto_tree_add_subtree(sub_tree, tvb,offset, length,
5240 ett_pppmux_subframe_info, NULL, "Information Field");
5241 next_tvb = tvb_new_subset_length(tvb, offset, length);
5242
5243 if (!dissector_try_uint(ppp_subdissector_table, pid, next_tvb, pinfo,
5244 info_tree)) {
5245 call_data_dissector(next_tvb, pinfo, info_tree);
5246 }
5247 offset += length;
5248 length_remaining -= length;
5249 }
5250 return tvb_captured_length(tvb);
5251 }
5252
5253 /*
5254 * RFC 2507 / RFC 2508 Internet Protocol Header Compression
5255 */
5256 #define IPHC_CRTP_FH_FLAG_MASK 0xc0
5257 #define IPHC_CRTP_FH_CIDLEN_FLAG 0x80
5258 #define IPHC_CRTP_FH_DATA_FLAG 0x40
5259
5260 #define IPHC_CRTP_CS_CID8 1
5261 #define IPHC_CRTP_CS_CID16 2
5262
5263 static int * const iphc_crtp_fh_flags_fields[] = {
5264 &hf_iphc_crtp_fh_cidlenflag,
5265 &hf_iphc_crtp_fh_dataflag,
5266 NULL
5267 };
5268
5269 static const true_false_string iphc_crtp_fh_cidlenflag = {
5270 "16-bit",
5271 "8-bit"
5272 };
5273
5274 static const value_string iphc_crtp_cs_flags[] = {
5275 {IPHC_CRTP_CS_CID8, "8-bit Context Id"},
5276 {IPHC_CRTP_CS_CID16, "16-bit Context Id"},
5277 {0, NULL}
5278 };
5279
5280 static const crumb_spec_t iphc_crtp_cntcp_cid16_crumbs[] = {
5281 {0, 8},
5282 {16, 8},
5283 {0, 0}
5284 };
5285
5286 /*
5287 * 0x61 Packets: Full IP/UDP Header
5288 */
5289 static int
dissect_iphc_crtp_fh(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5290 dissect_iphc_crtp_fh(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5291 {
5292 proto_tree *fh_tree, *info_tree;
5293 proto_item *ti;
5294 guint ip_hdr_len, flags, seq;
5295 guint length;
5296 guint hdr_len;
5297 tvbuff_t *next_tvb;
5298 int offset_seq;
5299 int offset_cid;
5300 guint8 ip_version;
5301 guint8 next_protocol;
5302 guchar *ip_packet;
5303
5304 length = tvb_reported_length(tvb);
5305
5306 col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
5307 col_set_str(pinfo->cinfo, COL_INFO, "Full Header");
5308
5309 /* only dissect IPv4 and UDP */
5310 ip_version = tvb_get_guint8(tvb, 0) >> 4;
5311 flags = (tvb_get_guint8(tvb, 2) & IPHC_CRTP_FH_FLAG_MASK);
5312 next_protocol = tvb_get_guint8(tvb, 9);
5313
5314 ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
5315 "%s", val_to_str_ext_const(PPP_RTP_FH, &ppp_vals_ext, "Unknown"));
5316 fh_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
5317
5318 proto_tree_add_bitmask_with_flags(fh_tree, tvb, 2, hf_iphc_crtp_fh_flags,
5319 ett_iphc_crtp_fh_flags, iphc_crtp_fh_flags_fields, ENC_BIG_ENDIAN,
5320 BMT_NO_FLAGS);
5321 proto_tree_add_item(fh_tree, hf_iphc_crtp_gen, tvb, 2, 1,
5322 ENC_BIG_ENDIAN);
5323
5324 /* calculate length of IP header, assume IPv4 */
5325 ip_hdr_len = (tvb_get_guint8(tvb, 0) & 0x0f) * 4;
5326
5327 /* calculate total hdr length, assume UDP */
5328 hdr_len = ip_hdr_len + 8;
5329
5330 if (ip_version != 4) {
5331 proto_tree_add_expert_format(fh_tree, pinfo, &ei_iphc_crtp_ip_version, tvb, 3, -1,
5332 "IP version is %u: the only supported version is 4",
5333 ip_version);
5334 return 1;
5335 }
5336
5337 if (next_protocol != IP_PROTO_UDP) {
5338 proto_tree_add_expert_format(fh_tree, pinfo, &ei_iphc_crtp_next_protocol, tvb, 3, -1,
5339 "Next protocol is %s (%u): the only supported protocol is UDP",
5340 ipprotostr(next_protocol), next_protocol);
5341 return 1;
5342 }
5343
5344 /* context id and sequence fields */
5345 if (flags & IPHC_CRTP_FH_CIDLEN_FLAG) {
5346 offset_seq = 3;
5347 offset_cid = ip_hdr_len + 4;
5348 if (flags & IPHC_CRTP_FH_DATA_FLAG) {
5349 proto_tree_add_item(fh_tree, hf_iphc_crtp_seq, tvb, offset_seq, 1,
5350 ENC_BIG_ENDIAN);
5351 } else {
5352 seq = tvb_get_guint8(tvb, offset_seq);
5353 if (seq != 0) {
5354 ti = proto_tree_add_item(fh_tree, hf_iphc_crtp_seq, tvb, offset_seq,
5355 1, ENC_BIG_ENDIAN);
5356 expert_add_info(pinfo, ti, &ei_iphc_crtp_seq_nonzero);
5357 }
5358 }
5359 proto_tree_add_item(fh_tree, hf_iphc_crtp_cid16, tvb, offset_cid,
5360 2, ENC_BIG_ENDIAN);
5361 } else {
5362 offset_cid = 3;
5363 offset_seq = ip_hdr_len + 5;
5364 proto_tree_add_item(fh_tree, hf_iphc_crtp_cid8, tvb, offset_cid, 1,
5365 ENC_BIG_ENDIAN);
5366 if (flags & IPHC_CRTP_FH_DATA_FLAG) {
5367 proto_tree_add_item(fh_tree, hf_iphc_crtp_seq, tvb, offset_seq, 1,
5368 ENC_BIG_ENDIAN);
5369 } else {
5370 seq = tvb_get_guint8(tvb, offset_seq);
5371 if (seq != 0) {
5372 ti = proto_tree_add_item(fh_tree, hf_iphc_crtp_seq, tvb, offset_seq,
5373 1, ENC_BIG_ENDIAN);
5374 expert_add_info(pinfo, ti, &ei_iphc_crtp_seq_nonzero);
5375 }
5376 }
5377 }
5378
5379 /* information field */
5380 info_tree = proto_tree_add_subtree(fh_tree, tvb, 0, length, ett_iphc_crtp_info, NULL, "Information Field");
5381
5382 /* XXX: 1: May trap above; 2: really only need to check for ip_hdr_len+6 ?? */
5383 tvb_ensure_bytes_exist (tvb, 0, hdr_len); /* ip_hdr_len + 8 */
5384
5385 /* allocate a copy of the IP packet */
5386 ip_packet = (guchar *)tvb_memdup(pinfo->pool, tvb, 0, length);
5387
5388 /* restore the proper values to the IP and UDP length fields */
5389 ip_packet[2] = length >> 8;
5390 ip_packet[3] = length;
5391
5392 ip_packet[ip_hdr_len + 4] = (length - ip_hdr_len) >> 8;
5393 ip_packet[ip_hdr_len + 5] = (length - ip_hdr_len);
5394
5395 next_tvb = tvb_new_child_real_data(tvb, ip_packet, length, length);
5396 add_new_data_source(pinfo, next_tvb, "Decompressed Data");
5397
5398 if (!dissector_try_uint(ppp_subdissector_table, PPP_IP, next_tvb, pinfo,
5399 info_tree)) {
5400 call_data_dissector(next_tvb, pinfo, info_tree);
5401 }
5402 return tvb_captured_length(tvb);
5403 }
5404
5405 /*
5406 * 0x2067 Packets: Compressed UDP with 16-bit Context Identifier
5407 */
5408 static int
dissect_iphc_crtp_cudp16(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5409 dissect_iphc_crtp_cudp16(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5410 {
5411 proto_tree *cudp_tree;
5412 proto_item *ti;
5413 guint length;
5414 guint hdr_length;
5415 int offset = 0;
5416
5417 col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
5418 col_set_str(pinfo->cinfo, COL_INFO, "Compressed UDP 16");
5419
5420 length = tvb_reported_length(tvb);
5421
5422 ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
5423 "%s",
5424 val_to_str_ext_const(PPP_RTP_CUDP16, &ppp_vals_ext, "Unknown"));
5425 cudp_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
5426
5427 hdr_length = 3;
5428
5429 proto_tree_add_item(cudp_tree, hf_iphc_crtp_cid16, tvb, 0, 2,
5430 ENC_BIG_ENDIAN);
5431 proto_tree_add_item(cudp_tree, hf_iphc_crtp_seq, tvb, 2, 1,
5432 ENC_BIG_ENDIAN);
5433
5434 offset += hdr_length;
5435 length -= hdr_length;
5436
5437 proto_tree_add_item(cudp_tree, hf_iphc_crtp_data, tvb, offset, length, ENC_NA);
5438
5439 return tvb_captured_length(tvb);
5440 }
5441
5442 /*
5443 * 0x67 Packets: Compressed UDP with 8-bit Context Identifier
5444 */
5445 static int
dissect_iphc_crtp_cudp8(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5446 dissect_iphc_crtp_cudp8(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5447 {
5448 proto_tree *cudp_tree;
5449 proto_item *ti;
5450 guint length;
5451 guint hdr_length;
5452 int offset = 0;
5453
5454 col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
5455 col_set_str(pinfo->cinfo, COL_INFO, "Compressed UDP 8");
5456
5457 length = tvb_reported_length(tvb);
5458
5459 ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
5460 "%s",
5461 val_to_str_ext_const(PPP_RTP_CUDP8, &ppp_vals_ext, "Unknown"));
5462 cudp_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
5463
5464 hdr_length = 2;
5465
5466 proto_tree_add_item(cudp_tree, hf_iphc_crtp_cid8, tvb, 0, 1,
5467 ENC_BIG_ENDIAN);
5468 proto_tree_add_item(cudp_tree, hf_iphc_crtp_seq, tvb, 1, 1,
5469 ENC_BIG_ENDIAN);
5470
5471 offset += hdr_length;
5472 length -= hdr_length;
5473
5474 proto_tree_add_item(cudp_tree, hf_iphc_crtp_data, tvb, offset, length, ENC_NA);
5475
5476 return tvb_captured_length(tvb);
5477 }
5478
5479
5480 /*
5481 * 0x2065 Packets: Context State
5482 */
5483 static int
dissect_iphc_crtp_cs(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5484 dissect_iphc_crtp_cs(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5485 {
5486 proto_tree *cs_tree;
5487 proto_item *ti = NULL;
5488 guint8 flags, cnt;
5489 guint length, cid_size;
5490 guint offset = 2, hf;
5491
5492 col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
5493 col_set_str(pinfo->cinfo, COL_INFO, "Context State");
5494
5495 ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
5496 "%s", val_to_str_ext_const(PPP_RTP_CS, &ppp_vals_ext, "Unknown"));
5497
5498 cs_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
5499
5500 proto_tree_add_item(cs_tree, hf_iphc_crtp_cs_flags, tvb, 0, 1,
5501 ENC_BIG_ENDIAN);
5502 proto_tree_add_item(cs_tree, hf_iphc_crtp_cs_cnt, tvb, 1, 1,
5503 ENC_BIG_ENDIAN);
5504
5505 /* calculate required length */
5506 flags = tvb_get_guint8(tvb, 0);
5507 cnt = tvb_get_guint8(tvb, 1);
5508
5509 if (flags == IPHC_CRTP_CS_CID8) {
5510 hf = hf_iphc_crtp_cid8;
5511 cid_size = 1;
5512 length = 3 * cnt;
5513 } else {
5514 hf = hf_iphc_crtp_cid16;
5515 cid_size = 2;
5516 length = 4 * cnt;
5517 }
5518
5519 while (offset < length) {
5520 proto_tree_add_item(cs_tree, hf, tvb, offset, cid_size,
5521 ENC_BIG_ENDIAN);
5522 offset += cid_size;
5523 proto_tree_add_item(cs_tree, hf_iphc_crtp_cs_invalid, tvb, offset,
5524 1, ENC_BIG_ENDIAN);
5525 proto_tree_add_item(cs_tree, hf_iphc_crtp_seq, tvb, offset, 1,
5526 ENC_BIG_ENDIAN);
5527 ++offset;
5528 proto_tree_add_item(cs_tree, hf_iphc_crtp_gen, tvb, offset, 1,
5529 ENC_BIG_ENDIAN);
5530 ++offset;
5531 }
5532
5533 return tvb_captured_length(tvb);
5534 }
5535
5536 /*
5537 * 0x65 Packets: Compressed Non TCP
5538 */
5539 static int
dissect_iphc_crtp_cntcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5540 dissect_iphc_crtp_cntcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5541 {
5542 proto_tree *cntcp_tree;
5543 proto_item *ti;
5544 guint length, flags;
5545 guint hdr_length;
5546 int offset = 0;
5547
5548 col_set_str(pinfo->cinfo,COL_PROTOCOL, "CRTP");
5549 col_set_str(pinfo->cinfo, COL_INFO, "Compressed Non TCP");
5550
5551 length = tvb_reported_length(tvb);
5552
5553 flags = (tvb_get_guint8(tvb, 1) & IPHC_CRTP_FH_FLAG_MASK);
5554
5555 ti = proto_tree_add_protocol_format(tree, proto_iphc_crtp, tvb, 0, -1,
5556 "%s",
5557 val_to_str_ext_const(PPP_RTP_CNTCP, &ppp_vals_ext, "Unknown"));
5558 cntcp_tree = proto_item_add_subtree(ti, ett_iphc_crtp);
5559
5560 if (flags & IPHC_CRTP_FH_CIDLEN_FLAG) {
5561 /* RFC 2507 6. Compressed Header Formats
5562 * d) Compressed non-TCP header, 16 bit CID:
5563 * 0 7
5564 * +-+-+-+-+-+-+-+-+
5565 * | msb of CID |
5566 * +-+-+-+-+-+-+-+-+
5567 * |1|D| Generation|
5568 * +-+-+-+-+-+-+-+-+
5569 * | lsb of CID |
5570 * +-+-+-+-+-+-+-+-+
5571 * | data | (if D=1)
5572 * - - - - - - - -
5573 * | RANDOM fields, if any (section 7) (implied)
5574 */
5575 hdr_length = 3;
5576 proto_tree_add_split_bits_item_ret_val(cntcp_tree, hf_iphc_crtp_cid16, tvb, 0,
5577 iphc_crtp_cntcp_cid16_crumbs, NULL);
5578 } else {
5579 /* c) Compressed non-TCP header, 8 bit CID:
5580 * 0 7
5581 * +-+-+-+-+-+-+-+-+
5582 * | CID |
5583 * +-+-+-+-+-+-+-+-+
5584 * |0|D| Generation|
5585 * +-+-+-+-+-+-+-+-+
5586 * | data | (if D=1)
5587 * - - - - - - - -
5588 * | RANDOM fields, if any (section 7) (implied)
5589 * - - - - - - - -
5590 */
5591 hdr_length = 2;
5592 proto_tree_add_item(cntcp_tree, hf_iphc_crtp_cid8, tvb, 0, 1,
5593 ENC_BIG_ENDIAN);
5594 }
5595 proto_tree_add_bitmask_with_flags(cntcp_tree, tvb, 1, hf_iphc_crtp_fh_flags,
5596 ett_iphc_crtp_fh_flags, iphc_crtp_fh_flags_fields, ENC_BIG_ENDIAN,
5597 BMT_NO_FLAGS);
5598 proto_tree_add_item(cntcp_tree, hf_iphc_crtp_gen, tvb, 1, 1,
5599 ENC_BIG_ENDIAN);
5600
5601 if (flags & IPHC_CRTP_FH_DATA_FLAG) {
5602 proto_tree_add_item(cntcp_tree, hf_iphc_crtp_seq, tvb, hdr_length++,
5603 1, ENC_BIG_ENDIAN);
5604 }
5605
5606 offset += hdr_length;
5607 length -= hdr_length;
5608
5609 /* The IPv4 Identification Field is RANDOM and thus included in a
5610 * compressed Non TCP packet (RFC 2507 6a, 7.13a). Only IPv4 is
5611 * supported in this dissector, so we don't worry about the IPv6
5612 * case, which is different (RFC 2507 7.1)."
5613 */
5614 proto_tree_add_item(cntcp_tree, hf_iphc_crtp_ip_id, tvb, offset,
5615 2, ENC_BIG_ENDIAN);
5616 offset += 2;
5617 length -= 2;
5618
5619 proto_tree_add_item(cntcp_tree, hf_iphc_crtp_data, tvb, offset, length, ENC_NA);
5620
5621 return tvb_captured_length(tvb);
5622 }
5623
5624 /*
5625 * RFC 3032.
5626 */
5627 static int
dissect_mplscp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5628 dissect_mplscp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5629 {
5630 dissect_cp(tvb, proto_mplscp, ett_mplscp, cp_vals, ett_mplscp_options,
5631 NULL, pinfo, tree);
5632 return tvb_captured_length(tvb);
5633 }
5634
5635 /*
5636 * Cisco Discovery Protocol Control Protocol.
5637 * XXX - where is this documented?
5638 */
5639 static int
dissect_cdpcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5640 dissect_cdpcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5641 {
5642 dissect_cp(tvb, proto_cdpcp, ett_cdpcp, cp_vals, ett_cdpcp_options, NULL,
5643 pinfo, tree);
5644 return tvb_captured_length(tvb);
5645 }
5646
5647 /* PPP Multilink Protcol (RFC 1990) and
5648 * the Multiclass Extension to Multi-Link PPP (RFC 2686)
5649 */
5650 static gboolean mp_short_seqno = FALSE; /* Default to long sequence numbers */
5651 static guint mp_max_fragments = 6;
5652 /* Maximum fragments to try to reassemble. This affects performance and
5653 * memory use significantly. */
5654 static guint mp_fragment_aging = 4000; /* Short sequence numbers only 12 bit */
5655
5656 #define MP_FRAG_MASK 0xFC
5657 #define MP_FRAG_MASK_SHORT 0xF0
5658 #define MP_FRAG_FIRST 0x80
5659 #define MP_FRAG_LAST 0x40
5660 #define MP_FRAG_CLS 0x3C
5661 #define MP_FRAG_RESERVED 0x03
5662 #define MP_FRAG_CLS_SHORT 0x30
5663
5664 /* According to RFC 1990, the length the MP header isn't indicated anywhere
5665 in the header itself. It starts out at four bytes and can be
5666 negotiated down to two using LCP. We currently have a preference
5667 to select short headers. - gcc & gh
5668 */
5669
5670 static int
dissect_mp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5671 dissect_mp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5672 {
5673 proto_tree *mp_tree;
5674 proto_item *ti;
5675 gboolean save_fragmented;
5676 guint8 flags;
5677 guint32 cls; /* 32 bit since we shift it left and XOR with seqnum */
5678 guint32 seqnum;
5679 gint hdrlen;
5680 fragment_head *frag_mp;
5681 tvbuff_t *next_tvb;
5682 static int * const mp_flags[] = {
5683 &hf_mp_frag_first,
5684 &hf_mp_frag_last,
5685 &hf_mp_sequence_num_cls,
5686 &hf_mp_sequence_num_reserved,
5687 NULL
5688 };
5689 static int * const mp_short_flags[] = {
5690 &hf_mp_frag_first,
5691 &hf_mp_frag_last,
5692 &hf_mp_short_sequence_num_cls,
5693 NULL
5694 };
5695
5696 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP MP");
5697 col_set_str(pinfo->cinfo, COL_INFO, "PPP Multilink");
5698
5699 save_fragmented = pinfo->fragmented;
5700 flags = tvb_get_guint8(tvb, 0);
5701
5702 ti = proto_tree_add_item(tree, proto_mp, tvb, 0,
5703 mp_short_seqno ? 2 : 4, ENC_NA);
5704 mp_tree = proto_item_add_subtree(ti, ett_mp);
5705
5706 if (mp_short_seqno) {
5707 proto_tree_add_bitmask(mp_tree, tvb, 0, hf_mp_frag_short, ett_mp_flags, mp_short_flags, ENC_NA);
5708 proto_tree_add_item_ret_uint(mp_tree, hf_mp_short_sequence_num, tvb, 0, 2, ENC_BIG_ENDIAN, &seqnum);
5709 } else {
5710 proto_tree_add_bitmask(mp_tree, tvb, 0, hf_mp_frag, ett_mp_flags, mp_flags, ENC_NA);
5711 proto_tree_add_item_ret_uint(mp_tree, hf_mp_sequence_num, tvb, 1, 3, ENC_BIG_ENDIAN, &seqnum);
5712 }
5713
5714 hdrlen = mp_short_seqno ? 2 : 4;
5715 if (mp_short_seqno) {
5716 cls = (flags & MP_FRAG_CLS_SHORT) >> 4;
5717 } else {
5718 cls = (flags & MP_FRAG_CLS) >> 2;
5719 }
5720 if (tvb_reported_length_remaining(tvb, hdrlen) > 0) {
5721 pinfo->fragmented = TRUE;
5722 frag_mp = NULL;
5723 if (!pinfo->fd->visited) {
5724 frag_mp = fragment_add_seq_single_aging(&mp_reassembly_table,
5725 tvb, hdrlen, pinfo, seqnum ^ (cls << 24), NULL,
5726 tvb_captured_length_remaining(tvb, hdrlen),
5727 flags & MP_FRAG_FIRST, flags & MP_FRAG_LAST,
5728 mp_max_fragments, mp_fragment_aging);
5729 } else {
5730 frag_mp = fragment_get_reassembled_id(&mp_reassembly_table, pinfo, seqnum ^ (cls << 24));
5731 }
5732 next_tvb = process_reassembled_data(tvb, hdrlen, pinfo,
5733 "Reassembled PPP MP payload", frag_mp, &mp_frag_items,
5734 NULL, mp_tree);
5735
5736 if (frag_mp) {
5737 if (pinfo->num == frag_mp->reassembled_in) {
5738 dissect_ppp(next_tvb, pinfo, tree, NULL);
5739 } else {
5740 col_append_fstr(pinfo->cinfo, COL_INFO,
5741 " (PPP MP reassembled in packet %u)",
5742 frag_mp->reassembled_in);
5743 proto_tree_add_item(mp_tree, hf_mp_payload, tvb, hdrlen, -1, ENC_NA);
5744 }
5745 } else {
5746 col_append_fstr(pinfo->cinfo, COL_INFO,
5747 " (PPP MP Unreassembled fragment %u)",
5748 seqnum);
5749 proto_tree_add_item(mp_tree, hf_mp_payload, tvb, hdrlen, -1, ENC_NA);
5750 }
5751 }
5752
5753 pinfo->fragmented = save_fragmented;
5754 return tvb_captured_length(tvb);
5755 }
5756
5757 /*
5758 * Handles PPP without HDLC framing, just a protocol field (RFC 1661).
5759 */
5760 static int
dissect_ppp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5761 dissect_ppp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5762 {
5763 proto_item *ti;
5764 proto_tree *fh_tree;
5765
5766 ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, -1, ENC_NA);
5767 fh_tree = proto_item_add_subtree(ti, ett_ppp);
5768
5769 dissect_ppp_common(tvb, pinfo, tree, fh_tree, ti, 0);
5770 return tvb_captured_length(tvb);
5771 }
5772
5773 static void
dissect_ppp_hdlc_common(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree)5774 dissect_ppp_hdlc_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
5775 {
5776 proto_item *ti;
5777 proto_tree *fh_tree;
5778 guint8 byte0;
5779 int proto_offset;
5780 tvbuff_t *next_tvb;
5781
5782 byte0 = tvb_get_guint8(tvb, 0);
5783
5784 /* PPP HDLC encapsulation */
5785 if (byte0 == 0xff)
5786 proto_offset = 2;
5787 else {
5788 /* address and control are compressed (NULL) */
5789 proto_offset = 0;
5790 }
5791
5792 /* load the top pane info. This should be overwritten by
5793 the next protocol in the stack */
5794 ti = proto_tree_add_item(tree, proto_ppp, tvb, 0, -1, ENC_NA);
5795 fh_tree = proto_item_add_subtree(ti, ett_ppp);
5796 if (byte0 == 0xff) {
5797 proto_tree_add_item(fh_tree, hf_ppp_address, tvb, 0, 1,
5798 ENC_BIG_ENDIAN);
5799 proto_tree_add_item(fh_tree, hf_ppp_control, tvb, 1, 1,
5800 ENC_BIG_ENDIAN);
5801 }
5802
5803 next_tvb = decode_fcs(tvb, pinfo, fh_tree, ppp_fcs_decode, proto_offset);
5804 dissect_ppp_common(next_tvb, pinfo, tree, fh_tree, ti, proto_offset);
5805 }
5806
5807 /*
5808 * Handles link-layer encapsulations where the frame might be
5809 * a PPP in HDLC-like Framing frame (RFC 1662) or a Cisco HDLC frame.
5810 */
5811 static int
dissect_ppp_hdlc(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5812 dissect_ppp_hdlc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
5813 {
5814 guint8 byte0;
5815
5816 byte0 = tvb_get_guint8(tvb, 0);
5817 if (byte0 == CHDLC_ADDR_UNICAST || byte0 == CHDLC_ADDR_MULTICAST) {
5818 /* Cisco HDLC encapsulation */
5819 return call_dissector(chdlc_handle, tvb, pinfo, tree);
5820 }
5821
5822 /*
5823 * XXX - should we have an exported dissector that always dissects
5824 * PPP-in-HDLC-like-framing, without checking for Cisco HDLC, for
5825 * use when we know the packets are PPP, not Cisco HDLC?
5826 */
5827 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP");
5828 switch (pinfo->p2p_dir) {
5829
5830 case P2P_DIR_SENT:
5831 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DTE");
5832 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DCE");
5833 break;
5834
5835 case P2P_DIR_RECV:
5836 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "DCE");
5837 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "DTE");
5838 break;
5839
5840 default:
5841 col_set_str(pinfo->cinfo, COL_RES_DL_SRC, "N/A");
5842 col_set_str(pinfo->cinfo, COL_RES_DL_DST, "N/A");
5843 break;
5844 }
5845
5846 dissect_ppp_hdlc_common(tvb, pinfo, tree);
5847 return tvb_captured_length(tvb);
5848 }
5849
5850 static tvbuff_t*
remove_escape_chars(tvbuff_t * tvb,packet_info * pinfo,int offset,int length)5851 remove_escape_chars(tvbuff_t *tvb, packet_info *pinfo, int offset, int length)
5852 {
5853 guint8 *buff;
5854 int i;
5855 int scanned_len = 0;
5856 guint8 octet;
5857 tvbuff_t *next_tvb;
5858
5859 buff = (guint8 *)wmem_alloc(pinfo->pool, length);
5860 i = 0;
5861 while (scanned_len < length) {
5862 octet = tvb_get_guint8(tvb, offset);
5863 if (octet == 0x7d) {
5864 offset++;
5865 scanned_len++;
5866 if (scanned_len >= length)
5867 break;
5868 octet = tvb_get_guint8(tvb, offset);
5869 buff[i] = octet ^ 0x20;
5870 } else {
5871 buff[i] = octet;
5872 }
5873 offset++;
5874 scanned_len++;
5875 i++;
5876 }
5877 if (i == 0) {
5878 return NULL;
5879 }
5880 next_tvb = tvb_new_child_real_data(tvb, buff, i, i);
5881
5882 return next_tvb;
5883 }
5884
5885 /*
5886 * Handles link-layer encapsulations where we have a raw RFC 1662
5887 * HDLC-like asynchronous framing byte stream, and have to
5888 * break the byte stream into frames and remove escapes.
5889 */
5890 static int
dissect_ppp_raw_hdlc(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)5891 dissect_ppp_raw_hdlc( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_ )
5892 {
5893 proto_item *ti;
5894 proto_tree *bs_tree;
5895 gint offset, end_offset, data_offset;
5896 int length, data_length;
5897 tvbuff_t *ppp_tvb;
5898 gboolean first = TRUE;
5899
5900 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP");
5901
5902 ti = proto_tree_add_item(tree, proto_ppp_hdlc, tvb, 0, -1, ENC_NA);
5903 bs_tree = proto_item_add_subtree(ti, ett_ppp_hdlc_data);
5904
5905 /*
5906 * XXX - this needs to handle a PPP frame split over multiple higher-level
5907 * packets.
5908 */
5909
5910 /*
5911 * Look for a frame delimiter.
5912 */
5913 offset = tvb_find_guint8(tvb, 0, -1, 0x7e);
5914 if (offset == -1) {
5915 /*
5916 * None found - this is presumably continued from an earlier
5917 * packet and continued in a later packet.
5918 */
5919 col_set_str(pinfo->cinfo, COL_INFO, "PPP Fragment");
5920 proto_tree_add_item(bs_tree, hf_ppp_hdlc_fragment, tvb, offset, -1, ENC_NA);
5921 offset++;
5922 length = tvb_captured_length_remaining(tvb,offset);
5923 ppp_tvb = remove_escape_chars(tvb, pinfo, offset,length);
5924 if (ppp_tvb != NULL) {
5925 add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
5926 call_data_dissector(ppp_tvb, pinfo, tree);
5927 }
5928 return tvb_captured_length(tvb);
5929 }
5930 if (offset != 0) {
5931 /*
5932 * We have some data preceding the first PPP packet;
5933 * mark it as a PPP fragment.
5934 */
5935 col_set_str(pinfo->cinfo, COL_INFO, "PPP Fragment");
5936 length = offset;
5937 proto_tree_add_item(bs_tree, hf_ppp_hdlc_fragment, tvb, 0, length, ENC_NA);
5938 if (length != 0) {
5939 ppp_tvb = remove_escape_chars(tvb, pinfo, 0, length - 1);
5940 if (ppp_tvb != NULL) {
5941 add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
5942 call_data_dissector(ppp_tvb, pinfo, tree);
5943 }
5944 }
5945 }
5946 while (tvb_reported_length_remaining(tvb, offset) > 0) {
5947 /*
5948 * Look for the next frame delimiter.
5949 */
5950 end_offset = tvb_find_guint8(tvb, offset + 1, -1, 0x7e);
5951 if (end_offset == -1) {
5952 /*
5953 * We didn't find one. This is probably continued in a later
5954 * packet.
5955 */
5956 if (first)
5957 col_set_str(pinfo->cinfo, COL_INFO, "PPP Fragment");
5958 proto_tree_add_item(bs_tree, hf_ppp_hdlc_fragment, tvb, offset, -1, ENC_NA);
5959 offset++;
5960 length = tvb_captured_length_remaining(tvb, offset);
5961 ppp_tvb = remove_escape_chars(tvb, pinfo, offset, length);
5962 if (ppp_tvb != NULL) {
5963 add_new_data_source(pinfo, ppp_tvb, "PPP Fragment");
5964 call_data_dissector(ppp_tvb, pinfo, tree);
5965 }
5966 return tvb_captured_length(tvb);
5967 }
5968
5969 data_offset = offset + 1; /* skip starting frame delimiter */
5970 data_length = end_offset - data_offset;
5971
5972 /*
5973 * Is that frame delimiter immediately followed by another one?
5974 * Some PPP implementations put a frame delimiter at the
5975 * beginning and the end of each frame, although RFC 1662
5976 * appears only to require that there be one frame delimiter
5977 * between adjacent frames:
5978 *
5979 * Each frame begins and ends with a Flag Sequence, which is the
5980 * binary sequence 01111110 (hexadecimal 0x7e). All implementations
5981 * continuously check for this flag, which is used for frame
5982 * synchronization.
5983 *
5984 * Only one Flag Sequence is required between two frames. Two
5985 * consecutive Flag Sequences constitute an empty frame, which is
5986 * silently discarded, and not counted as a FCS error.
5987 *
5988 * If the delimiter at the end of this frame is followed by
5989 * another delimiter, we consider the first delimiter part
5990 * of this frame.
5991 */
5992 if (tvb_offset_exists(tvb, end_offset + 1) &&
5993 tvb_get_guint8(tvb, end_offset+1) == 0x7e) {
5994 end_offset++;
5995 }
5996 length = end_offset - offset;
5997 proto_tree_add_item(bs_tree, hf_ppp_hdlc_data, tvb, offset, length, ENC_NA);
5998 if (length > 1) {
5999 ppp_tvb = remove_escape_chars(tvb, pinfo, data_offset, data_length);
6000 if (ppp_tvb != NULL) {
6001 add_new_data_source(pinfo, ppp_tvb, "PPP Message");
6002 dissect_ppp_hdlc_common(ppp_tvb, pinfo, tree);
6003 first = FALSE;
6004 }
6005 }
6006 offset = end_offset;
6007 }
6008 return tvb_captured_length(tvb);
6009 }
6010
6011 /*
6012 * At least for the PPP/USB captures I've seen, the data either starts with
6013 * 0x7eff03 or 0x7eff7d23 or 0xff03, so this function performs that heuristic
6014 * matching first before calling dissect_ppp_raw_hdlc(). Otherwise, if we call
6015 * it directly for USB captures, some captures like the following will not be
6016 * dissected correctly:
6017 * https://gitlab.com/wireshark/wireshark/-/wikis/SampleCaptures#head-886e340c31ca977f321c921f81cbec4c21bb7738
6018 */
6019 static gboolean
dissect_ppp_usb(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)6020 dissect_ppp_usb( tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ )
6021 {
6022 /*
6023 * In some cases, the 0x03 normally in byte 3 is escaped so we must look
6024 * for the 2 byte sequence of 0x7d23 instead of 0x03. The 0x23 is
6025 * generated by 0x20^0x03 per section 4.2 of:
6026 * https://tools.ietf.org/html/rfc1662.html.
6027 */
6028 const guchar buf1[3] = {0x7e, 0xff, 0x03};
6029 const guchar buf2[4] = {0x7e, 0xff, 0x7d, 0x23};
6030 tvbuff_t *next_tvb;
6031
6032 if ((tvb_memeql(tvb, 0, buf2, sizeof(buf2)) == 0) ||
6033 (tvb_memeql(tvb, 0, buf1, sizeof(buf1)) == 0)) {
6034 dissect_ppp_raw_hdlc(tvb, pinfo, tree, data);
6035 } else if ((tvb_memeql(tvb, 0, &buf1[1], sizeof(buf1) - 1) == 0) ||
6036 (tvb_memeql(tvb, 0, &buf2[1], sizeof(buf2) - 1) == 0)) {
6037 /* It's missing the 0x7e framing character. What TODO?
6038 * Should we try faking it by sticking 0x7e in front? Or try telling
6039 * dissect_ppp_raw_hdlc() NOT to look for the 0x7e frame deliminator?
6040 * Or is this a bug in libpcap (used 1.1.0)?
6041 * Or a bug in the Linux kernel (tested with 2.6.24.4) Or a bug in
6042 * usbmon? Or is the data we're looking at really just part of the
6043 * payload and not control data? Well, at least in my case it's
6044 * definitely not, but not sure if this is always the case. Is this
6045 * issue applicable only to PPP/USB or PPP/XYZ, in which case a more
6046 * general solution should be found?
6047 */
6048 /* For now, just try skipping the framing I guess??? */
6049 if (tvb_get_guint8(tvb, 1) == 0x03)
6050 next_tvb = tvb_new_subset_remaining(tvb, 2);
6051 else
6052 next_tvb = tvb_new_subset_remaining(tvb, 3);
6053 dissect_ppp(next_tvb, pinfo, tree, data);
6054 } else if (tvb_get_guint8(tvb, 0) == 0x7e) {
6055 /* Well, let's guess that since the 1st byte is 0x7e that it really is
6056 * a PPP frame, and the address and control bytes are compressed (NULL)
6057 * per https://tools.ietf.org/html/rfc1662, section 3.2, which means
6058 * that they're omitted from the packet. */
6059 next_tvb = tvb_new_subset_remaining(tvb, 1);
6060 dissect_ppp_hdlc_common(next_tvb, pinfo, tree);
6061 } else
6062 return (FALSE);
6063 return (TRUE);
6064 }
6065
6066 void
proto_register_ppp_raw_hdlc(void)6067 proto_register_ppp_raw_hdlc(void)
6068 {
6069 static hf_register_info hf[] = {
6070 /* Generated from convert_proto_tree_add_text.pl */
6071 { &hf_ppp_hdlc_fragment, { "PPP Fragment", "ppp_hdlc.fragment", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6072 { &hf_ppp_hdlc_data, { "PPP Data", "ppp_hdlc.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6073 };
6074
6075 static gint *ett[] = {
6076 &ett_ppp_hdlc_data
6077 };
6078
6079 proto_ppp_hdlc = proto_register_protocol("PPP In HDLC-Like Framing",
6080 "PPP-HDLC", "ppp_hdlc");
6081 proto_register_subtree_array(ett, array_length(ett));
6082 proto_register_field_array(proto_ppp_hdlc, hf, array_length(hf));
6083
6084 register_capture_dissector_table("ppp_hdlc", "PPP-HDLC");
6085 register_capture_dissector("ppp_hdlc", capture_ppp_hdlc, proto_ppp_hdlc);
6086 }
6087
6088 void
proto_reg_handoff_ppp_raw_hdlc(void)6089 proto_reg_handoff_ppp_raw_hdlc(void)
6090 {
6091 dissector_handle_t ppp_raw_hdlc_handle;
6092 capture_dissector_handle_t ppp_hdlc_cap_handle;
6093
6094 ppp_raw_hdlc_handle = create_dissector_handle(dissect_ppp_raw_hdlc, proto_ppp);
6095
6096 dissector_add_uint("gre.proto", ETHERTYPE_CDMA2000_A10_UBS, ppp_raw_hdlc_handle);
6097 dissector_add_uint("gre.proto", ETHERTYPE_3GPP2, ppp_raw_hdlc_handle);
6098
6099 /*
6100 * The heuristic checks are rather weak. Each payload starting with
6101 * 0x7e is accepted as a PPP over USB frame, this creates a lot of
6102 * false positives. We disable the heuristic subdissector by
6103 * default.
6104 */
6105 heur_dissector_add("usb.bulk", dissect_ppp_usb,
6106 "PPP USB bulk endpoint", "ppp_usb_bulk", proto_ppp, HEURISTIC_DISABLE);
6107
6108 ppp_hdlc_cap_handle = find_capture_dissector("ppp_hdlc");
6109 capture_dissector_add_uint("wtap_encap", WTAP_ENCAP_PPP, ppp_hdlc_cap_handle);
6110 capture_dissector_add_uint("sll.ltype", LINUX_SLL_P_PPPHDLC, ppp_hdlc_cap_handle);
6111 capture_dissector_add_uint("fr.nlpid", NLPID_PPP, ppp_hdlc_cap_handle);
6112
6113 chdlc_cap_handle = find_capture_dissector("chdlc");
6114 }
6115
6116 /*
6117 * Handles PAP just as a protocol field
6118 */
6119 static int
dissect_pap(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)6120 dissect_pap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
6121 {
6122 proto_item *ti, *data_ti;
6123 proto_tree *fh_tree, *data_tree = NULL;
6124 guint8 code;
6125 gchar *peer_id, *password, *message;
6126 guint8 peer_id_length, password_length, message_length;
6127 int offset = 0;
6128
6129 code = tvb_get_guint8(tvb, 0);
6130
6131 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP PAP");
6132 col_set_str(pinfo->cinfo, COL_INFO,
6133 val_to_str_const(code, pap_vals, "Unknown"));
6134
6135 ti = proto_tree_add_item(tree, proto_pap, tvb, 0, -1, ENC_NA);
6136 fh_tree = proto_item_add_subtree(ti, ett_pap);
6137
6138 proto_tree_add_item(fh_tree, hf_pap_code, tvb, offset, 1,
6139 ENC_BIG_ENDIAN);
6140 offset++;
6141
6142 proto_tree_add_item(fh_tree, hf_pap_identifier, tvb, offset, 1,
6143 ENC_BIG_ENDIAN);
6144 offset++;
6145
6146 proto_tree_add_item(fh_tree, hf_pap_length, tvb, offset, 2,
6147 ENC_BIG_ENDIAN);
6148 offset += 2;
6149
6150 data_ti = proto_tree_add_item(fh_tree, hf_pap_data, tvb, offset, -1,
6151 ENC_NA);
6152 data_tree = proto_item_add_subtree(data_ti, ett_pap_data);
6153
6154 switch (code) {
6155 case CONFREQ:
6156 proto_tree_add_item(data_tree, hf_pap_peer_id_length, tvb, offset,
6157 1, ENC_BIG_ENDIAN);
6158 peer_id_length = tvb_get_guint8(tvb, offset);
6159 offset++;
6160
6161 proto_tree_add_item(data_tree, hf_pap_peer_id, tvb, offset,
6162 peer_id_length, ENC_ASCII|ENC_NA);
6163 peer_id = tvb_format_text(pinfo->pool, tvb, offset, peer_id_length);
6164 offset += peer_id_length;
6165
6166 proto_tree_add_item(data_tree, hf_pap_password_length, tvb, offset,
6167 1, ENC_BIG_ENDIAN);
6168 password_length = tvb_get_guint8(tvb, offset);
6169 offset++;
6170
6171 proto_tree_add_item(data_tree, hf_pap_password, tvb, offset,
6172 password_length, ENC_ASCII|ENC_NA);
6173 password = tvb_format_text(pinfo->pool, tvb, offset, password_length);
6174
6175 col_append_fstr(pinfo->cinfo, COL_INFO,
6176 " (Peer-ID='%s', Password='%s')", peer_id, password);
6177 break;
6178
6179 case CONFACK:
6180 case CONFNAK:
6181 proto_tree_add_item(data_tree, hf_pap_message_length, tvb, offset,
6182 1, ENC_BIG_ENDIAN);
6183 message_length = tvb_get_guint8(tvb, offset);
6184 offset +=1;
6185
6186 proto_tree_add_item(data_tree, hf_pap_message, tvb, offset,
6187 message_length, ENC_ASCII|ENC_NA);
6188 message = tvb_format_text(pinfo->pool, tvb, offset, message_length);
6189
6190 col_append_fstr(pinfo->cinfo, COL_INFO, " (Message='%s')",
6191 message);
6192 break;
6193
6194 default:
6195 proto_tree_add_item(data_tree, hf_pap_stuff, tvb, offset, -1,
6196 ENC_NA);
6197 break;
6198 }
6199 return tvb_captured_length(tvb);
6200 }
6201
6202 /*
6203 * RFC 1994
6204 * Handles CHAP just as a protocol field
6205 */
6206 static int
dissect_chap(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)6207 dissect_chap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
6208 {
6209 proto_item *ti;
6210 proto_tree *fh_tree;
6211 proto_item *tf;
6212 proto_tree *field_tree;
6213 guint8 code, value_size;
6214 guint32 length;
6215 int offset;
6216
6217 code = tvb_get_guint8(tvb, 0);
6218 col_set_str(pinfo->cinfo, COL_PROTOCOL, "PPP CHAP");
6219 col_set_str(pinfo->cinfo, COL_INFO,
6220 val_to_str_const(code, chap_vals, "Unknown"));
6221
6222
6223 /* Create CHAP protocol tree */
6224 ti = proto_tree_add_item(tree, proto_chap, tvb, 0, -1, ENC_NA);
6225 fh_tree = proto_item_add_subtree(ti, ett_chap);
6226
6227 proto_tree_add_item(fh_tree, hf_chap_code, tvb, 0, 1, ENC_BIG_ENDIAN);
6228 proto_tree_add_item(fh_tree, hf_chap_identifier, tvb, 1, 1,
6229 ENC_BIG_ENDIAN);
6230
6231 /* Length - make sure it's valid */
6232 length = tvb_get_ntohs(tvb, 2);
6233 if (length < 4) {
6234 proto_tree_add_uint_format_value(fh_tree, hf_chap_length, tvb, 2, 2,
6235 length, "%u (invalid, must be >= 4)", length);
6236 return 4;
6237 }
6238 proto_item_set_len(ti, length);
6239 proto_tree_add_item(fh_tree, hf_chap_length, tvb, 2, 2,
6240 ENC_BIG_ENDIAN);
6241
6242 offset = 4; /* Offset moved to after length field */
6243 length -= 4; /* Length includes previous 4 bytes, subtract */
6244
6245 switch (code) {
6246 /* Challenge or Response data */
6247 case CHAP_CHAL:
6248 case CHAP_RESP:
6249 if (length > 0) {
6250 guint value_offset = 0;
6251 guint name_offset = 0, name_size = 0;
6252
6253 /* Create data subtree */
6254 tf = proto_tree_add_item(fh_tree, hf_chap_data, tvb, offset,
6255 length, ENC_NA);
6256 field_tree = proto_item_add_subtree(tf, ett_chap_data);
6257 length--;
6258
6259 /* Value size */
6260 value_size = tvb_get_guint8(tvb, offset);
6261 if (value_size > length) {
6262 proto_tree_add_uint_format_value(field_tree, hf_chap_value_size, tvb, offset, 1,
6263 value_size, "%d byte%s (invalid, must be <= %u)",
6264 value_size, plurality(value_size, "", "s"), length);
6265 return offset;
6266 }
6267 proto_tree_add_item(field_tree, hf_chap_value_size, tvb,
6268 offset, 1, ENC_BIG_ENDIAN);
6269 offset++;
6270
6271 /* Value */
6272 if (length > 0) {
6273 value_offset = offset;
6274 proto_tree_add_item(field_tree, hf_chap_value, tvb, offset,
6275 value_size, ENC_NA);
6276
6277 /* Move along value_size bytes */
6278 offset += value_size;
6279 length -= value_size;
6280
6281 /* Find name in remaining bytes */
6282 if (length > 0) {
6283 proto_tree_add_item(field_tree, hf_chap_name, tvb,
6284 offset, length, ENC_ASCII|ENC_NA);
6285 name_offset = offset;
6286 name_size = length;
6287 }
6288
6289 /* Show name and value in info column */
6290 col_append_fstr(pinfo->cinfo, COL_INFO,
6291 " (NAME='%s%s', VALUE=0x%s)",
6292 tvb_format_text(pinfo->pool, tvb, name_offset,
6293 (name_size > 20) ? 20 : name_size),
6294 (name_size > 20) ? "..." : "",
6295 tvb_bytes_to_str(pinfo->pool, tvb, value_offset, value_size));
6296 }
6297 }
6298 break;
6299
6300 /* Success or Failure data */
6301 case CHAP_SUCC:
6302 case CHAP_FAIL:
6303 if (length > 0) {
6304 proto_tree_add_item(fh_tree, hf_chap_message, tvb, offset,
6305 length, ENC_ASCII|ENC_NA);
6306 }
6307
6308 /* Show message in info column */
6309 col_append_fstr(pinfo->cinfo, COL_INFO, " (MESSAGE='%s')",
6310 tvb_format_text(pinfo->pool, tvb, offset, length));
6311 break;
6312
6313 /* Code from unknown code type... */
6314 default:
6315 if (length > 0)
6316 proto_tree_add_item(fh_tree, hf_chap_stuff, tvb, offset, length, ENC_NA);
6317 break;
6318 }
6319 return tvb_captured_length(tvb);
6320 }
6321
6322 /*
6323 * RFC 2472.
6324 */
6325 static int
dissect_ipv6cp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)6326 dissect_ipv6cp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
6327 {
6328 dissect_cp(tvb, proto_ipv6cp, ett_ipv6cp, cp_vals, ett_ipv6cp_options, ipv6cp_option_table, pinfo, tree);
6329 return tvb_captured_length(tvb);
6330 }
6331
6332 static void
dissect_ipv6cp_opt_type_len(tvbuff_t * tvb,int offset,proto_tree * tree,const char * name)6333 dissect_ipv6cp_opt_type_len(tvbuff_t *tvb, int offset, proto_tree *tree,
6334 const char *name)
6335 {
6336 guint8 type;
6337
6338 type = tvb_get_guint8(tvb, offset);
6339 proto_tree_add_uint_format_value(tree, hf_ipv6cp_opt_type, tvb, offset, 1,
6340 type, "%s (%u)", name, type);
6341 proto_tree_add_item(tree, hf_ipv6cp_opt_length, tvb, offset + 1, 1, ENC_BIG_ENDIAN);
6342 }
6343
6344 static gboolean
dissect_ipv6cp_fixed_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,int proto,int ett,int expected_length,proto_tree ** ret_tree,proto_item ** ret_item)6345 dissect_ipv6cp_fixed_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
6346 int proto, int ett, int expected_length,
6347 proto_tree** ret_tree, proto_item** ret_item)
6348 {
6349 if (!ppp_option_len_check(tree, pinfo, tvb, proto, tvb_reported_length(tvb), expected_length))
6350 return FALSE;
6351
6352 *ret_item = proto_tree_add_item(tree, proto, tvb, 0, expected_length, ENC_NA);
6353 *ret_tree = proto_item_add_subtree(*ret_item, ett);
6354
6355 dissect_ipv6cp_opt_type_len(tvb, 0, *ret_tree, proto_registrar_get_name(proto));
6356 return TRUE;
6357 }
6358
6359 static int
dissect_ipv6cp_if_id_opt(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)6360 dissect_ipv6cp_if_id_opt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
6361 {
6362 proto_tree* field_tree;
6363 proto_item* tf;
6364 int offset = 0;
6365
6366 if (!dissect_ipv6cp_fixed_opt(tvb, pinfo, tree, proto_ipv6cp_option_if_id, ett_ipv6cp_if_id_opt, 10,
6367 &field_tree, &tf))
6368 return tvb_captured_length(tvb);
6369
6370 proto_tree_add_item(field_tree, hf_ipv6cp_interface_identifier, tvb, offset+2, 8, ENC_NA);
6371 return tvb_captured_length(tvb);
6372 }
6373
6374 void
proto_register_ppp(void)6375 proto_register_ppp(void)
6376 {
6377 static hf_register_info hf[] = {
6378 { &hf_ppp_direction,
6379 { "Direction", "ppp.direction", FT_UINT8, BASE_DEC,
6380 VALS(ppp_direction_vals), 0x0, "PPP direction", HFILL }},
6381 { &hf_ppp_address,
6382 { "Address", "ppp.address", FT_UINT8, BASE_HEX,
6383 NULL, 0x0, NULL, HFILL }},
6384 { &hf_ppp_control,
6385 { "Control", "ppp.control", FT_UINT8, BASE_HEX,
6386 NULL, 0x0, NULL, HFILL }},
6387 { &hf_ppp_protocol,
6388 { "Protocol", "ppp.protocol", FT_UINT16, BASE_HEX|BASE_EXT_STRING,
6389 &ppp_vals_ext, 0x0, NULL, HFILL }},
6390 { &hf_ppp_code,
6391 { "Code", "ppp.code", FT_UINT8, BASE_DEC,
6392 NULL, 0x0, NULL, HFILL }},
6393 { &hf_ppp_identifier,
6394 { "Identifier", "ppp.identifier", FT_UINT8, BASE_DEC_HEX,
6395 NULL, 0x0, NULL, HFILL }},
6396 { &hf_ppp_length,
6397 { "Length", "ppp.length", FT_UINT16, BASE_DEC,
6398 NULL, 0x0, NULL, HFILL }},
6399 { &hf_ppp_magic_number,
6400 { "Magic Number", "ppp.magic_number", FT_UINT32, BASE_HEX,
6401 NULL, 0x0, NULL, HFILL }},
6402 { &hf_ppp_oui,
6403 { "OUI", "ppp.oui", FT_UINT24, BASE_OUI,
6404 NULL, 0x0, NULL, HFILL }},
6405 { &hf_ppp_kind,
6406 { "Kind", "ppp.kind", FT_UINT8, BASE_DEC_HEX,
6407 NULL, 0x0, NULL, HFILL }},
6408 { &hf_ppp_data,
6409 { "Data", "ppp.data", FT_BYTES, BASE_NONE,
6410 NULL, 0x0, NULL, HFILL }},
6411 { &hf_ppp_fcs_16,
6412 { "FCS 16", "ppp.fcs_16", FT_UINT16, BASE_HEX,
6413 NULL, 0x0, NULL, HFILL }},
6414 { &hf_ppp_fcs_32,
6415 { "FCS 32", "ppp.fcs_32", FT_UINT32, BASE_HEX,
6416 NULL, 0x0, NULL, HFILL }},
6417 { &hf_ppp_fcs_status,
6418 { "FCS Status", "ppp.fcs.status", FT_UINT8, BASE_NONE,
6419 VALS(proto_checksum_vals), 0x0, NULL, HFILL }},
6420 };
6421 static gint *ett[] = {
6422 &ett_ppp,
6423 &ett_ppp_opt_type,
6424 &ett_ppp_unknown_opt
6425 };
6426 static ei_register_info ei[] = {
6427 { &ei_ppp_opt_len_invalid, { "ppp.opt.len.invalid", PI_PROTOCOL, PI_WARN, "Invalid length for option", EXPFILL }},
6428 { &ei_ppp_fcs, { "ppp.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
6429 };
6430
6431 module_t *ppp_module;
6432 expert_module_t* expert_ppp;
6433
6434 proto_ppp = proto_register_protocol("Point-to-Point Protocol", "PPP", "ppp");
6435 proto_register_field_array(proto_ppp, hf, array_length(hf));
6436 proto_register_subtree_array(ett, array_length(ett));
6437 expert_ppp = expert_register_protocol(proto_ppp);
6438 expert_register_field_array(expert_ppp, ei, array_length(ei));
6439
6440 /* subdissector code */
6441 ppp_subdissector_table = register_dissector_table("ppp.protocol",
6442 "PPP protocol", proto_ppp, FT_UINT16, BASE_HEX);
6443
6444 ppp_hdlc_handle = register_dissector("ppp_hdlc", dissect_ppp_hdlc, proto_ppp);
6445 register_dissector("ppp_lcp_options", dissect_lcp_options, proto_ppp);
6446 ppp_handle = register_dissector("ppp", dissect_ppp, proto_ppp);
6447
6448 /* Register the preferences for the ppp protocol */
6449 ppp_module = prefs_register_protocol(proto_ppp, NULL);
6450
6451 prefs_register_enum_preference(ppp_module, "fcs_type",
6452 "PPP Frame Checksum Type",
6453 "The type of PPP frame checksum (none, 16-bit, 32-bit)",
6454 &ppp_fcs_decode, fcs_options, FALSE);
6455 prefs_register_obsolete_preference(ppp_module, "decompress_vj");
6456 prefs_register_uint_preference(ppp_module, "default_proto_id",
6457 "PPPMuxCP Default PID (in hex)",
6458 "Default Protocol ID to be used for PPPMuxCP",
6459 16, &pppmux_def_prot_id);
6460 }
6461
6462 void
proto_reg_handoff_ppp(void)6463 proto_reg_handoff_ppp(void)
6464 {
6465 /*
6466 * Get a handle for the CHDLC dissector.
6467 */
6468 chdlc_handle = find_dissector_add_dependency("chdlc", proto_ppp);
6469
6470 dissector_add_uint("fr.nlpid", NLPID_PPP, ppp_handle);
6471
6472 dissector_add_uint("wtap_encap", WTAP_ENCAP_PPP, ppp_hdlc_handle);
6473 dissector_add_uint("wtap_encap", WTAP_ENCAP_PPP_WITH_PHDR,
6474 ppp_hdlc_handle);
6475 dissector_add_uint("sll.ltype", LINUX_SLL_P_PPPHDLC, ppp_hdlc_handle);
6476 dissector_add_uint("osinl.excl", NLPID_PPP, ppp_handle);
6477 dissector_add_uint("gre.proto", ETHERTYPE_PPP, ppp_hdlc_handle);
6478 dissector_add_uint("juniper.proto", JUNIPER_PROTO_PPP, ppp_handle);
6479 dissector_add_uint("sflow_245.header_protocol", SFLOW_245_HEADER_PPP, ppp_hdlc_handle);
6480 dissector_add_uint("l2tp.pw_type", L2TPv3_PROTOCOL_PPP, ppp_hdlc_handle);
6481 }
6482
6483 void
proto_register_mp(void)6484 proto_register_mp(void)
6485 {
6486 static hf_register_info hf[] = {
6487 { &hf_mp_frag,
6488 { "Fragment", "mp.frag", FT_UINT8, BASE_HEX,
6489 NULL, MP_FRAG_MASK, NULL, HFILL }},
6490 { &hf_mp_frag_short,
6491 { "Fragment", "mp.frag", FT_UINT8, BASE_HEX,
6492 NULL, MP_FRAG_MASK_SHORT, NULL, HFILL }},
6493 { &hf_mp_frag_first,
6494 { "First fragment", "mp.first", FT_BOOLEAN, 8,
6495 TFS(&tfs_yes_no), MP_FRAG_FIRST, NULL, HFILL }},
6496 { &hf_mp_frag_last,
6497 { "Last fragment", "mp.last", FT_BOOLEAN, 8,
6498 TFS(&tfs_yes_no), MP_FRAG_LAST, NULL, HFILL }},
6499 { &hf_mp_sequence_num,
6500 { "Sequence number", "mp.seq", FT_UINT24, BASE_DEC,
6501 NULL, 0x0, NULL, HFILL }},
6502 { &hf_mp_sequence_num_cls,
6503 { "Class", "mp.sequence_num_cls", FT_UINT8, BASE_DEC,
6504 NULL, MP_FRAG_CLS, NULL, HFILL }},
6505 { &hf_mp_sequence_num_reserved,
6506 { "Reserved", "mp.sequence_num_reserved", FT_BOOLEAN, 8,
6507 NULL, MP_FRAG_RESERVED, NULL, HFILL }},
6508 { &hf_mp_short_sequence_num,
6509 { "Short Sequence number", "mp.sseq", FT_UINT16, BASE_DEC,
6510 NULL, 0x0FFF, NULL, HFILL }},
6511 { &hf_mp_short_sequence_num_cls,
6512 { "Class", "mp.short_sequence_num_cls", FT_UINT8, BASE_DEC,
6513 NULL, MP_FRAG_CLS_SHORT, NULL, HFILL }},
6514 { &hf_mp_payload,
6515 {"Payload", "mp.payload", FT_BYTES, BASE_NONE,
6516 NULL, 0x00, NULL, HFILL }},
6517 { &hf_mp_fragments,
6518 {"Message fragments", "mp.fragments", FT_NONE, BASE_NONE,
6519 NULL, 0x00, NULL, HFILL }},
6520 { &hf_mp_fragment,
6521 {"Message fragment", "mp.fragment", FT_FRAMENUM, BASE_NONE,
6522 NULL, 0x00, NULL, HFILL }},
6523 { &hf_mp_fragment_overlap,
6524 {"Message fragment overlap", "mp.fragment.overlap",
6525 FT_BOOLEAN, BASE_NONE,
6526 NULL, 0x00, NULL, HFILL }},
6527 { &hf_mp_fragment_overlap_conflicts,
6528 {"Message fragment overlapping with conflicting data", "mp.fragment.overlap.conflicts",
6529 FT_BOOLEAN, BASE_NONE,
6530 NULL, 0x00, NULL, HFILL }},
6531 { &hf_mp_fragment_multiple_tails,
6532 {"Message has multiple tail fragments", "mp.fragment.multiple_tails",
6533 FT_BOOLEAN, BASE_NONE,
6534 NULL, 0x00, NULL, HFILL }},
6535 { &hf_mp_fragment_too_long_fragment,
6536 {"Message fragment too long", "mp.fragment.too_long_fragment",
6537 FT_BOOLEAN, BASE_NONE,
6538 NULL, 0x00, NULL, HFILL }},
6539 { &hf_mp_fragment_error,
6540 {"Message defragmentation error", "mp.fragment.error",
6541 FT_FRAMENUM, BASE_NONE,
6542 NULL, 0x00, NULL, HFILL }},
6543 { &hf_mp_fragment_count,
6544 {"Message fragment count", "mp.fragment.count", FT_UINT32, BASE_DEC,
6545 NULL, 0x00, NULL, HFILL }},
6546 { &hf_mp_reassembled_in,
6547 {"Reassembled in", "mp.reassembled.in", FT_FRAMENUM, BASE_NONE,
6548 NULL, 0x00, NULL, HFILL }},
6549 { &hf_mp_reassembled_length,
6550 {"Reassembled length", "mp.reassembled.length", FT_UINT32, BASE_DEC,
6551 NULL, 0x00, NULL, HFILL }}
6552 };
6553 static gint *ett[] = {
6554 &ett_mp,
6555 &ett_mp_flags,
6556 &ett_mp_fragment,
6557 &ett_mp_fragments
6558 };
6559
6560 module_t *mp_module;
6561
6562 proto_mp = proto_register_protocol("PPP Multilink Protocol", "PPP MP", "mp");
6563 proto_register_field_array(proto_mp, hf, array_length(hf));
6564 proto_register_subtree_array(ett, array_length(ett));
6565 reassembly_table_register(&mp_reassembly_table,
6566 &addresses_reassembly_table_functions);
6567
6568 /* Register the preferences for the PPP multilink protocol */
6569 mp_module = prefs_register_protocol(proto_mp, NULL);
6570
6571 prefs_register_bool_preference(mp_module, "short_seqno",
6572 "Short sequence numbers",
6573 "Whether PPP Multilink frames use 12-bit sequence numbers",
6574 &mp_short_seqno);
6575 prefs_register_uint_preference(mp_module, "max_fragments",
6576 "Maximum fragments",
6577 "Maximum number of PPP Multilink fragments to try to reassemble into one frame",
6578 10, &mp_max_fragments);
6579 prefs_register_uint_preference(mp_module, "fragment_aging",
6580 "Max unreassembled fragment age",
6581 "Age off unreassembled fragments after this many packets",
6582 10, &mp_fragment_aging);
6583 }
6584
6585 void
proto_reg_handoff_mp(void)6586 proto_reg_handoff_mp(void)
6587 {
6588 dissector_handle_t mp_handle;
6589
6590 mp_handle = create_dissector_handle(dissect_mp, proto_mp);
6591 dissector_add_uint("ppp.protocol", PPP_MP, mp_handle);
6592 }
6593
6594 void
proto_register_lcp(void)6595 proto_register_lcp(void)
6596 {
6597 static hf_register_info hf[] = {
6598 { &hf_lcp_magic_number,
6599 { "Magic Number", "lcp.magic_number", FT_UINT32, BASE_HEX,
6600 NULL, 0x0, NULL, HFILL }},
6601 { &hf_lcp_data,
6602 { "Data", "lcp.data", FT_BYTES, BASE_NONE,
6603 NULL, 0x0, NULL, HFILL }},
6604 { &hf_lcp_message,
6605 { "Message", "lcp.message", FT_STRING, BASE_NONE,
6606 NULL, 0x0, NULL, HFILL }},
6607 { &hf_lcp_secs_remaining,
6608 { "Seconds Remaining", "lcp.secs_remaining", FT_UINT32, BASE_DEC,
6609 NULL, 0x0, NULL, HFILL }},
6610 { &hf_lcp_rej_proto,
6611 { "Rejected Protocol", "lcp.rej_proto", FT_UINT16,
6612 BASE_HEX | BASE_EXT_STRING, &ppp_vals_ext, 0x0, NULL, HFILL }},
6613 { &hf_lcp_opt_type,
6614 { "Type", "lcp.opt.type", FT_UINT8, BASE_DEC,
6615 NULL, 0x0, NULL, HFILL }},
6616 { &hf_lcp_opt_length,
6617 { "Length", "lcp.opt.length", FT_UINT8, BASE_DEC,
6618 NULL, 0x0, NULL, HFILL }},
6619 { &hf_lcp_opt_oui,
6620 { "OUI", "lcp.opt.oui", FT_UINT24, BASE_OUI,
6621 NULL, 0x0, NULL, HFILL }},
6622 { &hf_lcp_opt_kind,
6623 { "Kind", "lcp.opt.kind", FT_UINT8, BASE_DEC_HEX,
6624 NULL, 0x0, NULL, HFILL }},
6625 { &hf_lcp_opt_data,
6626 { "Data", "lcp.opt.data", FT_BYTES, BASE_NONE,
6627 NULL, 0x0, NULL, HFILL }},
6628 { &hf_lcp_opt_mru,
6629 { "Maximum Receive Unit", "lcp.opt.mru", FT_UINT16, BASE_DEC,
6630 NULL, 0x0, NULL, HFILL }},
6631 { &hf_lcp_opt_asyncmap,
6632 { "Async Control Character Map", "lcp.opt.asyncmap", FT_UINT32,
6633 BASE_HEX, NULL, 0x0, NULL, HFILL }},
6634 { &hf_lcp_opt_asyncmap_nul,
6635 { "NUL", "lcp.opt.asyncmap.nul", FT_BOOLEAN, 32,
6636 NULL, 0x00000001, NULL, HFILL }},
6637 { &hf_lcp_opt_asyncmap_soh,
6638 { "SOH", "lcp.opt.asyncmap.soh", FT_BOOLEAN, 32,
6639 NULL, 0x00000002, NULL, HFILL }},
6640 { &hf_lcp_opt_asyncmap_stx,
6641 { "STX", "lcp.opt.asyncmap.stx", FT_BOOLEAN, 32,
6642 NULL, 0x00000004, NULL, HFILL }},
6643 { &hf_lcp_opt_asyncmap_etx,
6644 { "ETX", "lcp.opt.asyncmap.etx", FT_BOOLEAN, 32,
6645 NULL, 0x00000008, NULL, HFILL }},
6646 { &hf_lcp_opt_asyncmap_eot,
6647 { "EOT", "lcp.opt.asyncmap.eot", FT_BOOLEAN, 32,
6648 NULL, 0x00000010, NULL, HFILL }},
6649 { &hf_lcp_opt_asyncmap_enq,
6650 { "ENQ", "lcp.opt.asyncmap.enq", FT_BOOLEAN, 32,
6651 NULL, 0x00000020, NULL, HFILL }},
6652 { &hf_lcp_opt_asyncmap_ack,
6653 { "ACK", "lcp.opt.asyncmap.ack", FT_BOOLEAN, 32,
6654 NULL, 0x00000040, NULL, HFILL }},
6655 { &hf_lcp_opt_asyncmap_bel,
6656 { "BEL", "lcp.opt.asyncmap.bel", FT_BOOLEAN, 32,
6657 NULL, 0x00000080, NULL, HFILL }},
6658 { &hf_lcp_opt_asyncmap_bs,
6659 { "BS", "lcp.opt.asyncmap.bs", FT_BOOLEAN, 32,
6660 NULL, 0x00000100, NULL, HFILL }},
6661 { &hf_lcp_opt_asyncmap_ht,
6662 { "HT", "lcp.opt.asyncmap.ht", FT_BOOLEAN, 32,
6663 NULL, 0x00000200, NULL, HFILL }},
6664 { &hf_lcp_opt_asyncmap_lf,
6665 { "LF", "lcp.opt.asyncmap.lf", FT_BOOLEAN, 32,
6666 NULL, 0x00000400, NULL, HFILL }},
6667 { &hf_lcp_opt_asyncmap_vt,
6668 { "VT", "lcp.opt.asyncmap.vt", FT_BOOLEAN, 32,
6669 NULL, 0x00000800, NULL, HFILL }},
6670 { &hf_lcp_opt_asyncmap_ff,
6671 { "FF", "lcp.opt.asyncmap.ff", FT_BOOLEAN, 32,
6672 NULL, 0x00001000, NULL, HFILL }},
6673 { &hf_lcp_opt_asyncmap_cr,
6674 { "CR", "lcp.opt.asyncmap.cr", FT_BOOLEAN, 32,
6675 NULL, 0x00002000, NULL, HFILL }},
6676 { &hf_lcp_opt_asyncmap_so,
6677 { "SO", "lcp.opt.asyncmap.so", FT_BOOLEAN, 32,
6678 NULL, 0x00004000, NULL, HFILL }},
6679 { &hf_lcp_opt_asyncmap_si,
6680 { "SI", "lcp.opt.asyncmap.si", FT_BOOLEAN, 32,
6681 NULL, 0x00008000, NULL, HFILL }},
6682 { &hf_lcp_opt_asyncmap_dle,
6683 { "DLE", "lcp.opt.asyncmap.dle", FT_BOOLEAN, 32,
6684 NULL, 0x00010000, NULL, HFILL }},
6685 { &hf_lcp_opt_asyncmap_dc1,
6686 { "DC1 (XON)", "lcp.opt.asyncmap.dc1", FT_BOOLEAN, 32,
6687 NULL, 0x00020000, NULL, HFILL }},
6688 { &hf_lcp_opt_asyncmap_dc2,
6689 { "DC2", "lcp.opt.asyncmap.dc2", FT_BOOLEAN, 32,
6690 NULL, 0x00040000, NULL, HFILL }},
6691 { &hf_lcp_opt_asyncmap_dc3,
6692 { "DC3 (XOFF)", "lcp.opt.asyncmap.dc3", FT_BOOLEAN, 32,
6693 NULL, 0x00080000, NULL, HFILL }},
6694 { &hf_lcp_opt_asyncmap_dc4,
6695 { "DC4", "lcp.opt.asyncmap.dc4", FT_BOOLEAN, 32,
6696 NULL, 0x00100000, NULL, HFILL }},
6697 { &hf_lcp_opt_asyncmap_nak,
6698 { "NAK", "lcp.opt.asyncmap.nak", FT_BOOLEAN, 32,
6699 NULL, 0x00200000, NULL, HFILL }},
6700 { &hf_lcp_opt_asyncmap_syn,
6701 { "SYN", "lcp.opt.asyncmap.syn", FT_BOOLEAN, 32,
6702 NULL, 0x00400000, NULL, HFILL }},
6703 { &hf_lcp_opt_asyncmap_etb,
6704 { "ETB", "lcp.opt.asyncmap.etb", FT_BOOLEAN, 32,
6705 NULL, 0x00800000, NULL, HFILL }},
6706 { &hf_lcp_opt_asyncmap_can,
6707 { "CAN", "lcp.opt.asyncmap.can", FT_BOOLEAN, 32,
6708 NULL, 0x01000000, NULL, HFILL }},
6709 { &hf_lcp_opt_asyncmap_em,
6710 { "EM", "lcp.opt.asyncmap.em", FT_BOOLEAN, 32,
6711 NULL, 0x02000000, NULL, HFILL }},
6712 { &hf_lcp_opt_asyncmap_sub,
6713 { "SUB", "lcp.opt.asyncmap.sub", FT_BOOLEAN, 32,
6714 NULL, 0x04000000, NULL, HFILL }},
6715 { &hf_lcp_opt_asyncmap_esc,
6716 { "ESC", "lcp.opt.asyncmap.esc", FT_BOOLEAN, 32,
6717 NULL, 0x08000000, NULL, HFILL }},
6718 { &hf_lcp_opt_asyncmap_fs,
6719 { "FS", "lcp.opt.asyncmap.fs", FT_BOOLEAN, 32,
6720 NULL, 0x10000000, NULL, HFILL }},
6721 { &hf_lcp_opt_asyncmap_gs,
6722 { "GS", "lcp.opt.asyncmap.gs", FT_BOOLEAN, 32,
6723 NULL, 0x20000000, NULL, HFILL }},
6724 { &hf_lcp_opt_asyncmap_rs,
6725 { "RS", "lcp.opt.asyncmap.rs", FT_BOOLEAN, 32,
6726 NULL, 0x40000000, NULL, HFILL }},
6727 { &hf_lcp_opt_asyncmap_us,
6728 { "US", "lcp.opt.asyncmap.us", FT_BOOLEAN, 32,
6729 NULL, 0x80000000, NULL, HFILL }},
6730 { &hf_lcp_opt_auth_protocol,
6731 { "Authentication Protocol", "lcp.opt.auth_protocol", FT_UINT16,
6732 BASE_HEX | BASE_EXT_STRING, &ppp_vals_ext, 0x0, NULL, HFILL }},
6733 { &hf_lcp_opt_algorithm,
6734 { "Algorithm", "lcp.opt.algorithm", FT_UINT8,
6735 BASE_DEC | BASE_RANGE_STRING, &chap_alg_rvals,
6736 0x0, NULL, HFILL }},
6737 { &hf_lcp_opt_quality_protocol,
6738 { "Quality Protocol", "lcp.opt.quality_protocol", FT_UINT16,
6739 BASE_HEX | BASE_EXT_STRING, &ppp_vals_ext, 0x0, NULL, HFILL }},
6740 { &hf_lcp_opt_magic_number,
6741 { "Magic Number", "lcp.opt.magic_number", FT_UINT32, BASE_HEX,
6742 NULL, 0x0, NULL, HFILL }},
6743 { &hf_lcp_opt_reportingperiod,
6744 { "Reporting Period", "lcp.opt.reporting_period", FT_UINT32,
6745 BASE_DEC|BASE_UNIT_STRING, &units_microsecond_microseconds, 0x0,
6746 "Maximum time in micro-seconds that the remote end should "
6747 "wait between transmission of LCP Link-Quality-Report packets",
6748 HFILL }},
6749 { &hf_lcp_opt_fcs_alternatives,
6750 { "FCS Alternatives", "lcp.opt.fcs_alternatives", FT_UINT8,
6751 BASE_HEX, NULL, 0x0, NULL, HFILL }},
6752 { &hf_lcp_opt_fcs_alternatives_null,
6753 { "NULL FCS", "lcp.opt.fcs_alternatives.null", FT_BOOLEAN, 8,
6754 NULL, 0x01, NULL, HFILL }},
6755 { &hf_lcp_opt_fcs_alternatives_ccitt16,
6756 { "CCITT 16-bit", "lcp.opt.fcs_alternatives.ccitt16", FT_BOOLEAN,
6757 8, NULL, 0x02, NULL, HFILL }},
6758 { &hf_lcp_opt_fcs_alternatives_ccitt32,
6759 { "CCITT 32-bit", "lcp.opt.fcs_alternatives.ccitt32", FT_BOOLEAN,
6760 8, NULL, 0x04, NULL, HFILL }},
6761 { &hf_lcp_opt_maximum,
6762 { "Maximum", "lcp.opt.maximum", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, &units_octet_octets, 0x0,
6763 "The largest number of padding octets which may be added "
6764 "to the frame.", HFILL }},
6765 { &hf_lcp_opt_window,
6766 { "Window", "lcp.opt.window", FT_UINT8, BASE_DEC|BASE_UNIT_STRING, &units_frame_frames, 0x0,
6767 "The number of frames the receiver will buffer.", HFILL }},
6768 { &hf_lcp_opt_hdlc_address,
6769 { "Address", "lcp.opt.hdlc_address", FT_BYTES, BASE_NONE, NULL,
6770 0x0, "An HDLC Address as specified in ISO 3309.", HFILL }},
6771 { &hf_lcp_opt_operation,
6772 { "Operation", "lcp.opt.operation", FT_UINT8, BASE_DEC,
6773 VALS(callback_op_vals), 0x0, NULL, HFILL }},
6774 { &hf_lcp_opt_message,
6775 { "Message", "lcp.opt.message", FT_BYTES, BASE_NONE,
6776 NULL, 0x0, NULL, HFILL }},
6777 { &hf_lcp_opt_mrru,
6778 { "MRRU", "lcp.opt.mrru", FT_UINT16, BASE_DEC, NULL, 0x0,
6779 "Maximum Receive Reconstructed Unit", HFILL }},
6780 { &hf_lcp_opt_ep_disc_class,
6781 { "Class", "lcp.opt.ep_disc_class", FT_UINT8, BASE_DEC,
6782 VALS(multilink_ep_disc_class_vals), 0x0, NULL, HFILL }},
6783 { &hf_lcp_opt_ip_address,
6784 { "IP Address", "lcp.opt.ip_address", FT_IPv4, BASE_NONE,
6785 NULL, 0x0, NULL, HFILL }},
6786 { &hf_lcp_opt_802_1_address,
6787 { "IEEE 802.1 Address", "lcp.opt.802_1_address", FT_ETHER,
6788 BASE_NONE, NULL, 0x0, NULL, HFILL }},
6789 { &hf_lcp_opt_magic_block,
6790 { "PPP Magic-Number Block", "lcp.opt.magic_block", FT_BYTES,
6791 BASE_NONE, NULL, 0x0, NULL, HFILL }},
6792 { &hf_lcp_opt_psndn,
6793 { "Public Switched Network Directory Number", "lcp.opt.psndn",
6794 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6795 { &hf_lcp_opt_mode,
6796 { "Mode", "lcp.opt.mode", FT_UINT8, BASE_DEC,
6797 VALS(dce_id_mode_vals), 0x0, NULL, HFILL }},
6798 { &hf_lcp_opt_unused,
6799 { "Unused", "lcp.opt.unused", FT_BYTES, BASE_NONE,
6800 NULL, 0x0, NULL, HFILL }},
6801 { &hf_lcp_opt_link_discrim,
6802 { "Link Discriminator", "lcp.opt.link_discrim", FT_UINT16,
6803 BASE_DEC_HEX, NULL, 0x0, NULL, HFILL }},
6804 { &hf_lcp_opt_id,
6805 { "Identification", "lcp.opt.id", FT_UINT_BYTES, BASE_NONE,
6806 NULL, 0x0, NULL, HFILL }},
6807 { &hf_lcp_opt_cobs_flags,
6808 { "Flags", "lcp.opt.flags", FT_UINT8, BASE_HEX,
6809 NULL, 0x0, NULL, HFILL }},
6810 { &hf_lcp_opt_cobs_flags_res,
6811 { "Reserved", "lcp.opt.flags.reserved", FT_UINT8, BASE_HEX,
6812 NULL, 0xFC, NULL, HFILL }},
6813 { &hf_lcp_opt_cobs_flags_pre,
6814 { "PRE", "lcp.opt.flags.pre", FT_BOOLEAN, 8,
6815 NULL, 0x02, "Preemption", HFILL }},
6816 { &hf_lcp_opt_cobs_flags_zxe,
6817 { "ZXE", "lcp.opt.flags.zxe", FT_BOOLEAN, 8,
6818 NULL, 0x01, "Zero pair/run elimination", HFILL }},
6819 { &hf_lcp_opt_class,
6820 { "Class", "lcp.opt.class", FT_UINT8, BASE_DEC,
6821 NULL, 0x0, NULL, HFILL }},
6822 { &hf_lcp_opt_prefix,
6823 { "Prefix", "lcp.opt.prefix", FT_UINT_BYTES, BASE_NONE,
6824 NULL, 0x0, NULL, HFILL }},
6825 { &hf_lcp_opt_code,
6826 { "Code", "lcp.opt.code", FT_UINT8, BASE_DEC,
6827 VALS(ml_hdr_fmt_code_vals), 0x0, NULL, HFILL }},
6828 { &hf_lcp_opt_max_susp_classes,
6829 { "Max suspendable classes", "lcp.opt.max_susp_classes",
6830 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
6831 { &hf_lcp_opt_MIBenum,
6832 { "MIBenum", "lcp.opt.MIBenum", FT_UINT32,
6833 BASE_DEC | BASE_EXT_STRING, &charset_vals_ext, 0x0,
6834 "A unique integer value identifying a charset", HFILL }},
6835 { &hf_lcp_opt_language_tag,
6836 { "Language-Tag", "lcp.opt.language_tag", FT_STRING, BASE_NONE,
6837 NULL, 0x0, NULL, HFILL }}
6838 };
6839
6840 static gint *ett[] = {
6841 &ett_lcp,
6842 &ett_lcp_options,
6843 &ett_lcp_vendor_opt,
6844 &ett_lcp_mru_opt,
6845 &ett_lcp_asyncmap_opt,
6846 &ett_lcp_authprot_opt,
6847 &ett_lcp_qualprot_opt,
6848 &ett_lcp_magicnumber_opt,
6849 &ett_lcp_linkqualmon_opt,
6850 &ett_lcp_pcomp_opt,
6851 &ett_lcp_acccomp_opt,
6852 &ett_lcp_fcs_alternatives_opt,
6853 &ett_lcp_self_desc_pad_opt,
6854 &ett_lcp_numbered_mode_opt,
6855 &ett_lcp_callback_opt,
6856 &ett_lcp_compound_frames_opt,
6857 &ett_lcp_nomdataencap_opt,
6858 &ett_lcp_multilink_mrru_opt,
6859 &ett_lcp_multilink_ssnh_opt,
6860 &ett_lcp_multilink_ep_disc_opt,
6861 &ett_lcp_magic_block,
6862 &ett_lcp_dce_identifier_opt,
6863 &ett_lcp_multilink_pp_opt,
6864 &ett_lcp_bacp_link_discrim_opt,
6865 &ett_lcp_auth_opt,
6866 &ett_lcp_cobs_opt,
6867 &ett_lcp_prefix_elision_opt,
6868 &ett_multilink_hdr_fmt_opt,
6869 &ett_lcp_internationalization_opt,
6870 &ett_lcp_sonet_sdh_opt
6871 };
6872
6873 proto_lcp = proto_register_protocol("PPP Link Control Protocol", "PPP LCP", "lcp");
6874 proto_register_field_array(proto_lcp, hf, array_length(hf));
6875 proto_register_subtree_array(ett, array_length(ett));
6876
6877 lcp_option_table = register_dissector_table("lcp.option", "PPP LCP Options", proto_lcp, FT_UINT8, BASE_DEC);
6878
6879 /* Register LCP options as their own protocols so we can get the name of the option */
6880 proto_lcp_option_vendor = proto_register_protocol_in_name_only("Vendor Specific", "Vendor Specific", "lcp.opt.vendor", proto_lcp, FT_BYTES);
6881 proto_lcp_option_mru = proto_register_protocol_in_name_only("Maximum Receive Unit", "Maximum Receive Unit", "lcp.opt.mtu_bytes", proto_lcp, FT_BYTES);
6882 proto_lcp_option_async_map = proto_register_protocol_in_name_only("Async Control Character Map", "Async Control Character Map", "lcp.opt.asyncmap_bytes", proto_lcp, FT_BYTES);
6883 proto_lcp_option_authprot = proto_register_protocol_in_name_only("Authentication Protocol", "Authentication Protocol", "lcp.opt.auth_protocol_bytes", proto_lcp, FT_BYTES);
6884 proto_lcp_option_qualprot = proto_register_protocol_in_name_only("Quality Protocol", "Quality Protocol", "lcp.opt.quality_protocol_bytes", proto_lcp, FT_BYTES);
6885 proto_lcp_option_magicnumber = proto_register_protocol_in_name_only("Magic Number", "Magic Number", "lcp.opt.magic_number_bytes", proto_lcp, FT_BYTES);
6886 proto_lcp_option_linkqualmon = proto_register_protocol_in_name_only("Link Quality Monitoring", "Link Quality Monitoring", "lcp.opt.linkqualmon", proto_lcp, FT_BYTES);
6887 proto_lcp_option_field_compress = proto_register_protocol_in_name_only("Protocol Field Compression", "Protocol Field Compression", "lcp.opt.field_compress", proto_lcp, FT_BYTES);
6888 proto_lcp_option_addr_field_compress = proto_register_protocol_in_name_only("Address and Control Field Compression", "Address and Control Field Compression", "lcp.opt.addr_field_compress", proto_lcp, FT_BYTES);
6889 proto_lcp_option_fcs_alternatives = proto_register_protocol_in_name_only("FCS Alternatives", "FCS Alternatives", "lcp.opt.fcs_alternatives_bytes", proto_lcp, FT_BYTES);
6890 proto_lcp_option_self_desc_pad = proto_register_protocol_in_name_only("Self Describing Pad", "Self Describing Pad", "lcp.opt.self_desc_pad", proto_lcp, FT_BYTES);
6891 proto_lcp_option_numbered_mode = proto_register_protocol_in_name_only("Numbered Mode", "Numbered Mode", "lcp.opt.numbered_mode", proto_lcp, FT_BYTES);
6892 /* TODO? CI_MULTILINK_PROC */
6893 proto_lcp_option_callback = proto_register_protocol_in_name_only("Callback", "Callback", "lcp.opt.callback", proto_lcp, FT_BYTES);
6894 /* TODO? CI_CONNECTTIME */
6895 proto_lcp_option_compound_frames = proto_register_protocol_in_name_only("Compound Frames (Deprecated)", "Compound Frames (Deprecated)", "lcp.opt.compound_frames", proto_lcp, FT_BYTES);
6896 proto_lcp_option_nomdataencap = proto_register_protocol_in_name_only("Nominal Data Encapsulation (Deprecated)", "Nominal Data Encapsulation (Deprecated)", "lcp.opt.nomdataencap", proto_lcp, FT_BYTES);
6897 proto_lcp_option_multilink_mrru = proto_register_protocol_in_name_only("Multilink MRRU", "Multilink MRRU", "lcp.opt.multilink_mrru", proto_lcp, FT_BYTES);
6898 proto_lcp_option_multilink_ssnh = proto_register_protocol_in_name_only("Multilink Short Sequence Number Header", "Multilink Short Sequence Number Header", "lcp.opt.multilink_ssnh", proto_lcp, FT_BYTES);
6899 proto_lcp_option_multilink_ep_disc = proto_register_protocol_in_name_only("Multilink Endpoint Discriminator", "Multilink Endpoint Discriminator", "lcp.opt.multilink_ep_disc", proto_lcp, FT_BYTES);
6900 /* TODO? CI_PROP_KEN: ken@funk.com: www.funk.com => www.juniper.net */
6901 proto_lcp_option_dce_identifier = proto_register_protocol_in_name_only("DCE Identifier", "DCE Identifier", "lcp.opt.dce_identifier", proto_lcp, FT_BYTES);
6902 proto_lcp_option_multilink_pp = proto_register_protocol_in_name_only("Multi Link Plus Procedure", "Multi Link Plus Procedure", "lcp.opt.multilink_pp", proto_lcp, FT_BYTES);
6903 proto_lcp_option_link_discrim = proto_register_protocol_in_name_only("Link Discriminator for BACP", "Link Discriminator for BACP", "lcp.opt.link_discrim_bytes", proto_lcp, FT_BYTES);
6904 proto_lcp_option_auth = proto_register_protocol_in_name_only("Authentication Option", "Authentication Option", "lcp.opt.auth", proto_lcp, FT_BYTES);
6905 proto_lcp_option_cobs = proto_register_protocol_in_name_only("Consistent Overhead Byte Stuffing (COBS)", "Consistent Overhead Byte Stuffing (COBS)", "lcp.opt.cobs", proto_lcp, FT_BYTES);
6906 proto_lcp_option_prefix_elision = proto_register_protocol_in_name_only("Prefix Elision", "Prefix Elision", "lcp.opt.prefix_elision", proto_lcp, FT_BYTES);
6907 proto_lcp_option_multilink_hdr_fmt = proto_register_protocol_in_name_only("Multilink header format", "Multilink header format", "lcp.opt.multilink_hdr_fmt", proto_lcp, FT_BYTES);
6908 proto_lcp_option_internationalization = proto_register_protocol_in_name_only("Internationalization", "Internationalization", "lcp.opt.internationalization", proto_lcp, FT_BYTES);
6909 proto_lcp_option_sonet_sdh = proto_register_protocol_in_name_only("Simple Data Link on SONET/SDH", "Simple Data Link on SONET/SDH", "lcp.opt.sonet_sdh", proto_lcp, FT_BYTES);
6910 }
6911
6912 void
proto_reg_handoff_lcp(void)6913 proto_reg_handoff_lcp(void)
6914 {
6915 dissector_handle_t lcp_handle;
6916
6917 lcp_handle = create_dissector_handle(dissect_lcp, proto_lcp);
6918 dissector_add_uint("ppp.protocol", PPP_LCP, lcp_handle);
6919
6920
6921 /*
6922 * NDISWAN on Windows translates Ethernet frames from higher-level
6923 * protocols into PPP frames to hand to the PPP driver, and translates
6924 * PPP frames from the PPP driver to hand to the higher-level protocols.
6925 *
6926 * Apparently the PPP driver, on at least some versions of Windows,
6927 * passes frames for internal-to-PPP protocols up through NDISWAN;
6928 * the protocol type field appears to be passed through unchanged
6929 * (unlike what's done with, for example, the protocol type field
6930 * for IP, which is mapped from its PPP value to its Ethernet value).
6931 *
6932 * This means that we may see, on Ethernet captures, frames for
6933 * protocols internal to PPP, so we register PPP_LCP with the
6934 * "ethertype" dissector table as well as the PPP protocol dissector
6935 * table.
6936 */
6937 dissector_add_uint("ethertype", PPP_LCP, lcp_handle);
6938
6939 /*
6940 * for GSM-A / MobileL3 / GPRS SM / PCO
6941 */
6942 dissector_add_uint("sm_pco.protocol", PPP_LCP, lcp_handle);
6943
6944 /* Create dissection function handles for all LCP options */
6945 dissector_add_uint("lcp.option", CI_VENDORSPECIFIC, create_dissector_handle( dissect_lcp_vendor_opt, proto_lcp_option_vendor ));
6946 dissector_add_uint("lcp.option", CI_MRU, create_dissector_handle( dissect_lcp_mru_opt, proto_lcp_option_mru ));
6947 dissector_add_uint("lcp.option", CI_ASYNCMAP, create_dissector_handle( dissect_lcp_async_map_opt, proto_lcp_option_async_map ));
6948 dissector_add_uint("lcp.option", CI_AUTHPROT, create_dissector_handle( dissect_lcp_authprot_opt, proto_lcp_option_authprot ));
6949 dissector_add_uint("lcp.option", CI_QUALITY, create_dissector_handle( dissect_lcp_qualprot_opt, proto_lcp_option_qualprot ));
6950 dissector_add_uint("lcp.option", CI_MAGICNUMBER, create_dissector_handle( dissect_lcp_magicnumber_opt, proto_lcp_option_magicnumber ));
6951 dissector_add_uint("lcp.option", CI_LINKQUALMON, create_dissector_handle( dissect_lcp_linkqualmon_opt, proto_lcp_option_linkqualmon ));
6952 dissector_add_uint("lcp.option", CI_PCOMPRESSION, create_dissector_handle( dissect_lcp_field_compress, proto_lcp_option_field_compress ));
6953 dissector_add_uint("lcp.option", CI_ACCOMPRESSION, create_dissector_handle( dissect_lcp_addr_field_compress, proto_lcp_option_addr_field_compress ));
6954 dissector_add_uint("lcp.option", CI_FCS_ALTERNATIVES, create_dissector_handle( dissect_lcp_fcs_alternatives_opt, proto_lcp_option_fcs_alternatives ));
6955 dissector_add_uint("lcp.option", CI_SELF_DESCRIBING_PAD, create_dissector_handle( dissect_lcp_self_describing_pad_opt, proto_lcp_option_self_desc_pad ));
6956 dissector_add_uint("lcp.option", CI_NUMBERED_MODE, create_dissector_handle( dissect_lcp_numbered_mode_opt, proto_lcp_option_numbered_mode ));
6957 /* TODO? CI_MULTILINK_PROC */
6958 dissector_add_uint("lcp.option", CI_CALLBACK, create_dissector_handle( dissect_lcp_callback_opt, proto_lcp_option_callback ));
6959 /* TODO? CI_CONNECTTIME */
6960 dissector_add_uint("lcp.option", CI_COMPOUND_FRAMES, create_dissector_handle( dissect_lcp_compound_frames_opt, proto_lcp_option_compound_frames ));
6961 dissector_add_uint("lcp.option", CI_NOMDATAENCAP, create_dissector_handle( dissect_lcp_nomdataencap_opt, proto_lcp_option_nomdataencap ));
6962 dissector_add_uint("lcp.option", CI_MULTILINK_MRRU, create_dissector_handle( dissect_lcp_multilink_mrru_opt, proto_lcp_option_multilink_mrru ));
6963 dissector_add_uint("lcp.option", CI_MULTILINK_SSNH, create_dissector_handle( dissect_lcp_multilink_ssnh_opt, proto_lcp_option_multilink_ssnh ));
6964 dissector_add_uint("lcp.option", CI_MULTILINK_EP_DISC, create_dissector_handle( dissect_lcp_multilink_ep_disc_opt, proto_lcp_option_multilink_ep_disc ));
6965 /* TODO? CI_PROP_KEN: ken@funk.com: www.funk.com => www.juniper.net */
6966 dissector_add_uint("lcp.option", CI_DCE_IDENTIFIER, create_dissector_handle( dissect_lcp_dce_identifier_opt, proto_lcp_option_dce_identifier ));
6967 dissector_add_uint("lcp.option", CI_MULTILINK_PLUS_PROC, create_dissector_handle( dissect_lcp_multilink_pp_opt, proto_lcp_option_multilink_pp ));
6968 dissector_add_uint("lcp.option", CI_LINK_DISC_FOR_BACP, create_dissector_handle( dissect_lcp_bacp_link_discriminator_opt, proto_lcp_option_link_discrim ));
6969 dissector_add_uint("lcp.option", CI_LCP_AUTHENTICATION, create_dissector_handle( dissect_lcp_auth_opt, proto_lcp_option_auth ));
6970 dissector_add_uint("lcp.option", CI_COBS, create_dissector_handle( dissect_lcp_cobs_opt, proto_lcp_option_cobs ));
6971 dissector_add_uint("lcp.option", CI_PREFIX_ELISION, create_dissector_handle( dissect_lcp_prefix_elision_opt, proto_lcp_option_prefix_elision ));
6972 dissector_add_uint("lcp.option", CI_MULTILINK_HDR_FMT, create_dissector_handle( dissect_lcp_multilink_hdr_fmt_opt, proto_lcp_option_multilink_hdr_fmt ));
6973 dissector_add_uint("lcp.option", CI_INTERNATIONALIZATION, create_dissector_handle( dissect_lcp_internationalization_opt, proto_lcp_option_internationalization ));
6974 dissector_add_uint("lcp.option", CI_SDL_ON_SONET_SDH, create_dissector_handle( dissect_lcp_sonet_sdh_opt, proto_lcp_option_sonet_sdh ));
6975 }
6976
6977 void
proto_register_vsncp(void)6978 proto_register_vsncp(void)
6979 {
6980 static hf_register_info hf[] = {
6981 { &hf_vsncp_opt_type, { "Type", "vsncp.opt.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
6982 { &hf_vsncp_opt_length, { "Length", "vsncp.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
6983 /* Generated from convert_proto_tree_add_text.pl */
6984 { &hf_vsncp_pdn_identifier, { "PDN Identifier", "vsncp.pdn_identifier", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
6985 { &hf_vsncp_attach_type, { "Attach Type", "vsncp.attach_type", FT_UINT8, BASE_HEX, VALS(vsncp_attach_vals), 0x0, NULL, HFILL }},
6986 { &hf_vsncp_pdn_type, { "PDN Type", "vsncp.pdn_type", FT_UINT8, BASE_HEX, VALS(vsncp_pdntype_vals), 0x0, NULL, HFILL }},
6987 { &hf_vsncp_error_code, { "Error Code", "vsncp.error_code", FT_UINT8, BASE_HEX, VALS(vsncp_errorcode_vals), 0x0, NULL, HFILL }},
6988 { &hf_vsncp_pdn_ipv4, { "PDN IPv4", "vsncp.pdn_ipv4", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6989 { &hf_vsncp_pdn_ipv6, { "PDN IPv6", "vsncp.pdn_ipv6", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6990 { &hf_vsncp_default_router_address, { "IPv4 Default Router Address", "vsncp.default_router_address", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6991 { &hf_vsncp_access_point_name, { "Access Point Name Label", "vsncp.access_point_name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6992 { &hf_vsncp_address_allocation_cause, { "Address Allocation Cause", "vsncp.address_allocation_cause", FT_UINT8, BASE_HEX, VALS(vsncp_alloc_vals), 0x0, NULL, HFILL }},
6993 { &hf_vsncp_ambr_data, { "AMBR Data", "vsncp.ambr_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6994 { &hf_vsncp_ipv6_interface_identifier, { "IPv6 interface identifier", "vsncp.ipv6_interface_identifier", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6995 { &hf_vsncp_protocol, { "Protocol", "vsncp.protocol", FT_UINT16, BASE_HEX, VALS(vsncp_pco_vals), 0x0, NULL, HFILL }},
6996 { &hf_vsncp_protocol_configuration_length, { "Length", "vsncp.protocol_configuration_length", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
6997 { &hf_vsncp_protocol_configuration_data, { "Data", "vsncp.protocol_configuration_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
6998 { &hf_vsncp_code, { "Code", "vsncp.code", FT_UINT8, BASE_HEX, VALS(cp_vals), 0x0, NULL, HFILL }},
6999 { &hf_vsncp_identifier, { "Identifier", "vsncp.identifier", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
7000 { &hf_vsncp_length, { "Length", "vsncp.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7001 };
7002
7003 static gint *ett[] = {
7004 &ett_vsncp,
7005 &ett_vsncp_options,
7006 &ett_vsncp_pdnid_opt,
7007 &ett_vsncp_apname_opt,
7008 &ett_vsncp_pdntype_opt,
7009 &ett_vsncp_pdnaddress_opt,
7010 &ett_vsncp_pco_opt,
7011 &ett_vsncp_errorcode_opt,
7012 &ett_vsncp_attachtype_opt,
7013 &ett_vsncp_ipv4address_opt,
7014 &ett_vsncp_addressalloc_opt,
7015 &ett_vsncp_apn_ambr_opt,
7016 &ett_vsncp_ipv6_hsgw_lla_iid_opt,
7017 };
7018
7019 proto_vsncp = proto_register_protocol("Vendor Specific Control Protocol", "VSNCP", "vsncp");
7020 proto_register_subtree_array(ett, array_length(ett));
7021 proto_register_field_array(proto_vsncp, hf, array_length(hf));
7022
7023 vsncp_option_table = register_dissector_table("vsncp.option", "PPP VSNCP Options", proto_vsncp, FT_UINT8, BASE_DEC);
7024
7025 /* Register VSNCP options as their own protocols so we can get the name of the option */
7026 proto_vsncp_option_pdnid = proto_register_protocol_in_name_only("PDN Identifier", "PDN Identifier", "vsncp.opt.pdnid", proto_vsncp, FT_BYTES);
7027 proto_vsncp_option_apname = proto_register_protocol_in_name_only("Access Point Name", "Access Point Name", "vsncp.opt.apname", proto_vsncp, FT_BYTES);
7028 proto_vsncp_option_pdntype = proto_register_protocol_in_name_only("PDN Type", "PDN Type", "vsncp.opt.pdntype", proto_vsncp, FT_BYTES);
7029 proto_vsncp_option_pdnaddress = proto_register_protocol_in_name_only("PDN Address", "PDN Address", "vsncp.opt.pdnaddress", proto_vsncp, FT_BYTES);
7030 proto_vsncp_option_pco = proto_register_protocol_in_name_only("Protocol Configuration Options", "Protocol Configuration Options", "vsncp.opt.pco", proto_vsncp, FT_BYTES);
7031 proto_vsncp_option_errorcode = proto_register_protocol_in_name_only("Error Code", "Error Code", "vsncp.opt.errorcode", proto_vsncp, FT_BYTES);
7032 proto_vsncp_option_attachtype = proto_register_protocol_in_name_only("Attach Type", "Attach Type", "vsncp.opt.attachtype", proto_vsncp, FT_BYTES);
7033 proto_vsncp_option_ipv4address = proto_register_protocol_in_name_only("IPv4 Default Router Address", "IPv4 Default Router Address", "vsncp.opt.ipv4address", proto_vsncp, FT_BYTES);
7034 proto_vsncp_option_addressalloc = proto_register_protocol_in_name_only("Address Allocation Cause", "Address Allocation Cause", "vsncp.opt.addressalloc", proto_vsncp, FT_BYTES);
7035 proto_vsncp_option_apn_ambr = proto_register_protocol_in_name_only("APN Aggregate Maximum Bit Rate(APN-AMBR)", "APN Aggregate Maximum Bit Rate(APN-AMBR)", "vsncp.opt.apn_ambr", proto_vsncp, FT_BYTES);
7036 proto_vsncp_option_ipv6_hsgw_lla_iid = proto_register_protocol_in_name_only("IPv6 HSGW Link Local Address IID", "IPv6 HSGW Link Local Address IID", "vsncp.opt.ipv6_hsgw_lla_iid", proto_vsncp, FT_BYTES);
7037 }
7038
7039 void
proto_reg_handoff_vsncp(void)7040 proto_reg_handoff_vsncp(void)
7041 {
7042 dissector_handle_t vsncp_handle;
7043
7044 vsncp_handle = create_dissector_handle(dissect_vsncp, proto_vsncp);
7045 dissector_add_uint("ppp.protocol", PPP_VSNCP, vsncp_handle);
7046
7047 dissector_add_uint("vsncp.option", CI_PDN_IDENTIFIER, create_dissector_handle( dissect_vsncp_pdnid_opt, proto_vsncp_option_pdnid ));
7048 dissector_add_uint("vsncp.option", CI_ACCESS_POINT_NM, create_dissector_handle( dissect_vsncp_apname_opt, proto_vsncp_option_apname ));
7049 dissector_add_uint("vsncp.option", CI_PDN_TYPE, create_dissector_handle( dissect_vsncp_pdntype_opt, proto_vsncp_option_pdntype ));
7050 dissector_add_uint("vsncp.option", CI_PDN_ADDRESS, create_dissector_handle( dissect_vsncp_pdnaddress_opt, proto_vsncp_option_pdnaddress ));
7051 dissector_add_uint("vsncp.option", CI_PROTOCOL_CONFIG, create_dissector_handle( dissect_vsncp_pco_opt, proto_vsncp_option_pco ));
7052 dissector_add_uint("vsncp.option", CI_ERROR_CODE, create_dissector_handle( dissect_vsncp_errorcode_opt, proto_vsncp_option_errorcode ));
7053 dissector_add_uint("vsncp.option", CI_ATTACH_TYPE, create_dissector_handle( dissect_vsncp_attachtype_opt, proto_vsncp_option_attachtype ));
7054 dissector_add_uint("vsncp.option", CI_IPv4DEFAULT_ROUTER, create_dissector_handle( dissect_vsncp_ipv4address_opt, proto_vsncp_option_ipv4address ));
7055 dissector_add_uint("vsncp.option", CI_ADDRESS_ALLOC, create_dissector_handle( dissect_vsncp_addressalloc_opt, proto_vsncp_option_addressalloc ));
7056 dissector_add_uint("vsncp.option", CI_APN_AMBR, create_dissector_handle( dissect_vsncp_apn_ambr_opt, proto_vsncp_option_apn_ambr ));
7057 dissector_add_uint("vsncp.option", CI_IPv6_HSGW_LLA_IID, create_dissector_handle( dissect_vsncp_ipv6_hsgw_lla_iid_opt, proto_vsncp_option_ipv6_hsgw_lla_iid ));
7058 }
7059
7060 void
proto_register_vsnp(void)7061 proto_register_vsnp(void)
7062 {
7063 static gint *ett[] = {
7064 &ett_vsnp
7065 };
7066
7067 static hf_register_info hf[] = {
7068 { &hf_vsnp_pdnid,
7069 { "PDN ID", "vsnp.pdnid", FT_UINT8, BASE_HEX,
7070 NULL, 0x0, NULL, HFILL }}
7071 };
7072
7073 proto_vsnp = proto_register_protocol("Vendor Specific Network Protocol",
7074 "PPP VSNP", "vsnp");
7075 proto_register_subtree_array(ett, array_length(ett));
7076 proto_register_field_array(proto_vsnp, hf, array_length(hf));
7077 }
7078
7079 void
proto_reg_handoff_vsnp(void)7080 proto_reg_handoff_vsnp(void)
7081 {
7082 dissector_handle_t vsnp_handle;
7083
7084 vsnp_handle = create_dissector_handle(dissect_vsnp, proto_vsnp);
7085 dissector_add_uint("ppp.protocol", PPP_VSNP, vsnp_handle);
7086 }
7087
7088 void
proto_register_ipcp(void)7089 proto_register_ipcp(void)
7090 {
7091 static hf_register_info hf[] = {
7092 { &hf_ipcp_opt_type,
7093 { "Type", "ipcp.opt.type", FT_UINT8, BASE_DEC,
7094 NULL, 0x0, NULL, HFILL }},
7095 { &hf_ipcp_opt_length,
7096 { "Length", "ipcp.opt.length", FT_UINT8, BASE_DEC,
7097 NULL, 0x0, NULL, HFILL }},
7098 { &hf_ipcp_opt_src_address,
7099 { "Source IP Address", "ipcp.opt.src_address", FT_IPv4, BASE_NONE,
7100 NULL, 0x0, NULL, HFILL }},
7101 { &hf_ipcp_opt_dst_address,
7102 { "Destination IP Address", "ipcp.opt.dst_address", FT_IPv4,
7103 BASE_NONE, NULL, 0x0, NULL, HFILL }},
7104 { &hf_ipcp_opt_compress_proto,
7105 { "IP Compression Protocol", "ipcp.opt.compress_proto", FT_UINT16,
7106 BASE_HEX, VALS(ipcp_compress_proto_vals), 0x0, NULL, HFILL }},
7107 { &hf_ipcp_opt_max_cid,
7108 { "Max CID", "ipcp.opt.max_cid", FT_UINT16, BASE_DEC,
7109 NULL, 0x0, "Maximum value of a context identifier", HFILL }},
7110 { &hf_ipcp_opt_mrru,
7111 { "MRRU", "ipcp.opt.mrru", FT_UINT16, BASE_DEC,
7112 NULL, 0x0, "Maximum Reconstructed Reception Unit", HFILL }},
7113 { &hf_ipcp_opt_max_slot_id,
7114 { "Max Slot ID", "ipcp.opt.max_slot_id", FT_UINT8, BASE_DEC,
7115 NULL, 0x0, NULL, HFILL }},
7116 { &hf_ipcp_opt_comp_slot_id,
7117 { "Comp Slot ID", "ipcp.opt.comp_slot_id", FT_BOOLEAN, 8,
7118 TFS(&tfs_comp_slot_id), 0x01, NULL, HFILL }},
7119 { &hf_ipcp_opt_tcp_space,
7120 { "TCP Space", "ipcp.opt.tcp_space", FT_UINT16, BASE_DEC,
7121 NULL, 0x0, NULL, HFILL }},
7122 { &hf_ipcp_opt_non_tcp_space,
7123 { "Non TCP Space", "ipcp.opt.non_tcp_space", FT_UINT16, BASE_DEC,
7124 NULL, 0x0, NULL, HFILL }},
7125 { &hf_ipcp_opt_f_max_period,
7126 { "F Max Period", "ipcp.opt.f_max_period", FT_UINT16, BASE_DEC,
7127 NULL, 0x0, "Maximum interval between full headers", HFILL }},
7128 { &hf_ipcp_opt_f_max_time,
7129 { "F Max Time", "ipcp.opt.f_max_time", FT_UINT16, BASE_DEC, NULL,
7130 0x0, "Maximum time interval between full headers", HFILL }},
7131 { &hf_ipcp_opt_max_header,
7132 { "Max Header", "ipcp.opt.max_header", FT_UINT16, BASE_DEC, NULL,
7133 0x0,
7134 "The largest header size in octets that may be compressed",
7135 HFILL }},
7136 { &hf_ipcp_data,
7137 { "Data", "ipcp.data", FT_BYTES, BASE_NONE,
7138 NULL, 0x0, NULL, HFILL }},
7139 { &hf_ipcp_opt_ip_address,
7140 { "IP Address", "ipcp.opt.ip_address", FT_IPv4, BASE_NONE,
7141 NULL, 0x0, NULL, HFILL }},
7142 { &hf_ipcp_opt_mobilenodehomeaddr,
7143 { "Mobile Node's Home Address", "ipcp.opt.mobilenodehomeaddress",
7144 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7145 { &hf_ipcp_opt_pri_dns_address,
7146 { "Primary DNS Address", "ipcp.opt.pri_dns_address",
7147 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7148 { &hf_ipcp_opt_pri_nbns_address,
7149 { "Primary NBNS Address", "ipcp.opt.pri_nbns_address",
7150 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7151 { &hf_ipcp_opt_sec_dns_address,
7152 { "Secondary DNS Address", "ipcp.opt.sec_dns_address",
7153 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7154 { &hf_ipcp_opt_sec_nbns_address,
7155 { "Secondary NBNS Address", "ipcp.opt.sec_nbns_address",
7156 FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7157 { &hf_ipcp_opt_rohc_type,
7158 { "Type", "ipcp.opt.rohc.type", FT_UINT8, BASE_DEC,
7159 NULL, 0x0, NULL, HFILL }},
7160 { &hf_ipcp_opt_rohc_length,
7161 { "Length", "ipcp.opt.rohc.length", FT_UINT8, BASE_DEC,
7162 NULL, 0x0, NULL, HFILL }},
7163 { &hf_ipcp_opt_rohc_profile,
7164 { "Profile", "ipcp.opt.rohc.profile", FT_UINT16, BASE_HEX,
7165 VALS(ipcp_rohc_profile_vals), 0x0, NULL, HFILL }},
7166 { &hf_ipcp_opt_iphc_type,
7167 { "Type", "ipcp.opt.iphc.type", FT_UINT8, BASE_DEC,
7168 NULL, 0x0, NULL, HFILL }},
7169 { &hf_ipcp_opt_iphc_length,
7170 { "Length", "ipcp.opt.iphc.length", FT_UINT8, BASE_DEC,
7171 NULL, 0x0, NULL, HFILL }},
7172 { &hf_ipcp_opt_iphc_param,
7173 { "Parameter", "ipcp.opt.iphc.param", FT_UINT8, BASE_DEC,
7174 VALS(ipcp_iphc_parameter_vals), 0x0, NULL, HFILL }}
7175 };
7176
7177 static gint *ett[] = {
7178 &ett_ipcp,
7179 &ett_ipcp_options,
7180 &ett_ipcp_ipaddrs_opt,
7181 &ett_ipcp_compress_opt,
7182 &ett_ipcp_ipaddr_opt,
7183 &ett_ipcp_mobileipv4_opt,
7184 &ett_ipcp_pridns_opt,
7185 &ett_ipcp_secdns_opt,
7186 &ett_ipcp_prinbns_opt,
7187 &ett_ipcp_secnbns_opt,
7188 &ett_ipcp_iphc_rtp_compress_opt,
7189 &ett_ipcp_iphc_enhanced_rtp_compress_opt,
7190 &ett_ipcp_iphc_neghdrcomp_opt,
7191 &ett_ipcp_rohc_profiles_opt
7192 };
7193
7194 proto_ipcp = proto_register_protocol("PPP IP Control Protocol", "PPP IPCP", "ipcp");
7195 proto_register_field_array(proto_ipcp, hf, array_length(hf));
7196 proto_register_subtree_array(ett, array_length(ett));
7197
7198 ipcp_option_table = register_dissector_table("ipcp.option", "PPP IPCP Options", proto_ipcp, FT_UINT8, BASE_DEC);
7199 ipcp_rohc_suboption_table = register_dissector_table("ipcp.rohc.option", "PPP IPCP ROHC Options", proto_ipcp, FT_UINT8, BASE_DEC);
7200 ipcp_iphc_suboption_table = register_dissector_table("ipcp.iphc.option", "PPP IPCP IPHC Options", proto_ipcp, FT_UINT8, BASE_DEC);
7201
7202 /* Register IPCP options as their own protocols so we can get the name of the option */
7203 proto_ipcp_option_addrs = proto_register_protocol_in_name_only("IP Addresses (deprecated)", "IP Addresses (deprecated)", "ipcp.opt.addrs", proto_ipcp, FT_BYTES);
7204 proto_ipcp_option_compress = proto_register_protocol_in_name_only("IP Compression Protocol", "IP Compression Protocol", "ipcp.opt.compress", proto_ipcp, FT_BYTES);
7205 proto_ipcp_option_addr = proto_register_protocol_in_name_only("IP Address", "IP Address", "ipcp.opt.addr", proto_ipcp, FT_BYTES);
7206 proto_ipcp_option_mobileipv4 = proto_register_protocol_in_name_only("Mobile Node's Home IP Address", "Mobile Node's Home IP Address", "ipcp.opt.mobileipv4", proto_ipcp, FT_BYTES);
7207 proto_ipcp_option_pri_dns = proto_register_protocol_in_name_only("Primary DNS Server IP Address", "Primary DNS Server IP Address", "ipcp.opt.pri_dns", proto_ipcp, FT_BYTES);
7208 proto_ipcp_option_pri_nbns = proto_register_protocol_in_name_only("Primary NBNS Server IP Address", "Primary NBNS Server IP Address", "ipcp.opt.pri_nbns", proto_ipcp, FT_BYTES);
7209 proto_ipcp_option_sec_dns = proto_register_protocol_in_name_only("Secondary DNS Server IP Address", "Secondary DNS Server IP Address", "ipcp.opt.sec_dns", proto_ipcp, FT_BYTES);
7210 proto_ipcp_option_sec_nbns = proto_register_protocol_in_name_only("Secondary NBNS Server IP Address", "Secondary NBNS Server IP Address", "ipcp.opt.sec_nbns", proto_ipcp, FT_BYTES);
7211
7212 proto_ipcp_rohc_option_profiles = proto_register_protocol_in_name_only("Profiles (RFC3241)", "Profiles (RFC3241)", "ipcp.opt.rohc.profile_bytes", proto_ipcp, FT_BYTES);
7213
7214 proto_ipcp_iphc_option_rtp_compress = proto_register_protocol_in_name_only("RTP compression (RFC2508)", "RTP compression (RFC2508)", "ipcp.opt.iphc.rtp_compress", proto_ipcp, FT_BYTES);
7215 proto_ipcp_iphc_option_enhanced_rtp_compress = proto_register_protocol_in_name_only("Enhanced RTP compression (RFC3545)", "Enhanced RTP compression (RFC3545)", "ipcp.opt.iphc.enhanced_rtp_compress", proto_ipcp, FT_BYTES);
7216 proto_ipcp_iphc_option_neghdrcomp = proto_register_protocol_in_name_only("Negotiating header compression (RFC3545)", "Negotiating header compression (RFC3545)", "ipcp.opt.iphc.neghdrcomp", proto_ipcp, FT_BYTES);
7217 }
7218
7219 void
proto_reg_handoff_ipcp(void)7220 proto_reg_handoff_ipcp(void)
7221 {
7222 dissector_handle_t ipcp_handle;
7223
7224 ipcp_handle = create_dissector_handle(dissect_ipcp, proto_ipcp);
7225 dissector_add_uint("ppp.protocol", PPP_IPCP, ipcp_handle);
7226
7227 /*
7228 * See above comment about NDISWAN for an explanation of why we're
7229 * registering with the "ethertype" dissector table.
7230 */
7231 dissector_add_uint("ethertype", PPP_IPCP, ipcp_handle);
7232
7233 /*
7234 * for GSM-A / MobileL3 / GPRS SM / PCO
7235 */
7236 dissector_add_uint("sm_pco.protocol", PPP_IPCP, ipcp_handle);
7237
7238 dissector_add_uint("ipcp.option", CI_ADDRS, create_dissector_handle( dissect_ipcp_addrs_opt, proto_ipcp_option_addrs ));
7239 dissector_add_uint("ipcp.option", CI_COMPRESS_PROTO, create_dissector_handle( dissect_ipcp_compress_opt, proto_ipcp_option_compress ));
7240 dissector_add_uint("ipcp.option", CI_ADDR, create_dissector_handle( dissect_ipcp_addr_opt, proto_ipcp_option_addr ));
7241 dissector_add_uint("ipcp.option", CI_MOBILE_IPv4, create_dissector_handle( dissect_ipcp_mobileipv4_opt, proto_ipcp_option_mobileipv4 ));
7242 dissector_add_uint("ipcp.option", CI_PRI_DNS, create_dissector_handle( dissect_ipcp_pri_dns_opt, proto_ipcp_option_pri_dns ));
7243 dissector_add_uint("ipcp.option", CI_PRI_NBNS, create_dissector_handle( dissect_ipcp_pri_nbns_opt, proto_ipcp_option_pri_nbns ));
7244 dissector_add_uint("ipcp.option", CI_SEC_DNS, create_dissector_handle( dissect_ipcp_sec_dns_opt, proto_ipcp_option_sec_dns ));
7245 dissector_add_uint("ipcp.option", CI_SEC_NBNS, create_dissector_handle( dissect_ipcp_sec_nbns_opt, proto_ipcp_option_sec_nbns ));
7246
7247 dissector_add_uint("ipcp.rohc.option", IPCP_ROHC_PROFILES, create_dissector_handle( dissect_ipcp_rohc_profiles_opt, proto_ipcp_rohc_option_profiles ));
7248
7249 dissector_add_uint("ipcp.iphc.option", IPCP_IPHC_CRTP, create_dissector_handle( dissect_ipcp_iphc_rtp_compress, proto_ipcp_iphc_option_rtp_compress ));
7250 dissector_add_uint("ipcp.iphc.option", IPCP_IPHC_ECRTP, create_dissector_handle( dissect_ipcp_iphc_enhanced_rtp_compress, proto_ipcp_iphc_option_enhanced_rtp_compress ));
7251 dissector_add_uint("ipcp.iphc.option", IPCP_IPHC_NEGHC, create_dissector_handle( dissect_ipcp_iphc_neghdrcomp_opt, proto_ipcp_iphc_option_neghdrcomp ));
7252 }
7253
7254 void
proto_register_bcp_bpdu(void)7255 proto_register_bcp_bpdu(void)
7256 {
7257 static hf_register_info hf[] = {
7258 { &hf_bcp_bpdu_flags,
7259 { "Flags", "bcp_bpdu.flags", FT_UINT8, BASE_HEX,
7260 NULL, 0x0, NULL, HFILL }},
7261 { &hf_bcp_bpdu_fcs_present,
7262 { "LAN FCS present", "bcp_bpdu.flags.fcs_present", FT_BOOLEAN, 8,
7263 TFS(&tfs_yes_no), BCP_FCS_PRESENT, NULL, HFILL }},
7264 { &hf_bcp_bpdu_zeropad,
7265 { "802.3 pad zero-filled", "bcp_bpdu.flags.zeropad", FT_BOOLEAN, 8,
7266 TFS(&tfs_yes_no), BCP_ZEROPAD, NULL, HFILL }},
7267 { &hf_bcp_bpdu_bcontrol,
7268 { "Bridge control", "bcp_bpdu.flags.bcontrol", FT_BOOLEAN, 8,
7269 TFS(&tfs_yes_no), BCP_IS_BCONTROL, NULL, HFILL }},
7270 { &hf_bcp_bpdu_pads,
7271 { "Pads", "bcp_bpdu.pads", FT_UINT8, BASE_DEC,
7272 NULL, BCP_PADS_MASK, NULL, HFILL }},
7273 { &hf_bcp_bpdu_mac_type,
7274 { "MAC Type", "bcp_bpdu.mac_type", FT_UINT8, BASE_DEC,
7275 VALS(bcp_bpdu_mac_type_vals), 0x0, NULL, HFILL }},
7276 { &hf_bcp_bpdu_pad,
7277 { "Pad", "bcp_bpdu.pad", FT_BYTES, BASE_NONE,
7278 NULL, 0x0, NULL, HFILL }},
7279 };
7280
7281 static gint *ett[] = {
7282 &ett_bcp_bpdu,
7283 &ett_bcp_bpdu_flags,
7284 };
7285
7286 proto_bcp_bpdu = proto_register_protocol("PPP Bridging Control Protocol Bridged PDU",
7287 "PPP BCP BPDU", "bcp_bpdu");
7288 proto_register_field_array(proto_bcp_bpdu, hf, array_length(hf));
7289 proto_register_subtree_array(ett, array_length(ett));
7290 }
7291
7292 void
proto_reg_handoff_bcp_bpdu(void)7293 proto_reg_handoff_bcp_bpdu(void)
7294 {
7295 dissector_handle_t bcp_bpdu_handle;
7296
7297 eth_withfcs_handle = find_dissector_add_dependency("eth_withfcs", proto_bcp_bpdu);
7298 eth_withoutfcs_handle = find_dissector_add_dependency("eth_withoutfcs", proto_bcp_bpdu);
7299
7300 bcp_bpdu_handle = create_dissector_handle(dissect_bcp_bpdu, proto_bcp_bpdu);
7301
7302 dissector_add_uint("ppp.protocol", PPP_BCP_BPDU, bcp_bpdu_handle);
7303 }
7304
7305 void
proto_register_bcp_ncp(void)7306 proto_register_bcp_ncp(void)
7307 {
7308 static hf_register_info hf[] = {
7309 { &hf_bcp_ncp_opt_type,
7310 { "Type", "bcp_ncp.lcp.opt.type", FT_UINT8, BASE_DEC,
7311 NULL, 0x0, NULL, HFILL } },
7312 { &hf_bcp_ncp_opt_length,
7313 { "Length", "bcp_ncp.lcp.opt.length", FT_UINT8, BASE_DEC,
7314 NULL, 0x0, NULL, HFILL } },
7315 { &hf_bcp_ncp_lan_seg_no,
7316 { "LAN Segment Number", "bcp_ncp.lcp.lan_seg_no", FT_UINT16, BASE_DEC,
7317 NULL, 0xfff0, NULL, HFILL } },
7318 { &hf_bcp_ncp_bridge_no,
7319 { "Bridge Number", "bcp_ncp.lcp.bridge_no", FT_UINT16, BASE_DEC,
7320 NULL, 0x000f, NULL, HFILL } },
7321 { &hf_bcp_ncp_tinygram_comp,
7322 { "Tinygram-Compression", "bcp_ncp.lcp.tinygram_comp", FT_BOOLEAN, 8,
7323 TFS(&tfs_enabled_disabled), 0x0, NULL, HFILL } },
7324 { &hf_bcp_ncp_mac,
7325 { "MAC Address", "bcp_ncp.lcp.mac_addres", FT_ETHER, BASE_NONE,
7326 NULL, 0x0, NULL, HFILL } },
7327 { &hf_bcp_ncp_mac_l,
7328 { "L bit", "bcp_ncp.lcp.mac_l", FT_UINT48, BASE_HEX,
7329 NULL, G_GUINT64_CONSTANT(0x0200000000), NULL, HFILL } },
7330 { &hf_bcp_ncp_mac_m,
7331 { "M bit", "bcp_ncp.lcp.mac_addre", FT_UINT48, BASE_HEX,
7332 NULL, G_GUINT64_CONSTANT(0x0100000000), NULL, HFILL } },
7333 { &hf_bcp_ncp_stp_prot,
7334 { "Protocol", "bcp_ncp.lcp.stp_protocol", FT_UINT8, BASE_DEC,
7335 VALS(bcp_ncp_stp_prot_vals), 0x0, NULL, HFILL } },
7336 { &hf_bcp_ncp_ieee_802_tagged_frame,
7337 { "IEEE-802-Tagged-Frame", "bcp_ncp.ieee_802_tagged_frame", FT_BOOLEAN, 8,
7338 TFS(&tfs_enabled_disabled), 0x0, NULL, HFILL } },
7339
7340 };
7341
7342 static gint *ett[] = {
7343 &ett_bcp_ncp,
7344 &ett_bcp_ncp_options,
7345 &ett_bcp_ncp_ieee_802_tagged_frame_opt,
7346 &ett_bcp_ncp_management_inline_opt,
7347 &ett_bcp_ncp_bcp_ind_opt,
7348 &ett_bcp_ncp_bridge_id_opt,
7349 &ett_bcp_ncp_line_id_opt,
7350 &ett_bcp_ncp_mac_sup_opt,
7351 &ett_bcp_ncp_tinygram_comp_opt,
7352 &ett_bcp_ncp_lan_id_opt,
7353 &ett_bcp_ncp_mac_addr_opt,
7354 &ett_bcp_ncp_stp_opt
7355 };
7356
7357 proto_bcp_ncp = proto_register_protocol("PPP Bridging Control Protocol Network Control Protocol", "PPP BCP NCP", "bcp_ncp");
7358 proto_register_field_array(proto_bcp_ncp, hf, array_length(hf));
7359 proto_register_subtree_array(ett, array_length(ett));
7360
7361 bcp_ncp_option_table = register_dissector_table("bcp_ncp.option", "PPP BCP NCP Options", proto_bcp_ncp, FT_UINT8, BASE_DEC);
7362
7363 /* Register BCP NCP options as their own protocols so we can get the name of the option */
7364 proto_bcp_ncp_option_bridge_id = proto_register_protocol_in_name_only("Bridge-Identification", "Bridge-Identification", "bcp_ncp.opt.bridge_id", proto_bcp_ncp, FT_BYTES);
7365 proto_bcp_ncp_option_line_id = proto_register_protocol_in_name_only("Line-Identification", "Line-Identification", "bcp_ncp.opt.line_id", proto_bcp_ncp, FT_BYTES);
7366 proto_bcp_ncp_option_mac_sup = proto_register_protocol_in_name_only("MAC-Support", "MAC-Support", "bcp_ncp.opt.mac_sup", proto_bcp_ncp, FT_BYTES);
7367 proto_bcp_ncp_option_tinygram_comp = proto_register_protocol_in_name_only("Tinygram-Compression", "Tinygram-Compression", "bcp_ncp.opt.tinygram_comp", proto_bcp_ncp, FT_BYTES);
7368 proto_bcp_ncp_option_lan_id = proto_register_protocol_in_name_only("LAN-Identification (obsoleted)", "LAN-Identification (obsoleted)", "bcp_ncp.opt.lan_id", proto_bcp_ncp, FT_BYTES);
7369 proto_bcp_ncp_option_mac_addr = proto_register_protocol_in_name_only("MAC-Address", "MAC-Address", "bcp_ncp.opt.mac_addr", proto_bcp_ncp, FT_BYTES);
7370 proto_bcp_ncp_option_stp = proto_register_protocol_in_name_only("Spanning-Tree-Protocol (old formatted)", "Spanning-Tree-Protocol (old formatted)", "bcp_ncp.opt.stp", proto_bcp_ncp, FT_BYTES);
7371 proto_bcp_ncp_option_ieee_802_tagged_frame = proto_register_protocol_in_name_only("IEEE 802 Tagged Frame", "IEEE 802 Tagged Frame", "bcp_ncp.opt.ieee_802_tagged_frame", proto_bcp_ncp, FT_BYTES);
7372 proto_bcp_ncp_option_management_inline = proto_register_protocol_in_name_only("Management Inline", "Management Inline", "bcp_ncp.opt.management_inline", proto_bcp_ncp, FT_BYTES);
7373 proto_bcp_ncp_option_bcp_ind = proto_register_protocol_in_name_only("Bridge Control Packet Indicator", "Bridge Control Packet Indicator", "bcp_ncp.opt.bcp_ind", proto_bcp_ncp, FT_BYTES);
7374 }
7375
7376 void
proto_reg_handoff_bcp_ncp(void)7377 proto_reg_handoff_bcp_ncp(void)
7378 {
7379 dissector_handle_t bcp_ncp_handle;
7380
7381 bcp_ncp_handle = create_dissector_handle(dissect_bcp_ncp, proto_bcp_ncp);
7382
7383 dissector_add_uint("ppp.protocol", PPP_BCP_NCP, bcp_ncp_handle);
7384
7385 dissector_add_uint("bcp_ncp.option", CI_BCPNCP_BRIDGE_ID, create_dissector_handle( dissect_bcp_ncp_bridge_id, proto_bcp_ncp_option_bridge_id ));
7386 dissector_add_uint("bcp_ncp.option", CI_BCPNCP_LINE_ID, create_dissector_handle( dissect_bcp_ncp_line_id, proto_bcp_ncp_option_line_id ));
7387 dissector_add_uint("bcp_ncp.option", CI_BCPNCP_MAC_SUPPORT, create_dissector_handle( dissect_bcp_ncp_mac_sup, proto_bcp_ncp_option_mac_sup ));
7388 dissector_add_uint("bcp_ncp.option", CI_BCPNCP_TINYGRAM_COMP, create_dissector_handle( dissect_bcp_ncp_tinygram_comp, proto_bcp_ncp_option_tinygram_comp ));
7389 dissector_add_uint("bcp_ncp.option", CI_BCPNCP_LAN_ID, create_dissector_handle( dissect_bcp_ncp_lan_id, proto_bcp_ncp_option_lan_id ));
7390 dissector_add_uint("bcp_ncp.option", CI_BCPNCP_MAC_ADDRESS, create_dissector_handle( dissect_bcp_ncp_mac_addr, proto_bcp_ncp_option_mac_addr ));
7391 dissector_add_uint("bcp_ncp.option", CI_BCPNCP_STP, create_dissector_handle( dissect_bcp_ncp_stp, proto_bcp_ncp_option_stp ));
7392 dissector_add_uint("bcp_ncp.option", CI_BCPNCP_IEEE_802_TAGGED_FRAME, create_dissector_handle( dissect_bcp_ncp_ieee_802_tagged_frame, proto_bcp_ncp_option_ieee_802_tagged_frame ));
7393 dissector_add_uint("bcp_ncp.option", CI_BCPNCP_MANAGEMENT_INLINE, create_dissector_handle( dissect_bcp_ncp_management_inline, proto_bcp_ncp_option_management_inline ));
7394 dissector_add_uint("bcp_ncp.option", CI_BCPNCP_BCP_IND, create_dissector_handle( dissect_bcp_ncp_bcp_ncp_bcp_ind, proto_bcp_ncp_option_bcp_ind ));
7395 }
7396
7397 void
proto_register_osinlcp(void)7398 proto_register_osinlcp(void)
7399 {
7400 static hf_register_info hf[] = {
7401 { &hf_osinlcp_opt_type,
7402 { "Type", "osinlcp.opt.type", FT_UINT8, BASE_DEC,
7403 NULL, 0x0, NULL, HFILL } },
7404 { &hf_osinlcp_opt_length,
7405 { "Length", "osinlcp.opt.length", FT_UINT8, BASE_DEC,
7406 NULL, 0x0, NULL, HFILL } },
7407 { &hf_osinlcp_opt_alignment,
7408 { "Alignment", "osinlcp.opt.alignment", FT_UINT8, BASE_DEC,
7409 NULL, 0x0, NULL, HFILL } }
7410 };
7411
7412 static gint *ett[] = {
7413 &ett_osinlcp,
7414 &ett_osinlcp_options,
7415 &ett_osinlcp_align_npdu_opt
7416 };
7417
7418 proto_osinlcp = proto_register_protocol("PPP OSI Network Layer Control Protocol", "PPP OSINLCP", "osinlcp");
7419 proto_register_field_array(proto_osinlcp, hf, array_length(hf));
7420 proto_register_subtree_array(ett, array_length(ett));
7421
7422 osinlcp_option_table = register_dissector_table("osinlcp.option", "PPP OSINLCP Options", proto_osinlcp, FT_UINT8, BASE_DEC);
7423
7424 /* Register OSINLCP options as their own protocols so we can get the name of the option */
7425 proto_osinlcp_option_align_npdu = proto_register_protocol_in_name_only("Align-NPDU", "Align-NPDU", "osinlcp.opt.def_pid", proto_osinlcp, FT_BYTES);
7426 }
7427
7428
7429 void
proto_reg_handoff_osinlcp(void)7430 proto_reg_handoff_osinlcp(void)
7431 {
7432 dissector_handle_t osinlcp_handle;
7433
7434 osinlcp_handle = create_dissector_handle(dissect_osinlcp, proto_osinlcp);
7435 dissector_add_uint("ppp.protocol", PPP_OSINLCP, osinlcp_handle);
7436
7437 /*
7438 * See above comment about NDISWAN for an explanation of why we're
7439 * registering with the "ethertype" dissector table.
7440 */
7441 dissector_add_uint("ethertype", PPP_OSINLCP, osinlcp_handle);
7442
7443 dissector_add_uint("osinlcp.option", CI_OSINLCP_ALIGN_NPDU, create_dissector_handle( dissect_osinlcp_align_npdu_opt, proto_osinlcp_option_align_npdu ));
7444 }
7445
7446 void
proto_register_ccp(void)7447 proto_register_ccp(void)
7448 {
7449 static hf_register_info hf[] = {
7450 { &hf_ccp_opt_type,
7451 { "Type", "ccp.opt.type", FT_UINT8, BASE_DEC,
7452 NULL, 0x0, NULL, HFILL }},
7453 { &hf_ccp_opt_length,
7454 { "Length", "ccp.opt.length", FT_UINT8, BASE_DEC,
7455 NULL, 0x0, NULL, HFILL }},
7456 { &hf_ccp_opt_oui,
7457 { "OUI", "ccp.opt.oui", FT_UINT24, BASE_OUI,
7458 NULL, 0x0, NULL, HFILL }},
7459 { &hf_ccp_opt_subtype,
7460 { "Subtype", "ccp.opt.subtype", FT_UINT8, BASE_DEC_HEX,
7461 NULL, 0x0, NULL, HFILL }},
7462 { &hf_ccp_opt_history_count,
7463 { "History Count", "ccp.opt.history_count", FT_UINT16, BASE_DEC,
7464 NULL, 0x0, "The maximum number of compression histories",
7465 HFILL }},
7466 { &hf_ccp_opt_cm,
7467 { "Check Mode Field", "ccp.opt.cm", FT_UINT8, BASE_DEC,
7468 NULL, 0x0, NULL, HFILL }},
7469 { &hf_ccp_opt_cm_reserved,
7470 { "Reserved", "ccp.opt.cm.reserved", FT_UINT8, BASE_DEC,
7471 NULL, 0xF8, NULL, HFILL }},
7472 { &hf_ccp_opt_cm_check_mode,
7473 { "Check Mode", "ccp.opt.cm.check_mode", FT_UINT8, BASE_DEC,
7474 VALS(stac_checkmode_vals), 0x07, NULL, HFILL }},
7475 { &hf_ccp_opt_supported_bits,
7476 { "Supported Bits", "ccp.opt.supported_bits", FT_UINT32, BASE_HEX,
7477 NULL, 0x0, NULL, HFILL }},
7478 { &hf_ccp_opt_supported_bits_h,
7479 { "H", "ccp.opt.supported_bits.h", FT_BOOLEAN, 32,
7480 TFS(&ccp_mppe_h_tfs), MPPE_SUPPORTED_BITS_H, NULL, HFILL }},
7481 { &hf_ccp_opt_supported_bits_m,
7482 { "M", "ccp.opt.supported_bits.m", FT_BOOLEAN, 32,
7483 TFS(&ccp_mppe_m_tfs), MPPE_SUPPORTED_BITS_M, NULL, HFILL }},
7484 { &hf_ccp_opt_supported_bits_s,
7485 { "S", "ccp.opt.supported_bits.s", FT_BOOLEAN, 32,
7486 TFS(&ccp_mppe_s_tfs), MPPE_SUPPORTED_BITS_S, NULL, HFILL }},
7487 { &hf_ccp_opt_supported_bits_l,
7488 { "L", "ccp.opt.supported_bits.l", FT_BOOLEAN, 32,
7489 TFS(&ccp_mppe_l_tfs), MPPE_SUPPORTED_BITS_L, NULL, HFILL }},
7490 { &hf_ccp_opt_supported_bits_d,
7491 { "D", "ccp.opt.supported_bits.d", FT_BOOLEAN, 32,
7492 TFS(&ccp_mppe_d_tfs), MPPE_SUPPORTED_BITS_D, NULL, HFILL }},
7493 { &hf_ccp_opt_supported_bits_c,
7494 { "C", "ccp.opt.supported_bits.c", FT_BOOLEAN, 32,
7495 TFS(&ccp_mppe_c_tfs), MPPC_SUPPORTED_BITS_C, NULL, HFILL }},
7496 { &hf_ccp_opt_history,
7497 { "History", "ccp.opt.history", FT_UINT8, BASE_DEC, NULL, 0x0,
7498 "Maximum size of the compression history in powers of 2",
7499 HFILL }},
7500 { &hf_ccp_opt_version,
7501 { "Version", "ccp.opt.version", FT_BYTES, BASE_NONE,
7502 NULL, 0x0, NULL, HFILL }},
7503 { &hf_ccp_opt_vd,
7504 { "Vers/Dict", "ccp.opt.vd", FT_UINT8, BASE_HEX,
7505 NULL, 0x0, NULL, HFILL }},
7506 { &hf_ccp_opt_vd_vers,
7507 { "Vers", "ccp.opt.vd.vers", FT_UINT8, BASE_DEC,
7508 NULL, 0xE0, NULL, HFILL }},
7509 { &hf_ccp_opt_vd_dict,
7510 { "Dict", "ccp.opt.vd.dict", FT_UINT8, BASE_DEC, NULL,
7511 0x1F, "The size in bits of the largest code used", HFILL }},
7512 { &hf_ccp_opt_check_mode,
7513 { "Check Mode", "ccp.opt.check_mode", FT_UINT8, BASE_DEC,
7514 VALS(lzsdcp_checkmode_vals), 0x0, NULL, HFILL }},
7515 { &hf_ccp_opt_process_mode,
7516 { "Process Mode", "ccp.opt.process_mode", FT_UINT8, BASE_DEC,
7517 VALS(lzsdcp_processmode_vals), 0x0, NULL, HFILL }},
7518 { &hf_ccp_opt_fe,
7519 { "Features", "ccp.opt.fe", FT_UINT8, BASE_DEC,
7520 NULL, 0xC0, NULL, HFILL }},
7521 { &hf_ccp_opt_p,
7522 { "Packet by Packet flag", "ccp.opt.p", FT_BOOLEAN, 8,
7523 TFS(&tfs_enabled_disabled), 0x20, NULL, HFILL }},
7524 { &hf_ccp_opt_History,
7525 { "History", "ccp.opt.History", FT_UINT8, BASE_DEC,
7526 NULL, 0x1F, NULL, HFILL }},
7527 { &hf_ccp_opt_contexts,
7528 { "# Contexts", "ccp.opt.contexts", FT_UINT8, BASE_DEC,
7529 NULL, 0x0, NULL, HFILL }},
7530 { &hf_ccp_opt_mode,
7531 { "Mode", "ccp.opt.mode", FT_UINT8, BASE_DEC,
7532 VALS(dce_mode_vals), 0x0, NULL, HFILL }},
7533 { &hf_ccp_opt_window,
7534 { "Window", "ccp.opt.window", FT_UINT8, BASE_DEC,
7535 NULL, 0xF0, NULL, HFILL }},
7536 { &hf_ccp_opt_method,
7537 { "Method", "ccp.opt.method", FT_UINT8, BASE_DEC,
7538 VALS(deflate_method_vals), 0x0F, NULL, HFILL }},
7539 { &hf_ccp_opt_mbz,
7540 { "MBZ", "ccp.opt.mbz", FT_UINT8, BASE_DEC,
7541 NULL, 0xFC, NULL, HFILL }},
7542 { &hf_ccp_opt_chk,
7543 { "Chk", "ccp.opt.chk", FT_UINT8, BASE_DEC,
7544 VALS(deflate_chk_vals), 0x03, NULL, HFILL }},
7545 { &hf_ccp_opt_mode_dictcount,
7546 { "Mode/Dictionary Count", "ccp.opt.mode_dictcount", FT_UINT16,
7547 BASE_DEC | BASE_RANGE_STRING, RVALS(v44lzjh_mode_dict_rvals),
7548 0x0, NULL, HFILL }},
7549 { &hf_ccp_opt_dict_size,
7550 { "Dictionary Size", "ccp.opt.dict_size", FT_UINT16, BASE_DEC,
7551 NULL, 0x0, NULL, HFILL }},
7552 { &hf_ccp_opt_history_length,
7553 { "History Length", "ccp.opt.history_length", FT_UINT16, BASE_DEC,
7554 NULL, 0x0, NULL, HFILL }},
7555 { &hf_ccp_opt_data,
7556 { "Data", "ccp.opt.data", FT_BYTES, BASE_NONE,
7557 NULL, 0x0, NULL, HFILL }},
7558 };
7559 static gint *ett[] = {
7560 &ett_ccp,
7561 &ett_ccp_options,
7562 &ett_ccp_oui_opt,
7563 &ett_ccp_predict1_opt,
7564 &ett_ccp_predict2_opt,
7565 &ett_ccp_puddle_opt,
7566 &ett_ccp_hpppc_opt,
7567 &ett_ccp_stac_opt,
7568 &ett_ccp_stac_opt_check_mode,
7569 &ett_ccp_mppe_opt,
7570 &ett_ccp_mppe_opt_supp_bits,
7571 &ett_ccp_gfza_opt,
7572 &ett_ccp_v42bis_opt,
7573 &ett_ccp_bsdcomp_opt,
7574 &ett_ccp_lzsdcp_opt,
7575 &ett_ccp_mvrca_opt,
7576 &ett_ccp_dce_opt,
7577 &ett_ccp_deflate_opt,
7578 &ett_ccp_v44lzjh_opt
7579 };
7580
7581 proto_ccp = proto_register_protocol("PPP Compression Control Protocol", "PPP CCP", "ccp");
7582 proto_register_field_array(proto_ccp, hf, array_length(hf));
7583 proto_register_subtree_array(ett, array_length(ett));
7584
7585 ccp_option_table = register_dissector_table("ccp.option", "PPP CCP Options", proto_ccp, FT_UINT8, BASE_DEC);
7586
7587 /* Register CCP options as their own protocols so we can get the name of the option */
7588 proto_ccp_option_oui = proto_register_protocol_in_name_only("OUI", "OUI", "ccp.opt_oui", proto_ccp, FT_BYTES);
7589 proto_ccp_option_predict1 = proto_register_protocol_in_name_only("Predictor type 1", "Predictor type 1", "ccp.opt.predict1", proto_ccp, FT_BYTES);
7590 proto_ccp_option_predict2 = proto_register_protocol_in_name_only("Predictor type 2", "Predictor type 2", "ccp.opt.predict2", proto_ccp, FT_BYTES);
7591 proto_ccp_option_puddle = proto_register_protocol_in_name_only("Puddle Jumper", "Puddle Jumper", "ccp.opt.puddle", proto_ccp, FT_BYTES);
7592 proto_ccp_option_hpppc = proto_register_protocol_in_name_only("Hewlett-Packard PPC", "Hewlett-Packard PPC", "ccp.opt.hpppc", proto_ccp, FT_BYTES);
7593 proto_ccp_option_stac = proto_register_protocol_in_name_only("Stac Electronics LZS", "Stac Electronics LZS", "ccp.opt.stac", proto_ccp, FT_BYTES);
7594 proto_ccp_option_stac_ascend = proto_register_protocol_in_name_only("Stac Electronics LZS (Ascend Proprietary version)", "Stac Electronics LZS (Ascend Proprietary version)", "ccp.opt.stac_ascend", proto_ccp, FT_BYTES);
7595 proto_ccp_option_mppe = proto_register_protocol_in_name_only("Microsoft PPE/PPC", "Microsoft PPE/PPC", "ccp.opt.mppe", proto_ccp, FT_BYTES);
7596 proto_ccp_option_gfza = proto_register_protocol_in_name_only("Gandalf FZA", "Gandalf FZA", "ccp.opt.gfza", proto_ccp, FT_BYTES);
7597 proto_ccp_option_v42bis = proto_register_protocol_in_name_only("V.42bis compression", "V.42bis compression", "ccp.opt.v42bis", proto_ccp, FT_BYTES);
7598 proto_ccp_option_bsdcomp = proto_register_protocol_in_name_only("BSD LZW Compress", "BSD LZW Compress", "ccp.opt.bsdcomp", proto_ccp, FT_BYTES);
7599 proto_ccp_option_lzsdcp = proto_register_protocol_in_name_only("LZS-DCP", "LZS-DCP", "ccp.opt.lzsdcp", proto_ccp, FT_BYTES);
7600 proto_ccp_option_mvrca = proto_register_protocol_in_name_only("MVRCA (Magnalink)", "MVRCA (Magnalink)", "ccp.opt.mvrca", proto_ccp, FT_BYTES);
7601 proto_ccp_option_dce = proto_register_protocol_in_name_only("PPP for Data Compression in Data Circuit-Terminating Equipment (DCE)", "PPP for Data Compression in Data Circuit-Terminating Equipment (DCE)", "ccp.opt.dce", proto_ccp, FT_BYTES);
7602 proto_ccp_option_deflate = proto_register_protocol_in_name_only("Deflate", "Deflate", "ccp.opt.deflate", proto_ccp, FT_BYTES);
7603 proto_ccp_option_v44lzjh = proto_register_protocol_in_name_only("V.44/LZJH compression", "V.44/LZJH compression", "ccp.opt.v44lzjh", proto_ccp, FT_BYTES);
7604 }
7605
7606 void
proto_reg_handoff_ccp(void)7607 proto_reg_handoff_ccp(void)
7608 {
7609 dissector_handle_t ccp_handle;
7610
7611 ccp_handle = create_dissector_handle(dissect_ccp, proto_ccp);
7612 dissector_add_uint("ppp.protocol", PPP_CCP, ccp_handle);
7613
7614 /*
7615 * See above comment about NDISWAN for an explanation of why we're
7616 * registering with the "ethertype" dissector table.
7617 */
7618 dissector_add_uint("ethertype", PPP_CCP, ccp_handle);
7619
7620 dissector_add_uint("ccp.option", CI_CCP_OUI, create_dissector_handle( dissect_ccp_oui_opt, proto_ccp_option_oui ));
7621 dissector_add_uint("ccp.option", CI_CCP_PREDICT1, create_dissector_handle( dissect_ccp_predict1_opt, proto_ccp_option_predict1 ));
7622 dissector_add_uint("ccp.option", CI_CCP_PREDICT2, create_dissector_handle( dissect_ccp_predict2_opt, proto_ccp_option_predict2 ));
7623 dissector_add_uint("ccp.option", CI_CCP_PUDDLE, create_dissector_handle( dissect_ccp_puddle_opt, proto_ccp_option_puddle ));
7624 dissector_add_uint("ccp.option", CI_CCP_HPPPC, create_dissector_handle( dissect_ccp_hpppc_opt, proto_ccp_option_hpppc ));
7625 dissector_add_uint("ccp.option", CI_CCP_STAC, create_dissector_handle( dissect_ccp_stac_opt, proto_ccp_option_stac ));
7626 dissector_add_uint("ccp.option", CI_CCP_MPPE, create_dissector_handle( dissect_ccp_mppe_opt, proto_ccp_option_mppe ));
7627 dissector_add_uint("ccp.option", CI_CCP_GFZA, create_dissector_handle( dissect_ccp_gfza_opt, proto_ccp_option_gfza ));
7628 dissector_add_uint("ccp.option", CI_CCP_V42BIS, create_dissector_handle( dissect_ccp_v42bis_opt, proto_ccp_option_v42bis ));
7629 dissector_add_uint("ccp.option", CI_CCP_BSDLZW, create_dissector_handle( dissect_ccp_bsdcomp_opt, proto_ccp_option_bsdcomp ));
7630 dissector_add_uint("ccp.option", CI_CCP_LZSDCP, create_dissector_handle( dissect_ccp_lzsdcp_opt, proto_ccp_option_lzsdcp ));
7631 dissector_add_uint("ccp.option", CI_CCP_MVRCA, create_dissector_handle( dissect_ccp_mvrca_opt, proto_ccp_option_mvrca ));
7632 dissector_add_uint("ccp.option", CI_CCP_DCE, create_dissector_handle( dissect_ccp_dce_opt, proto_ccp_option_dce ));
7633 dissector_add_uint("ccp.option", CI_CCP_DEFLATE, create_dissector_handle( dissect_ccp_deflate_opt, proto_ccp_option_deflate ));
7634 dissector_add_uint("ccp.option", CI_CCP_V44LZJH, create_dissector_handle( dissect_ccp_v44lzjh_opt, proto_ccp_option_v44lzjh ));
7635 }
7636
7637 void
proto_register_cbcp(void)7638 proto_register_cbcp(void)
7639 {
7640 static hf_register_info hf[] = {
7641 { &hf_cbcp_opt_type, { "Type", "cbcp.opt.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7642 { &hf_cbcp_opt_length, { "Length", "cbcp.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7643 /* Generated from convert_proto_tree_add_text.pl */
7644 { &hf_cbcp_callback_delay, { "Callback delay", "cbcp.callback_delay", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7645 { &hf_cbcp_address_type, { "Address Type", "cbcp.address_type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7646 { &hf_cbcp_address, { "Address", "cbcp.address", FT_STRINGZ, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7647 { &hf_cbcp_no_callback, { "No callback", "cbcp.no_callback", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7648 };
7649
7650 static gint *ett[] = {
7651 &ett_cbcp,
7652 &ett_cbcp_options,
7653 &ett_cbcp_callback_opt,
7654 &ett_cbcp_callback_opt_addr,
7655 &ett_cbcp_no_callback,
7656 &ett_cbcp_callback_user,
7657 &ett_cbcp_callback_admin,
7658 &ett_cbcp_callback_list,
7659 };
7660
7661 static ei_register_info ei[] = {
7662 { &ei_cbcp_address, { "cbcp.address.malformed", PI_MALFORMED, PI_ERROR, "Address runs past end of option", EXPFILL }},
7663 };
7664
7665 expert_module_t* expert_cbcp;
7666
7667 proto_cbcp = proto_register_protocol("PPP Callback Control Protocol", "PPP CBCP", "cbcp");
7668 proto_register_field_array(proto_cbcp, hf, array_length(hf));
7669 proto_register_subtree_array(ett, array_length(ett));
7670 expert_cbcp = expert_register_protocol(proto_cbcp);
7671 expert_register_field_array(expert_cbcp, ei, array_length(ei));
7672
7673 cbcp_option_table = register_dissector_table("cbcp.option", "PPP CBCP Options", proto_cbcp, FT_UINT8, BASE_DEC);
7674
7675 /* Register CBCP options as their own protocols so we can get the name of the option */
7676 proto_cbcp_option_no_callback = proto_register_protocol_in_name_only("No callback", "No callback", "cbcp.opt.no_callback", proto_cbcp, FT_BYTES);
7677 proto_cbcp_option_callback_user = proto_register_protocol_in_name_only("Callback to a user-specified number", "Callback to a user-specified number", "cbcp.opt.callback_user", proto_cbcp, FT_BYTES);
7678 proto_cbcp_option_callback_admin = proto_register_protocol_in_name_only("Callback to a pre-specified or admin-specified number", "Callback to a pre-specified or admin-specified number", "cbcp.opt.callback_admin", proto_cbcp, FT_BYTES);
7679 proto_cbcp_option_callback_list = proto_register_protocol_in_name_only("Callback to any of a list of numbers", "Callback to any of a list of numbers", "cbcp.opt.callback_list", proto_cbcp, FT_BYTES);
7680 }
7681
7682 void
proto_reg_handoff_cbcp(void)7683 proto_reg_handoff_cbcp(void)
7684 {
7685 dissector_handle_t cbcp_handle;
7686
7687 cbcp_handle = create_dissector_handle(dissect_cbcp, proto_cbcp);
7688 dissector_add_uint("ppp.protocol", PPP_CBCP, cbcp_handle);
7689
7690 /*
7691 * See above comment about NDISWAN for an explanation of why we're
7692 * registering with the "ethertype" dissector table.
7693 */
7694 dissector_add_uint("ethertype", PPP_CBCP, cbcp_handle);
7695
7696 dissector_add_uint("cbcp.option", CI_CBCP_NO_CALLBACK, create_dissector_handle( dissect_cbcp_no_callback_opt, proto_cbcp_option_no_callback ));
7697 dissector_add_uint("cbcp.option", CI_CBCP_CB_USER, create_dissector_handle( dissect_cbcp_callback_user_opt, proto_cbcp_option_callback_user ));
7698 dissector_add_uint("cbcp.option", CI_CBCP_CB_PRE, create_dissector_handle( dissect_cbcp_callback_admin_opt, proto_cbcp_option_callback_admin ));
7699 dissector_add_uint("cbcp.option", CI_CBCP_CB_ANY, create_dissector_handle( dissect_cbcp_callback_list_opt, proto_cbcp_option_callback_list ));
7700 }
7701
7702 void
proto_register_bacp(void)7703 proto_register_bacp(void)
7704 {
7705 static hf_register_info hf[] = {
7706 { &hf_bacp_opt_type, { "Type", "bacp.opt.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7707 { &hf_bacp_opt_length, { "Length", "bacp.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7708 /* Generated from convert_proto_tree_add_text.pl */
7709 { &hf_bacp_magic_number, { "Magic number", "bacp.magic_number", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
7710 { &hf_bacp_link_speed, { "Link Speed", "bacp.link_speed", FT_UINT16, BASE_DEC|BASE_UNIT_STRING, &units_kbps, 0x0, NULL, HFILL }},
7711 { &hf_bacp_link_type, { "Link Type", "bacp.link_type", FT_UINT8, BASE_DEC, VALS(bap_link_type_vals), 0x0, NULL, HFILL }},
7712 };
7713
7714 static gint *ett[] = {
7715 &ett_bacp,
7716 &ett_bacp_options,
7717 &ett_bacp_favored_peer_opt
7718 };
7719
7720 proto_bacp = proto_register_protocol("PPP Bandwidth Allocation Control Protocol", "PPP BACP", "bacp");
7721 proto_register_field_array(proto_bacp, hf, array_length(hf));
7722 proto_register_subtree_array(ett, array_length(ett));
7723
7724 bacp_option_table = register_dissector_table("bacp.option", "PPP BACP Options", proto_bacp, FT_UINT8, BASE_DEC);
7725
7726 /* Register BACP options as their own protocols so we can get the name of the option */
7727 proto_bacp_option_favored_peer = proto_register_protocol_in_name_only("Favored-Peer", "Favored-Peer", "bacp.opt.favored_peer", proto_bacp, FT_BYTES);
7728 }
7729
7730 void
proto_reg_handoff_bacp(void)7731 proto_reg_handoff_bacp(void)
7732 {
7733 dissector_handle_t bacp_handle;
7734
7735 bacp_handle = create_dissector_handle(dissect_bacp, proto_bacp);
7736 dissector_add_uint("ppp.protocol", PPP_BACP, bacp_handle);
7737
7738 /*
7739 * See above comment about NDISWAN for an explanation of why we're
7740 * registering with the "ethertype" dissector table.
7741 */
7742 dissector_add_uint("ethertype", PPP_BACP, bacp_handle);
7743
7744 dissector_add_uint("bacp.option", CI_BACP_FAVORED_PEER, create_dissector_handle( dissect_bacp_favored_peer_opt, proto_bacp_option_favored_peer ));
7745 }
7746
7747 void
proto_register_bap(void)7748 proto_register_bap(void)
7749 {
7750 static hf_register_info hf[] = {
7751 { &hf_bap_opt_type, { "Type", "bap.opt.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7752 { &hf_bap_opt_length, { "Length", "bap.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7753 /* Generated from convert_proto_tree_add_text.pl */
7754 { &hf_bap_sub_option_type, { "Sub-Option Type", "bap.sub_option_type", FT_UINT8, BASE_DEC, VALS(bap_phone_delta_subopt_vals), 0x0, NULL, HFILL }},
7755 { &hf_bap_sub_option_length, { "Sub-Option Length", "bap.sub_option_length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7756 { &hf_bap_unique_digit, { "Unique Digit", "bap.unique_digit", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7757 { &hf_bap_subscriber_number, { "Subscriber Number", "bap.subscriber_number", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7758 { &hf_bap_phone_number_sub_address, { "Phone Number Sub Address", "bap.phone_number_sub_address", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7759 { &hf_bap_unknown_option_data, { "Unknown", "bap.unknown_option_data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7760 { &hf_bap_reason, { "Reason", "bap.reason", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
7761 { &hf_bap_link_discriminator, { "Link Discriminator", "bap.link_discriminator", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
7762 { &hf_bap_call_status, { "Status", "bap.call_status", FT_UINT8, BASE_HEX|BASE_EXT_STRING, &q931_cause_code_vals_ext, 0x0, NULL, HFILL }},
7763 { &hf_bap_call_action, { "Action", "bap.call_action", FT_UINT8, BASE_HEX, VALS(bap_call_status_opt_action_vals), 0x0, NULL, HFILL }},
7764 { &hf_bap_type, { "Type", "bap.type", FT_UINT8, BASE_HEX, VALS(bap_vals), 0x0, NULL, HFILL }},
7765 { &hf_bap_identifier, { "Identifier", "bap.identifier", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
7766 { &hf_bap_length, { "Length", "bap.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
7767 { &hf_bap_response_code, { "Response Code", "bap.response_code", FT_UINT8, BASE_HEX, VALS(bap_resp_code_vals), 0x0, NULL, HFILL }},
7768 };
7769
7770 static gint *ett[] = {
7771 &ett_bap,
7772 &ett_bap_options,
7773 &ett_bap_link_type_opt,
7774 &ett_bap_phone_delta_opt,
7775 &ett_bap_phone_delta_subopt,
7776 &ett_bap_call_status_opt,
7777 &ett_bap_no_phone_opt,
7778 &ett_bap_reason_opt,
7779 &ett_bap_link_disc_opt,
7780 };
7781
7782 static ei_register_info ei[] = {
7783 { &ei_bap_sub_option_length, { "bap.sub_option_length.invalid", PI_PROTOCOL, PI_WARN, "Invalid length", EXPFILL }},
7784 };
7785
7786 expert_module_t* expert_bap;
7787
7788 proto_bap = proto_register_protocol("PPP Bandwidth Allocation Protocol", "PPP BAP", "bap");
7789 proto_register_field_array(proto_bap, hf, array_length(hf));
7790 proto_register_subtree_array(ett, array_length(ett));
7791 expert_bap = expert_register_protocol(proto_bap);
7792 expert_register_field_array(expert_bap, ei, array_length(ei));
7793
7794 bap_option_table = register_dissector_table("bap.option", "PPP BAP Options", proto_bap, FT_UINT8, BASE_DEC);
7795
7796 /* Register BAP options as their own protocols so we can get the name of the option */
7797 proto_bap_option_link_type = proto_register_protocol_in_name_only("Link Type", "Link Type", "bap.opt.link_type", proto_bap, FT_BYTES);
7798 proto_bap_option_phone_delta = proto_register_protocol_in_name_only("Phone Delta", "Phone Delta", "bap.opt.phone_delta", proto_bap, FT_BYTES);
7799 proto_bap_option_no_phone = proto_register_protocol_in_name_only("No Phone Number Needed", "No Phone Number Needed", "bap.opt.no_phone", proto_bap, FT_BYTES);
7800 proto_bap_option_reason = proto_register_protocol_in_name_only("Reason", "Reason", "bap.opt.reason", proto_bap, FT_BYTES);
7801 proto_bap_option_link_disc = proto_register_protocol_in_name_only("Link Discriminator", "Link Discriminator", "bap.opt.link_disc", proto_bap, FT_BYTES);
7802 proto_bap_option_call_status = proto_register_protocol_in_name_only("Call Status", "Call Status", "bap.opt.call_status", proto_bap, FT_BYTES);
7803 }
7804
7805 void
proto_reg_handoff_bap(void)7806 proto_reg_handoff_bap(void)
7807 {
7808 dissector_handle_t bap_handle;
7809
7810 bap_handle = create_dissector_handle(dissect_bap, proto_bap);
7811 dissector_add_uint("ppp.protocol", PPP_BAP, bap_handle);
7812
7813 /*
7814 * See above comment about NDISWAN for an explanation of why we're
7815 * registering with the "ethertype" dissector table.
7816 */
7817 dissector_add_uint("ethertype", PPP_BAP, bap_handle);
7818
7819 dissector_add_uint("bap.option", CI_BAP_LINK_TYPE, create_dissector_handle( dissect_bap_link_type_opt, proto_bap_option_link_type ));
7820 dissector_add_uint("bap.option", CI_BAP_PHONE_DELTA, create_dissector_handle( dissect_bap_phone_delta_opt, proto_bap_option_phone_delta ));
7821 dissector_add_uint("bap.option", CI_BAP_NO_PHONE_NUM_NEEDED, create_dissector_handle( dissect_bap_no_phone_opt, proto_bap_option_no_phone ));
7822 dissector_add_uint("bap.option", CI_BAP_REASON, create_dissector_handle( dissect_bap_reason_opt, proto_bap_option_reason ));
7823 dissector_add_uint("bap.option", CI_BAP_LINK_DISC, create_dissector_handle( dissect_bap_link_disc_opt, proto_bap_option_link_disc ));
7824 dissector_add_uint("bap.option", CI_BAP_CALL_STATUS, create_dissector_handle( dissect_bap_call_status_opt, proto_bap_option_call_status ));
7825 }
7826
7827 void
proto_register_comp_data(void)7828 proto_register_comp_data(void)
7829 {
7830 #if 0 /* See dissect_comp_data() */
7831 static gint *ett[] = {
7832 &ett_comp_data
7833 };
7834 #endif
7835
7836 proto_comp_data = proto_register_protocol("PPP Compressed Datagram",
7837 "PPP Comp", "comp_data");
7838 #if 0
7839 proto_register_subtree_array(ett, array_length(ett));
7840 #endif
7841 }
7842
7843 void
proto_reg_handoff_comp_data(void)7844 proto_reg_handoff_comp_data(void)
7845 {
7846 dissector_handle_t comp_data_handle;
7847
7848 comp_data_handle = create_dissector_handle(dissect_comp_data,
7849 proto_comp_data);
7850 dissector_add_uint("ppp.protocol", PPP_COMP, comp_data_handle);
7851
7852 /*
7853 * See above comment about NDISWAN for an explanation of why we're
7854 * registering with the "ethertype" dissector table.
7855 */
7856 dissector_add_uint("ethertype", PPP_COMP, comp_data_handle);
7857 }
7858
7859 void
proto_register_pap(void)7860 proto_register_pap(void)
7861 {
7862 static gint *ett[] = {
7863 &ett_pap,
7864 &ett_pap_data
7865 };
7866
7867 static hf_register_info hf[] = {
7868 { &hf_pap_code,
7869 { "Code", "pap.code", FT_UINT8, BASE_DEC, VALS(pap_vals), 0x0,
7870 "The Code field is one octet and identifies the type of PAP "
7871 "packet", HFILL }},
7872 { &hf_pap_identifier,
7873 { "Identifier", "pap.identifier", FT_UINT8, BASE_DEC, NULL, 0x0,
7874 "The Identifier field is one octet and aids in matching "
7875 "requests and replies.", HFILL }},
7876 { &hf_pap_length,
7877 { "Length", "pap.length", FT_UINT16, BASE_DEC, NULL, 0x0,
7878 "The Length field is two octets and indicates the length of "
7879 "the PAP packet", HFILL }},
7880 { &hf_pap_data,
7881 { "Data", "pap.data", FT_NONE, BASE_NONE, NULL, 0x0,
7882 "The format of the Data field is determined by the Code field",
7883 HFILL }},
7884 { &hf_pap_peer_id_length,
7885 { "Peer-ID-Length", "pap.peer_id.length",
7886 FT_UINT8, BASE_DEC, NULL, 0x0,
7887 "The Peer-ID-Length field is one octet and indicates the "
7888 "length of the Peer-ID field", HFILL }},
7889 { &hf_pap_peer_id,
7890 { "Peer-ID", "pap.peer_id", FT_STRING, BASE_NONE, NULL, 0x0,
7891 "The Peer-ID field is zero or more octets and indicates the "
7892 "name of the peer to be authenticated", HFILL }},
7893 { &hf_pap_password_length,
7894 { "Password-Length", "pap.password.length",
7895 FT_UINT8, BASE_DEC, NULL, 0x0,
7896 "The Password-Length field is one octet and indicates the "
7897 "length of the Password field", HFILL }},
7898 { &hf_pap_password,
7899 { "Password", "pap.password", FT_STRING, BASE_NONE, NULL, 0x0,
7900 "The Password field is zero or more octets and indicates the "
7901 "password to be used for authentication", HFILL }},
7902 { &hf_pap_message_length,
7903 { "Message-Length", "pap.message.length",
7904 FT_UINT8, BASE_DEC, NULL, 0x0,
7905 "The Message-Length field is one octet and indicates the "
7906 "length of the Message field", HFILL }},
7907 { &hf_pap_message,
7908 { "Message", "pap.message", FT_STRING, BASE_NONE, NULL, 0x0,
7909 "The Message field is zero or more octets, and its contents "
7910 "are implementation dependent.", HFILL }},
7911 { &hf_pap_stuff,
7912 { "stuff", "pap.stuff", FT_BYTES, BASE_NONE,
7913 NULL, 0x0, NULL, HFILL }}
7914 };
7915
7916 proto_pap = proto_register_protocol("PPP Password Authentication Protocol",
7917 "PPP PAP", "pap");
7918 proto_register_field_array(proto_pap, hf, array_length(hf));
7919 proto_register_subtree_array(ett, array_length(ett));
7920 }
7921
7922 void
proto_reg_handoff_pap(void)7923 proto_reg_handoff_pap(void)
7924 {
7925 dissector_handle_t pap_handle;
7926
7927 pap_handle = create_dissector_handle(dissect_pap, proto_pap);
7928 dissector_add_uint("ppp.protocol", PPP_PAP, pap_handle);
7929
7930 /*
7931 * See above comment about NDISWAN for an explanation of why we're
7932 * registering with the "ethertype" dissector table.
7933 */
7934 dissector_add_uint("ethertype", PPP_PAP, pap_handle);
7935
7936 /*
7937 * for GSM-A / MobileL3 / GPRS SM / PCO
7938 */
7939 dissector_add_uint("sm_pco.protocol", PPP_PAP, pap_handle);
7940 }
7941
7942 void
proto_register_chap(void)7943 proto_register_chap(void)
7944 {
7945 static gint *ett[] = {
7946 &ett_chap,
7947 &ett_chap_data
7948 };
7949
7950 static hf_register_info hf[] = {
7951 { &hf_chap_code,
7952 { "Code", "chap.code", FT_UINT8, BASE_DEC, VALS(chap_vals), 0x0,
7953 "CHAP code", HFILL }},
7954 { &hf_chap_identifier,
7955 { "Identifier", "chap.identifier", FT_UINT8, BASE_DEC, NULL, 0x0,
7956 "CHAP identifier", HFILL }},
7957 { &hf_chap_length,
7958 { "Length", "chap.length", FT_UINT16, BASE_DEC, NULL, 0x0,
7959 "CHAP length", HFILL }},
7960 { &hf_chap_data,
7961 { "Data", "chap.data", FT_NONE, BASE_NONE, NULL, 0x0,
7962 "CHAP Data", HFILL }},
7963 { &hf_chap_value_size,
7964 { "Value Size", "chap.value_size", FT_UINT8, BASE_DEC, NULL, 0x0,
7965 "CHAP value size", HFILL }},
7966 { &hf_chap_value,
7967 { "Value", "chap.value", FT_BYTES, BASE_NONE, NULL, 0x0,
7968 "CHAP value data", HFILL }},
7969 { &hf_chap_name,
7970 { "Name", "chap.name", FT_STRING, BASE_NONE, NULL, 0x0,
7971 "CHAP name", HFILL }},
7972 { &hf_chap_message,
7973 { "Message", "chap.message", FT_STRING, BASE_NONE, NULL, 0x0,
7974 "CHAP message", HFILL }},
7975 { &hf_chap_stuff,
7976 { "Stuff", "chap.stuff", FT_BYTES, BASE_NONE, NULL, 0x0,
7977 NULL, HFILL }},
7978 };
7979
7980 proto_chap = proto_register_protocol(
7981 "PPP Challenge Handshake Authentication Protocol", "PPP CHAP", "chap");
7982 proto_register_field_array(proto_chap, hf, array_length(hf));
7983 proto_register_subtree_array(ett, array_length(ett));
7984 }
7985
7986 void
proto_reg_handoff_chap(void)7987 proto_reg_handoff_chap(void)
7988 {
7989 dissector_handle_t chap_handle = create_dissector_handle(dissect_chap,
7990 proto_chap);
7991 dissector_add_uint("ppp.protocol", PPP_CHAP, chap_handle);
7992
7993 /*
7994 * See above comment about NDISWAN for an explanation of why we're
7995 * registering with the "ethertype" dissector table.
7996 */
7997 dissector_add_uint("ethertype", PPP_CHAP, chap_handle);
7998
7999 /*
8000 * for GSM-A / MobileL3 / GPRS SM / PCO
8001 */
8002 dissector_add_uint("sm_pco.protocol", PPP_CHAP, chap_handle);
8003 }
8004
8005 void
proto_register_pppmuxcp(void)8006 proto_register_pppmuxcp(void)
8007 {
8008 static hf_register_info hf[] = {
8009 { &hf_pppmux_flags_pid,
8010 { "PID", "pppmuxcp.flags.pid", FT_BOOLEAN, 8, TFS(&tfs_present_not_present), 0x80,
8011 NULL, HFILL }},
8012 { &hf_pppmux_flags_field_length,
8013 { "Length field", "pppmuxcp.flags.field_length", FT_BOOLEAN, 8, TFS(&tfs_pppmux_length_field), 0x40,
8014 NULL, HFILL }},
8015 { &hf_pppmuxcp_opt_type,
8016 { "Type", "pppmuxcp.opt.type", FT_UINT8, BASE_DEC, NULL, 0x0,
8017 NULL, HFILL }},
8018 { &hf_pppmuxcp_opt_length,
8019 { "Length", "pppmuxcp.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0,
8020 NULL, HFILL }},
8021
8022 /* Generated from convert_proto_tree_add_text.pl */
8023 { &hf_pppmux_flags, { "PFF/LXT", "pppmuxcp.flags", FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
8024 { &hf_pppmux_sub_frame_length, { "Sub-frame Length", "pppmuxcp.sub_frame_length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
8025 { &hf_pppmux_def_prot_id, { "Default Protocol ID", "pppmuxcp.def_prot_id", FT_UINT16, BASE_HEX|BASE_EXT_STRING, &ppp_vals_ext, 0x0, NULL, HFILL }},
8026 };
8027
8028 static gint *ett[] = {
8029 &ett_pppmuxcp,
8030 &ett_pppmuxcp_options,
8031 &ett_pppmuxcp_def_pid_opt
8032 };
8033
8034 proto_pppmuxcp = proto_register_protocol("PPPMux Control Protocol", "PPP PPPMuxCP", "pppmuxcp");
8035 proto_register_field_array(proto_pppmuxcp, hf, array_length(hf));
8036 proto_register_subtree_array(ett, array_length(ett));
8037
8038 pppmuxcp_option_table = register_dissector_table("pppmuxcp.option", "PPP PPPMuxCP Options", proto_pppmuxcp, FT_UINT8, BASE_DEC);
8039
8040 /* Register PPPMuxCP options as their own protocols so we can get the name of the option */
8041 proto_pppmuxcp_option_def_pid = proto_register_protocol_in_name_only("Default Protocol ID", "Default Protocol ID", "pppmuxcp.opt.def_pid", proto_pppmuxcp, FT_BYTES);
8042 }
8043
8044
8045 void
proto_reg_handoff_pppmuxcp(void)8046 proto_reg_handoff_pppmuxcp(void)
8047 {
8048 dissector_handle_t muxcp_handle;
8049
8050 muxcp_handle = create_dissector_handle(dissect_pppmuxcp, proto_pppmuxcp);
8051 dissector_add_uint("ppp.protocol", PPP_MUXCP, muxcp_handle);
8052
8053 /*
8054 * See above comment about NDISWAN for an explanation of why we're
8055 * registering with the "ethertype" dissector table.
8056 */
8057 dissector_add_uint("ethertype", PPP_MUXCP, muxcp_handle);
8058
8059 dissector_add_uint("pppmuxcp.option", CI_DEFAULT_PID, create_dissector_handle( dissect_pppmuxcp_def_pid_opt, proto_pppmuxcp_option_def_pid ));
8060 }
8061
8062
8063 void
proto_register_pppmux(void)8064 proto_register_pppmux(void)
8065 {
8066 static hf_register_info hf[] = {
8067 { &hf_pppmux_protocol,
8068 { "Protocol", "pppmux.protocol", FT_UINT16,
8069 BASE_HEX|BASE_EXT_STRING, &ppp_vals_ext, 0x0,
8070 "The protocol of the sub-frame.", HFILL }}
8071 };
8072
8073 static gint *ett[] = {
8074 &ett_pppmux,
8075 &ett_pppmux_subframe,
8076 &ett_pppmux_subframe_hdr,
8077 &ett_pppmux_subframe_flags,
8078 &ett_pppmux_subframe_info
8079 };
8080
8081 proto_pppmux = proto_register_protocol("PPP Multiplexing", "PPP PPPMux",
8082 "pppmux");
8083 proto_register_field_array(proto_pppmux, hf, array_length(hf));
8084 proto_register_subtree_array(ett, array_length(ett));
8085 }
8086
8087 void
proto_reg_handoff_pppmux(void)8088 proto_reg_handoff_pppmux(void)
8089 {
8090 dissector_handle_t pppmux_handle;
8091
8092 pppmux_handle = create_dissector_handle(dissect_pppmux, proto_pppmux);
8093 dissector_add_uint("ppp.protocol", PPP_MUX, pppmux_handle);
8094
8095 /*
8096 * See above comment about NDISWAN for an explanation of why we're
8097 * registering with the "ethertype" dissector table.
8098 */
8099 dissector_add_uint("ethertype", PPP_MUX, pppmux_handle);
8100 }
8101
8102 void
proto_register_mplscp(void)8103 proto_register_mplscp(void)
8104 {
8105 static gint *ett[] = {
8106 &ett_mplscp,
8107 &ett_mplscp_options
8108 };
8109
8110 proto_mplscp = proto_register_protocol("PPP MPLS Control Protocol",
8111 "PPP MPLSCP", "mplscp");
8112 proto_register_subtree_array(ett, array_length(ett));
8113 }
8114
8115 void
proto_reg_handoff_mplscp(void)8116 proto_reg_handoff_mplscp(void)
8117 {
8118 dissector_handle_t mplscp_handle;
8119
8120 mplscp_handle = create_dissector_handle(dissect_mplscp, proto_mplscp);
8121 dissector_add_uint("ppp.protocol", PPP_MPLSCP, mplscp_handle);
8122
8123 /*
8124 * See above comment about NDISWAN for an explanation of why we're
8125 * registering with the "ethertype" dissector table.
8126 */
8127 dissector_add_uint("ethertype", PPP_MPLSCP, mplscp_handle);
8128 }
8129
8130 void
proto_register_cdpcp(void)8131 proto_register_cdpcp(void)
8132 {
8133 static gint *ett[] = {
8134 &ett_cdpcp,
8135 &ett_cdpcp_options
8136 };
8137
8138 proto_cdpcp = proto_register_protocol("PPP CDP Control Protocol",
8139 "PPP CDPCP", "cdpcp");
8140 proto_register_subtree_array(ett, array_length(ett));
8141 }
8142
8143 void
proto_reg_handoff_cdpcp(void)8144 proto_reg_handoff_cdpcp(void)
8145 {
8146 dissector_handle_t cdpcp_handle;
8147
8148 cdpcp_handle = create_dissector_handle(dissect_cdpcp, proto_cdpcp);
8149 dissector_add_uint("ppp.protocol", PPP_CDPCP, cdpcp_handle);
8150
8151 /*
8152 * See above comment about NDISWAN for an explanation of why we're
8153 * registering with the "ethertype" dissector table.
8154 */
8155 dissector_add_uint("ethertype", PPP_CDPCP, cdpcp_handle);
8156 }
8157
8158 void
proto_register_ipv6cp(void)8159 proto_register_ipv6cp(void)
8160 {
8161 static hf_register_info hf[] = {
8162 { &hf_ipv6cp_opt_type, { "Type", "ipv6cp.opt.type", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
8163 { &hf_ipv6cp_opt_length, { "Length", "ipv6cp.opt.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
8164 /* Generated from convert_proto_tree_add_text.pl */
8165 { &hf_ipv6cp_interface_identifier, { "Interface Identifier", "ipv6cp.interface_identifier", FT_BYTES, SEP_COLON, NULL, 0x0, NULL, HFILL }},
8166 };
8167 static gint *ett[] = {
8168 &ett_ipv6cp,
8169 &ett_ipv6cp_options,
8170 &ett_ipv6cp_if_id_opt,
8171 &ett_ipv6cp_compress_opt
8172 };
8173
8174 proto_ipv6cp = proto_register_protocol("PPP IPv6 Control Protocol", "PPP IPV6CP", "ipv6cp");
8175 proto_register_field_array(proto_ipv6cp, hf, array_length(hf));
8176 proto_register_subtree_array(ett, array_length(ett));
8177
8178 ipv6cp_option_table = register_dissector_table("ipv6cp.option", "PPP IPV6CP Options", proto_ipv6cp, FT_UINT8, BASE_DEC);
8179
8180 /* Register IPV6CP options as their own protocols so we can get the name of the option */
8181 proto_ipv6cp_option_if_id = proto_register_protocol_in_name_only("Interface Identifier", "Interface Identifier", "ipv6cp.opt.interface_identifier", proto_ipv6cp, FT_BYTES);
8182 proto_ipv6cp_option_compress = proto_register_protocol_in_name_only("IPv6 compression", "IPv6 compression", "ipv6cp.opt.compress", proto_ipv6cp, FT_BYTES);
8183 }
8184
8185 void
proto_reg_handoff_ipv6cp(void)8186 proto_reg_handoff_ipv6cp(void)
8187 {
8188 dissector_handle_t ipv6cp_handle;
8189
8190 ipv6cp_handle = create_dissector_handle(dissect_ipv6cp, proto_ipv6cp);
8191 dissector_add_uint("ppp.protocol", PPP_IPV6CP, ipv6cp_handle);
8192
8193 /*
8194 * See above comment about NDISWAN for an explanation of why we're
8195 * registering with the "ethertype" dissector table.
8196 */
8197 dissector_add_uint("ethertype", PPP_IPV6CP, ipv6cp_handle);
8198
8199 /*
8200 * for GSM-A / MobileL3 / GPRS SM / PCO
8201 */
8202 dissector_add_uint("sm_pco.protocol", PPP_IPV6CP, ipv6cp_handle);
8203
8204 dissector_add_uint("ipv6cp.option", CI_IPV6CP_IF_ID, create_dissector_handle( dissect_ipv6cp_if_id_opt, proto_ipv6cp_option_if_id ));
8205 dissector_add_uint("ipv6cp.option", CI_COMPRESS_PROTO, create_dissector_handle( dissect_ipcp_compress_opt, proto_ipv6cp_option_compress ));
8206 }
8207
8208 void
proto_register_iphc_crtp(void)8209 proto_register_iphc_crtp(void)
8210 {
8211 static hf_register_info hf[] = {
8212 { &hf_iphc_crtp_cid16,
8213 { "Context Id", "crtp.cid", FT_UINT16, BASE_DEC, NULL, 0x0,
8214 "The context identifier of the compressed packet.", HFILL }},
8215 { &hf_iphc_crtp_cid8,
8216 { "Context Id", "crtp.cid", FT_UINT8, BASE_DEC, NULL, 0x0,
8217 "The context identifier of the compressed packet.", HFILL }},
8218 { &hf_iphc_crtp_gen,
8219 { "Generation", "crtp.gen", FT_UINT8, BASE_DEC, NULL, 0x3f,
8220 "The generation of the compressed packet.", HFILL }},
8221 { &hf_iphc_crtp_seq,
8222 { "Sequence (Data)", "crtp.seq", FT_UINT8, BASE_DEC, NULL, 0x0f,
8223 "The sequence of the compressed packet.", HFILL }},
8224 { &hf_iphc_crtp_fh_flags,
8225 { "Flags", "crtp.fh_flags", FT_UINT8, BASE_HEX, NULL,
8226 IPHC_CRTP_FH_FLAG_MASK,
8227 "The flags of the full header packet.", HFILL }},
8228 { &hf_iphc_crtp_fh_cidlenflag,
8229 { "CID Length", "crtp.fh_flags.cidlen", FT_BOOLEAN, 8, TFS(&iphc_crtp_fh_cidlenflag),
8230 IPHC_CRTP_FH_CIDLEN_FLAG, "A flag which is not set for 8-bit Context Ids and set for 16-bit Context Ids.", HFILL }},
8231 { &hf_iphc_crtp_fh_dataflag,
8232 { "Sequence (Data)", "crtp.fh_flags.data", FT_BOOLEAN, 8,
8233 TFS(&tfs_present_absent), IPHC_CRTP_FH_DATA_FLAG,
8234 "This indicates the presence of a nonzero data field, usually meaning the low nibble is a sequence number.", HFILL }},
8235 { &hf_iphc_crtp_cs_flags,
8236 { "Flags", "crtp.cs_flags", FT_UINT8, BASE_DEC, VALS(iphc_crtp_cs_flags),
8237 0x0, "The flags of the context state packet.", HFILL }},
8238 { &hf_iphc_crtp_cs_cnt,
8239 { "Count", "crtp.cnt", FT_UINT8, BASE_DEC, NULL, 0x0,
8240 "The count of the context state packet.", HFILL }},
8241 { &hf_iphc_crtp_cs_invalid,
8242 { "Invalid", "crtp.invalid", FT_BOOLEAN, 8, NULL, 0x80,
8243 "The invalid bit of the context state packet.", HFILL }},
8244 { &hf_iphc_crtp_ip_id,
8245 { "IP-ID", "crtp.ip-id", FT_UINT16, BASE_HEX_DEC, NULL, 0x0,
8246 "The IPv4 Identification Field is RANDOM and thus included in a compressed Non TCP packet (RFC 2507 6a), 7.13a). Only IPv4 is supported in this dissector.", HFILL }},
8247 { &hf_iphc_crtp_data,
8248 { "Data", "crtp.data", FT_BYTES, BASE_NONE, NULL, 0x0,
8249 NULL, HFILL }},
8250 };
8251
8252 static gint *ett[] = {
8253 &ett_iphc_crtp,
8254 &ett_iphc_crtp_hdr,
8255 &ett_iphc_crtp_info,
8256 &ett_iphc_crtp_fh_flags
8257 };
8258
8259 static ei_register_info ei[] = {
8260 { &ei_iphc_crtp_ip_version, { "crtp.ip_version_unsupported", PI_PROTOCOL, PI_WARN, "IP version is unsupported", EXPFILL }},
8261 { &ei_iphc_crtp_next_protocol, { "crtp.next_protocol_unsupported", PI_PROTOCOL, PI_WARN, "Next protocol is unsupported", EXPFILL }},
8262 { &ei_iphc_crtp_seq_nonzero, { "crtp.seq_nonzero", PI_PROTOCOL, PI_WARN, "Sequence (Data) field is nonzero despite D bit not set", EXPFILL }}
8263 };
8264
8265 expert_module_t* expert_iphc_crtp;
8266
8267 proto_iphc_crtp = proto_register_protocol("CRTP", "CRTP", "crtp");
8268 /* Created to remove Decode As confusion */
8269 proto_iphc_crtp_cudp16 = proto_register_protocol_in_name_only("CRTP (CUDP 16)", "CRTP (CUDP 16)", "crtp_cudp16", proto_iphc_crtp, FT_PROTOCOL);
8270 proto_iphc_crtp_cudp8 = proto_register_protocol_in_name_only("CRTP (CUDP 8)", "CRTP (CUDP 8)", "crtp_cudp8", proto_iphc_crtp, FT_PROTOCOL);
8271 proto_iphc_crtp_cs = proto_register_protocol_in_name_only("CRTP (CS)", "CRTP (CS)", "crtp_cs", proto_iphc_crtp, FT_PROTOCOL);
8272 proto_iphc_crtp_cntcp = proto_register_protocol_in_name_only("CRTP (CNTCP)", "CRTP (CNTCP)", "crtp_cntcp", proto_iphc_crtp, FT_PROTOCOL);
8273
8274 proto_register_field_array(proto_iphc_crtp, hf, array_length(hf));
8275 proto_register_subtree_array(ett, array_length(ett));
8276 expert_iphc_crtp = expert_register_protocol(proto_iphc_crtp);
8277 expert_register_field_array(expert_iphc_crtp, ei, array_length(ei));
8278 }
8279
8280 void
proto_reg_handoff_iphc_crtp(void)8281 proto_reg_handoff_iphc_crtp(void)
8282 {
8283 dissector_handle_t fh_handle;
8284 dissector_handle_t cudp16_handle;
8285 dissector_handle_t cudp8_handle;
8286 dissector_handle_t cs_handle;
8287 dissector_handle_t cntcp_handle;
8288
8289 fh_handle = create_dissector_handle(dissect_iphc_crtp_fh, proto_iphc_crtp);
8290 dissector_add_uint("ppp.protocol", PPP_RTP_FH, fh_handle);
8291
8292 cudp16_handle = create_dissector_handle(dissect_iphc_crtp_cudp16, proto_iphc_crtp_cudp16);
8293 dissector_add_uint("ppp.protocol", PPP_RTP_CUDP16, cudp16_handle);
8294
8295 cudp8_handle = create_dissector_handle(dissect_iphc_crtp_cudp8, proto_iphc_crtp_cudp8);
8296 dissector_add_uint("ppp.protocol", PPP_RTP_CUDP8, cudp8_handle);
8297
8298 cs_handle = create_dissector_handle(dissect_iphc_crtp_cs, proto_iphc_crtp_cs);
8299 dissector_add_uint("ppp.protocol", PPP_RTP_CS, cs_handle);
8300
8301 cntcp_handle = create_dissector_handle(dissect_iphc_crtp_cntcp, proto_iphc_crtp_cntcp);
8302 dissector_add_uint("ppp.protocol", PPP_RTP_CNTCP, cntcp_handle);
8303
8304 /*
8305 * See above comment about NDISWAN for an explanation of why we're
8306 * registering with the "ethertype" dissector table.
8307 */
8308 dissector_add_uint("ethertype", PPP_RTP_FH, fh_handle);
8309 dissector_add_uint("ethertype", PPP_RTP_CUDP16, cudp16_handle);
8310 dissector_add_uint("ethertype", PPP_RTP_CUDP8, cudp8_handle);
8311 dissector_add_uint("ethertype", PPP_RTP_CS, cs_handle);
8312 dissector_add_uint("ethertype", PPP_RTP_CNTCP, cntcp_handle);
8313 }
8314
8315 /*
8316 * Editor modelines - https://www.wireshark.org/tools/modelines.html
8317 *
8318 * Local variables:
8319 * c-basic-offset: 4
8320 * tab-width: 8
8321 * indent-tabs-mode: nil
8322 * End:
8323 *
8324 * vi: set shiftwidth=4 tabstop=8 expandtab:
8325 * :indentSize=4:tabSize=8:noTabs=true:
8326 */
8327