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