xref: /openbsd/usr.sbin/tcpdump/print-l2tp.c (revision cecf84d4)
1 /*	$OpenBSD: print-l2tp.c,v 1.8 2015/01/16 06:40:21 deraadt Exp $	*/
2 
3 /*
4  * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that: (1) source code distributions
9  * retain the above copyright notice and this paragraph in its entirety, (2)
10  * distributions including binary code include the above copyright notice and
11  * this paragraph in its entirety in the documentation or other materials
12  * provided with the distribution, and (3) all advertising materials mentioning
13  * features or use of this software display the following acknowledgement:
14  * ``This product includes software developed by the University of California,
15  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
16  * the University nor the names of its contributors may be used to endorse
17  * or promote products derived from this software without specific prior
18  * written permission.
19  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
22  *
23  * L2TP support contributed by Motonori Shindo (mshindo@ascend.co.jp)
24  */
25 
26 #include <sys/types.h>
27 #include <stdio.h>
28 #include <strings.h>
29 
30 #include "l2tp.h"
31 #include "interface.h"
32 
33 static char tstr[] = " [|l2tp]";
34 
35 #ifndef TRUE
36 #define TRUE 1
37 #endif
38 
39 #ifndef FALSE
40 #define FALSE 0
41 #endif
42 
43 static u_char *l2tp_message_type_string[] = {
44 	"RESERVED_0",		/* 0  Reserved */
45 	"SCCRQ",		/* 1  Start-Control-Connection-Request */
46 	"SCCRP",		/* 2  Start-Control-Connection-Reply */
47 	"SCCCN",		/* 3  Start-Control-Connection-Connected */
48 	"StopCCN",		/* 4  Stop-Control-Connection-Notification */
49 	"RESERVED_5",		/* 5  Reserved */
50 	"HELLO",		/* 6  Hello */
51 	"OCRQ",			/* 7  Outgoing-Call-Request */
52 	"OCRP",			/* 8  Outgoing-Call-Reply */
53 	"OCCN",			/* 9  Outgoing-Call-Connected */
54 	"ICRQ",			/* 10 Incoming-Call-Request */
55 	"ICRP",			/* 11 Incoming-Call-Reply */
56 	"ICCN",			/* 12 Incoming-Call-Connected */
57 	"RESERVED_13",		/* 13 Reserved */
58 	"CDN",			/* 14 Call-Disconnect-Notify */
59 	"WEN",			/* 15 WAN-Error-Notify */
60 	"SLI"			/* 16 Set-Link-Info */
61 #define L2TP_MAX_MSGTYPE_INDEX	17
62 };
63 
64 static void l2tp_msgtype_print(const u_char *dat, u_int length);
65 static void l2tp_result_code_print(const u_char *dat, u_int length);
66 static void l2tp_proto_ver_print(const u_char *dat, u_int length);
67 static void l2tp_framing_cap_print(const u_char *dat, u_int length);
68 static void l2tp_bearer_cap_print(const u_char *dat, u_int length);
69 static void l2tp_tie_breaker_print(const u_char *dat, u_int length);
70 static void l2tp_firm_ver_print(const u_char *dat, u_int length);
71 static void l2tp_host_name_print(const u_char *dat, u_int length);
72 static void l2tp_vendor_name_print(const u_char *dat, u_int length);
73 static void l2tp_assnd_tun_id_print(const u_char *dat, u_int length);
74 static void l2tp_recv_win_size_print(const u_char *dat, u_int length);
75 static void l2tp_challenge_print(const u_char *dat, u_int length);
76 static void l2tp_q931_cc_print(const u_char *dat, u_int length);
77 static void l2tp_challenge_resp_print(const u_char *dat, u_int length);
78 static void l2tp_assnd_sess_id_print(const u_char *dat, u_int length);
79 static void l2tp_call_ser_num_print(const u_char *dat, u_int length);
80 static void l2tp_minimum_bps_print(const u_char *dat, u_int length);
81 static void l2tp_maximum_bps_print(const u_char *dat, u_int length);
82 static void l2tp_bearer_type_print(const u_char *dat, u_int length);
83 static void l2tp_framing_type_print(const u_char *dat, u_int length);
84 static void l2tp_packet_proc_delay_print(const u_char *dat, u_int length);
85 static void l2tp_called_number_print(const u_char *dat, u_int length);
86 static void l2tp_calling_number_print(const u_char *dat, u_int length);
87 static void l2tp_sub_address_print(const u_char *dat, u_int length);
88 static void l2tp_tx_conn_speed_print(const u_char *dat, u_int length);
89 static void l2tp_phy_channel_id_print(const u_char *dat, u_int length);
90 static void l2tp_ini_recv_lcp_print(const u_char *dat, u_int length);
91 static void l2tp_last_sent_lcp_print(const u_char *dat, u_int length);
92 static void l2tp_last_recv_lcp_print(const u_char *dat, u_int length);
93 static void l2tp_proxy_auth_type_print(const u_char *dat, u_int length);
94 static void l2tp_proxy_auth_name_print(const u_char *dat, u_int length);
95 static void l2tp_proxy_auth_chal_print(const u_char *dat, u_int length);
96 static void l2tp_proxy_auth_id_print(const u_char *dat, u_int length);
97 static void l2tp_proxy_auth_resp_print(const u_char *dat, u_int length);
98 static void l2tp_call_errors_print(const u_char *dat, u_int length);
99 static void l2tp_accm_print(const u_char *dat, u_int length);
100 static void l2tp_random_vector_print(const u_char *dat, u_int length);
101 static void l2tp_private_grp_id_print(const u_char *dat, u_int length);
102 static void l2tp_rx_conn_speed_print(const u_char *dat, u_int length);
103 static void l2tp_seq_required_print(const u_char *dat, u_int length);
104 static void l2tp_avp_print(const u_char *dat, u_int length);
105 
106 static struct l2tp_avp_vec l2tp_avp[] = {
107   {"MSGTYPE", l2tp_msgtype_print}, 		/* 0  Message Type */
108   {"RESULT_CODE", l2tp_result_code_print},	/* 1  Result Code */
109   {"PROTO_VER", l2tp_proto_ver_print},		/* 2  Protocol Version */
110   {"FRAMING_CAP", l2tp_framing_cap_print},	/* 3  Framing Capabilities */
111   {"BEARER_CAP", l2tp_bearer_cap_print},	/* 4  Bearer Capabilities */
112   {"TIE_BREAKER", l2tp_tie_breaker_print},	/* 5  Tie Breaker */
113   {"FIRM_VER", l2tp_firm_ver_print},		/* 6  Firmware Revision */
114   {"HOST_NAME", l2tp_host_name_print},		/* 7  Host Name */
115   {"VENDOR_NAME", l2tp_vendor_name_print},	/* 8  Vendor Name */
116   {"ASSND_TUN_ID", l2tp_assnd_tun_id_print}, 	/* 9  Assigned Tunnel ID */
117   {"RECV_WIN_SIZE", l2tp_recv_win_size_print},	/* 10 Receive Window Size */
118   {"CHALLENGE", l2tp_challenge_print},		/* 11 Challenge */
119   {"Q931_CC", l2tp_q931_cc_print},		/* 12 Q.931 Cause Code */
120   {"CHALLENGE_RESP", l2tp_challenge_resp_print},/* 13 Challenge Response */
121   {"ASSND_SESS_ID", l2tp_assnd_sess_id_print},  /* 14 Assigned Session ID */
122   {"CALL_SER_NUM", l2tp_call_ser_num_print}, 	/* 15 Call Serial Number */
123   {"MINIMUM_BPS",	l2tp_minimum_bps_print},/* 16 Minimum BPS */
124   {"MAXIMUM_BPS", l2tp_maximum_bps_print},	/* 17 Maximum BPS */
125   {"BEARER_TYPE",	l2tp_bearer_type_print},/* 18 Bearer Type */
126   {"FRAMING_TYPE", l2tp_framing_type_print}, 	/* 19 Framing Type */
127   {"PACKET_PROC_DELAY", l2tp_packet_proc_delay_print}, /* 20 Packet Processing Delay (OBSOLETE) */
128   {"CALLED_NUMBER", l2tp_called_number_print},	/* 21 Called Number */
129   {"CALLING_NUMBER", l2tp_calling_number_print},/* 22 Calling Number */
130   {"SUB_ADDRESS",	l2tp_sub_address_print},/* 23 Sub-Address */
131   {"TX_CONN_SPEED", l2tp_tx_conn_speed_print},	/* 24 (Tx) Connect Speed */
132   {"PHY_CHANNEL_ID", l2tp_phy_channel_id_print},/* 25 Physical Channel ID */
133   {"INI_RECV_LCP", l2tp_ini_recv_lcp_print}, 	/* 26 Initial Received LCP CONFREQ */
134   {"LAST_SENT_LCP", l2tp_last_sent_lcp_print},	/* 27 Last Sent LCP CONFREQ */
135   {"LAST_RECV_LCP", l2tp_last_recv_lcp_print},	/* 28 Last Received LCP CONFREQ */
136   {"PROXY_AUTH_TYPE", l2tp_proxy_auth_type_print},/* 29 Proxy Authen Type */
137   {"PROXY_AUTH_NAME", l2tp_proxy_auth_name_print},/* 30 Proxy Authen Name */
138   {"PROXY_AUTH_CHAL", l2tp_proxy_auth_chal_print},/* 31 Proxy Authen Challenge */
139   {"PROXY_AUTH_ID", l2tp_proxy_auth_id_print},	/* 32 Proxy Authen ID */
140   {"PROXY_AUTH_RESP", l2tp_proxy_auth_resp_print},/* 33 Proxy Authen Response */
141   {"CALL_ERRORS", l2tp_call_errors_print},	/* 34 Call Errors */
142   {"ACCM", l2tp_accm_print},			/* 35 ACCM */
143   {"RANDOM_VECTOR", l2tp_random_vector_print},	/* 36 Random Vector */
144   {"PRIVATE_GRP_ID", l2tp_private_grp_id_print},/* 37 Private Group ID */
145   {"RX_CONN_SPEED", l2tp_rx_conn_speed_print},	/* 38 (Rx) Connect Speed */
146   {"SEQ_REQUIRED", l2tp_seq_required_print}, 	/* 39 Sequencing Required */
147 #define L2TP_MAX_AVP_INDEX	40
148 };
149 
150 #if 0
151 static char *l2tp_result_code_StopCCN[] = {
152          "Reserved",
153          "General request to clear control connection",
154          "General error--Error Code indicates the problem",
155          "Control channel already exists",
156          "Requester is not authorized to establish a control channel",
157          "The protocol version of the requester is not supported",
158          "Requester is being shut down",
159          "Finite State Machine error"
160 #define L2TP_MAX_RESULT_CODE_STOPCC_INDEX	8
161 };
162 #endif
163 
164 #if 0
165 static char *l2tp_result_code_CDN[] = {
166 	"Reserved",
167 	"Call disconnected due to loss of carrier",
168 	"Call disconnected for the reason indicated in error code",
169 	"Call disconnected for administrative reasons",
170 	"Call failed due to lack of appropriate facilities being " \
171 	"available (temporary condition)",
172 	"Call failed due to lack of appropriate facilities being " \
173 	"available (permanent condition)",
174 	"Invalid destination",
175 	"Call failed due to no carrier detected",
176 	"Call failed due to detection of a busy signal",
177 	"Call failed due to lack of a dial tone",
178 	"Call was not established within time allotted by LAC",
179 	"Call was connected but no appropriate framing was detected"
180 #define L2TP_MAX_RESULT_CODE_CDN_INDEX	12
181 };
182 #endif
183 
184 #if 0
185 static char *l2tp_error_code_general[] = {
186 	"No general error",
187 	"No control connection exists yet for this LAC-LNS pair",
188 	"Length is wrong",
189 	"One of the field values was out of range or " \
190 	"reserved field was non-zero"
191 	"Insufficient resources to handle this operation now",
192 	"The Session ID is invalid in this context",
193 	"A generic vendor-specific error occurred in the LAC",
194 	"Try another"
195 #define L2TP_MAX_ERROR_CODE_GENERAL_INDEX	8
196 };
197 #endif
198 
199 /******************************/
200 /* generic print out routines */
201 /******************************/
202 static void
203 print_string(const u_char *dat, u_int length)
204 {
205 	int i;
206 	for (i=0; i<length; i++) {
207 		printf("%c", *dat++);
208 	}
209 }
210 
211 static void
212 print_octets(const u_char *dat, u_int length)
213 {
214 	int i;
215 	for (i=0; i<length; i++) {
216 		printf("%02x", *dat++);
217 	}
218 }
219 
220 static void
221 print_short(const u_short *dat)
222 {
223 	printf("%u", ntohs(*dat));
224 }
225 
226 static void
227 print_int(const u_int *dat)
228 {
229 	printf("%lu", (u_long)ntohl(*dat));
230 }
231 
232 /**********************************/
233 /* AVP-specific print out routines*/
234 /**********************************/
235 static void
236 l2tp_msgtype_print(const u_char *dat, u_int length)
237 {
238 	u_short *ptr = (u_short *)dat;
239 
240 	if (ntohs(*ptr) < L2TP_MAX_MSGTYPE_INDEX) {
241 		printf("%s", l2tp_message_type_string[ntohs(*ptr)]);
242 	}
243 }
244 
245 static void
246 l2tp_result_code_print(const u_char *dat, u_int length)
247 {
248 	/* we just print out the result and error code number */
249 	u_short *ptr = (u_short *)dat;
250 
251 	if (length == 2) {		/* result code */
252 		printf("%d", ntohs(*ptr));
253 	} else if (length == 4) { 	/* result & error code */
254 		printf("%d/%d", ntohs(*ptr), ntohs(*(ptr+1)));
255 	} else if (length > 4) {	/* result & error code & msg */
256 		printf("%u/%u ", ntohs(*ptr), ntohs(*(ptr+1)));
257 		print_string((u_char *)(ptr+2), length - 4);
258 	}
259 }
260 
261 static void
262 l2tp_proto_ver_print(const u_char *dat, u_int length)
263 {
264 	printf("%d.%d", *dat, *(dat+1));
265 }
266 
267 
268 static void
269 l2tp_framing_cap_print(const u_char *dat, u_int length)
270 {
271 	u_int *ptr = (u_int *)dat;
272 
273 	if (ntohl(*ptr) &  L2TP_FRAMING_CAP_ASYNC_MASK) {
274 		printf("A");
275 	}
276 	if (ntohl(*ptr) &  L2TP_FRAMING_CAP_SYNC_MASK) {
277 		printf("S");
278 	}
279 }
280 
281 static void
282 l2tp_bearer_cap_print(const u_char *dat, u_int length)
283 {
284 	u_int *ptr = (u_int *)dat;
285 
286 	if (ntohl(*ptr) &  L2TP_BEARER_CAP_ANALOG_MASK) {
287 		printf("A");
288 	}
289 	if (ntohl(*ptr) &  L2TP_BEARER_CAP_DIGITAL_MASK) {
290 		printf("D");
291 	}
292 }
293 
294 static void
295 l2tp_tie_breaker_print(const u_char *dat, u_int length)
296 {
297 	print_octets(dat, (length < 8 ? length : 8));
298 }
299 
300 static void
301 l2tp_firm_ver_print(const u_char *dat, u_int length)
302 {
303 	print_short((u_short *)dat);
304 }
305 
306 static void
307 l2tp_host_name_print(const u_char *dat, u_int length)
308 {
309 	print_string(dat, length);
310 }
311 
312 static void
313 l2tp_vendor_name_print(const u_char *dat, u_int length)
314 {
315 	print_string(dat, length);
316 }
317 
318 static void
319 l2tp_assnd_tun_id_print(const u_char *dat, u_int length)
320 {
321 	print_short((u_short *)dat);
322 }
323 
324 static void
325 l2tp_recv_win_size_print(const u_char *dat, u_int length)
326 {
327 	print_short((u_short *)dat);
328 }
329 
330 static void
331 l2tp_challenge_print(const u_char *dat, u_int length)
332 {
333 	print_octets(dat, length);
334 }
335 
336 static void
337 l2tp_q931_cc_print(const u_char *dat, u_int length)
338 {
339 	print_short((u_short *)dat);
340 	print_short((u_short *)(dat + 2));
341 	if (length > 3) {
342 		printf(" ");
343 		print_string(dat+3, length-3);
344 	}
345 }
346 
347 static void
348 l2tp_challenge_resp_print(const u_char *dat, u_int length)
349 {
350 	print_octets(dat, 16);		/* XXX length should be 16? */
351 }
352 
353 static void
354 l2tp_assnd_sess_id_print(const u_char *dat, u_int length)
355 {
356 	print_short((u_short *)dat);
357 }
358 
359 static void
360 l2tp_call_ser_num_print(const u_char *dat, u_int length)
361 {
362 	print_int((u_int *)dat);
363 }
364 
365 static void
366 l2tp_minimum_bps_print(const u_char *dat, u_int length)
367 {
368 	print_int((u_int *)dat);
369 }
370 
371 static void
372 l2tp_maximum_bps_print(const u_char *dat, u_int length)
373 {
374 	print_int((u_int *)dat);
375 }
376 
377 static void
378 l2tp_bearer_type_print(const u_char *dat, u_int length)
379 {
380 	u_int *ptr = (u_int *)dat;
381 
382 	if (ntohl(*ptr) &  L2TP_BEARER_TYPE_ANALOG_MASK) {
383 		printf("A");
384 	}
385 	if (ntohl(*ptr) &  L2TP_BEARER_TYPE_DIGITAL_MASK) {
386 		printf("D");
387 	}
388 }
389 
390 static void
391 l2tp_framing_type_print(const u_char *dat, u_int length)
392 {
393 	u_int *ptr = (u_int *)dat;
394 
395 	if (ntohl(*ptr) &  L2TP_FRAMING_TYPE_ASYNC_MASK) {
396 		printf("A");
397 	}
398 	if (ntohl(*ptr) &  L2TP_FRAMING_TYPE_SYNC_MASK) {
399 		printf("S");
400 	}
401 }
402 
403 static void
404 l2tp_packet_proc_delay_print(const u_char *dat, u_int length)
405 {
406 	printf("obsolete");
407 }
408 
409 static void
410 l2tp_called_number_print(const u_char *dat, u_int length)
411 {
412 	print_string(dat, length);
413 }
414 
415 static void
416 l2tp_calling_number_print(const u_char *dat, u_int length)
417 {
418 	print_string(dat, length);
419 }
420 
421 static void
422 l2tp_sub_address_print(const u_char *dat, u_int length)
423 {
424 	print_string(dat, length);
425 }
426 
427 static void
428 l2tp_tx_conn_speed_print(const u_char *dat, u_int length)
429 {
430 	print_int((u_int *)dat);
431 }
432 
433 static void
434 l2tp_phy_channel_id_print(const u_char *dat, u_int length)
435 {
436 	print_int((u_int *)dat);
437 }
438 
439 static void
440 l2tp_ini_recv_lcp_print(const u_char *dat, u_int length)
441 {
442 	print_octets(dat, length);
443 }
444 
445 static void
446 l2tp_last_sent_lcp_print(const u_char *dat, u_int length)
447 {
448 	print_octets(dat, length);
449 }
450 
451 static void
452 l2tp_last_recv_lcp_print(const u_char *dat, u_int length)
453 {
454 	print_octets(dat, length);
455 }
456 
457 static void
458 l2tp_proxy_auth_type_print(const u_char *dat, u_int length)
459 {
460 	u_short *ptr = (u_short *)dat;
461 
462 	switch (ntohs(*ptr)) {
463 	case L2TP_AUTHEN_TYPE_RESERVED:
464 		printf("Reserved");
465 		break;
466 	case L2TP_AUTHEN_TYPE_TEXTUAL:
467 		printf("Textual");
468 		break;
469 	case L2TP_AUTHEN_TYPE_CHAP:
470 		printf("CHAP");
471 		break;
472 	case L2TP_AUTHEN_TYPE_PAP:
473 		printf("PAP");
474 		break;
475 	case L2TP_AUTHEN_TYPE_NO_AUTH:
476 		printf("No Auth");
477 		break;
478 	case L2TP_AUTHEN_TYPE_MSCHAP:
479 		printf("MS-CHAP");
480 		break;
481 	default:
482 		printf("unknown");
483 	}
484 }
485 
486 static void
487 l2tp_proxy_auth_name_print(const u_char *dat, u_int length)
488 {
489 	print_octets(dat, length);
490 }
491 
492 static void
493 l2tp_proxy_auth_chal_print(const u_char *dat, u_int length)
494 {
495 	print_octets(dat, length);
496 }
497 
498 static void
499 l2tp_proxy_auth_id_print(const u_char *dat, u_int length)
500 {
501 	u_short *ptr = (u_short *)dat;
502 
503 	printf("%d", ntohs(*ptr) & L2TP_PROXY_AUTH_ID_MASK);
504 }
505 
506 static void
507 l2tp_proxy_auth_resp_print(const u_char *dat, u_int length)
508 {
509 	print_octets(dat, length);
510 }
511 
512 static void
513 l2tp_call_errors_print(const u_char *dat, u_int length)
514 {
515 	struct l2tp_call_errors *ptr = (struct l2tp_call_errors *)dat;
516 
517 	printf("CRCErr=%d FrameErr=%d HardOver=%d BufOver=%d ",
518 	       ptr->crc_errs,
519 	       ptr->framing_errs,
520 	       ptr->hardware_overruns,
521 	       ptr->buffer_overruns);
522 	printf("Timeout=%d AlingErr=%d",
523 	       ptr->timeout_errs,
524 	       ptr->alignment_errs);
525 }
526 
527 static void
528 l2tp_accm_print(const u_char *dat, u_int length)
529 {
530 	struct l2tp_accm *ptr = (struct l2tp_accm *)dat;
531 
532 	printf("send=%x recv=%x", ptr->send_accm, ptr->recv_accm);
533 }
534 
535 static void
536 l2tp_random_vector_print(const u_char *dat, u_int length)
537 {
538 	print_octets(dat, length);
539 }
540 
541 static void
542 l2tp_private_grp_id_print(const u_char *dat, u_int length)
543 {
544 	print_string(dat, length);
545 	/* XXX print_octets is more appropriate?? */
546 }
547 
548 static void
549 l2tp_rx_conn_speed_print(const u_char *dat, u_int length)
550 {
551 	print_int((u_int *)dat);
552 }
553 
554 static void
555 l2tp_seq_required_print(const u_char *dat, u_int length)
556 {
557 	return;
558 }
559 
560 static void
561 l2tp_avp_print(const u_char *dat, u_int length)
562 {
563 	u_int len;
564 	const u_short *ptr = (u_short *)dat;
565 	int hidden = FALSE;
566 
567 	printf(" ");
568 	if (length > 0 && (snapend - dat) >= 2) {
569 		/* there must be at least two octets for the length
570 		   to be decoded */
571 		if ((len = (ntohs(*ptr) & L2TP_AVP_HDR_LEN_MASK)) <=
572 		    (snapend - dat)) {
573 			if (ntohs(*ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
574 				printf("*");
575 			}
576 			if (ntohs(*ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) {
577 				hidden = TRUE;
578 				printf("?");
579 			}
580 		} else {
581 			printf("|...");
582 			return;
583 		}
584 		ptr++;
585 
586 		if (ntohs(*ptr)) {	/* IETF == 0 */
587 			printf("vendor=%04x", ntohs(*ptr));
588 		}
589 		ptr++;
590 
591 		if (ntohs(*ptr) < L2TP_MAX_AVP_INDEX) {
592 			printf("%s", l2tp_avp[ntohs(*ptr)].name);
593 			printf("(");
594 			if (!hidden && len >= 6) {
595 				(l2tp_avp[ntohs(*ptr)].print)
596 					((u_char *)ptr+2, len-6);
597 			} else {
598 				printf("???");
599 			}
600 			printf(")");
601 		} else {
602 			printf(" invalid AVP %u", ntohs(*ptr));
603 		}
604 
605 		if (length >= len && len > 0)
606 			l2tp_avp_print(dat + len, length - len);
607 	} else if (length == 0) {
608 		return;
609 	} else {
610 		printf("|...");
611 	}
612 }
613 
614 
615 void
616 l2tp_print(const u_char *dat, u_int length)
617 {
618 	u_int cnt = 0;			/* total octets consumed */
619 	u_short pad, val;
620 	int flag_t, flag_l, flag_s, flag_o, flag_p;
621 	u_short l2tp_len;
622 
623 	flag_t = flag_l = flag_s = flag_o = flag_p = FALSE;
624 
625 	if (length < 6 || snapend - dat < 6) {
626 		/* flag/ver, tunnel_id, session_id must be present for
627 		   this packet to be properly decoded */
628 		printf("%s", tstr);
629 		return;
630 	}
631 
632 	TCHECK2(*dat, sizeof(val));
633 	memcpy(&val, dat, sizeof(val));
634 	if ((ntohs(val) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
635 		printf(" l2tp:");
636 	} else if ((ntohs(val) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
637 		printf(" l2f:");
638 		return;		/* nothing to do */
639 	} else {
640 		printf(" Unknown Version, neither L2F(1) nor L2TP(2)");
641 		return;		/* nothing we can do */
642 	}
643 
644 	printf("[");
645 	if (ntohs(val) & L2TP_FLAG_TYPE) {
646 		flag_t = TRUE;
647 		printf("T");
648 	}
649 	if (ntohs(val) & L2TP_FLAG_LENGTH) {
650 		flag_l = TRUE;
651 		printf("L");
652 	}
653 	if (ntohs(val) & L2TP_FLAG_SEQUENCE) {
654 		flag_s = TRUE;
655 		printf("S");
656 	}
657 	if (ntohs(val) & L2TP_FLAG_OFFSET) {
658 		flag_o = TRUE;
659 		printf("O");
660 	}
661 	if (ntohs(val) & L2TP_FLAG_PRIORITY) {
662 		flag_p = TRUE;
663 		printf("P");
664 	}
665 	printf("]");
666 
667 	dat += 2;
668 	cnt += 2;
669 
670 	if (flag_l) {
671 		TCHECK2(*dat, sizeof(val));
672 		memcpy(&val, dat, sizeof(val));
673 		l2tp_len = ntohs(val);
674 		dat += 2;
675 		cnt += 2;
676 	} else {
677 		l2tp_len = 0;
678 	}
679 
680 	TCHECK2(*dat, sizeof(val));
681 	memcpy(&val, dat, sizeof(val));
682 	printf("(%d/", ntohs(val));		/* Tunnel ID */
683 	dat += 2;
684 	cnt += 2;
685 	TCHECK2(*dat, sizeof(val));
686 	memcpy(&val, dat, sizeof(val));
687 	printf("%d)",  ntohs(val));		/* Session ID */
688 	dat += 2;
689 	cnt += 2;
690 
691 	if (flag_s) {
692 		TCHECK2(*dat, sizeof(val));
693 		memcpy(&val, dat, sizeof(val));
694 		printf("Ns=%d,", ntohs(val));
695 		dat += 2;
696 		cnt += 2;
697 		TCHECK2(*dat, sizeof(val));
698 		memcpy(&val, dat, sizeof(val));
699 		printf("Nr=%d",  ntohs(val));
700 		dat += 2;
701 		cnt += 2;
702 	}
703 
704 	if (flag_o) {
705 		TCHECK2(*dat, sizeof(val));
706 		memcpy(&val, dat, sizeof(val));
707 		pad =  ntohs(val);
708 		dat += 2;
709 		cnt += 2;
710 		TCHECK2(*dat, pad);
711 		dat += pad;
712 		cnt += pad;
713 	}
714 
715 	if (flag_t) {
716 		if (length - cnt == 0) {
717 			printf(" ZLB");
718 		} else {
719 			if (length >= cnt)
720 				l2tp_avp_print(dat, length - cnt);
721 		}
722 	} else {
723 #if 0
724 		printf(" {");
725 		ppp_hdlc_print(dat, length - cnt);
726 		printf("}");
727 #else
728 		printf("[hdlc|]");
729 #endif
730 	}
731 
732 trunc:
733 	printf("[|l2tp]");
734 }
735