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