2 * Redistribution and use in source and binary forms, with or without
3 * modification, are permitted provided that: (1) source code
4 * distributions retain the above copyright notice and this paragraph
5 * in its entirety, and (2) distributions including binary code include
6 * the above copyright notice and this paragraph in its entirety in
7 * the documentation or other materials provided with the distribution.
8 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
9 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
10 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
11 * FOR A PARTICULAR PURPOSE.
13 * Original code by Hannes Gredler (hannes@juniper.net)
17 static const char rcsid
[] _U_
=
18 "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.22 2005-07-20 13:09:59 hannes Exp $ (LBL)";
25 #include <tcpdump-stdinc.h>
30 #include "interface.h"
31 #include "addrtoname.h"
36 #include "ethertype.h"
39 #define JUNIPER_BPF_OUT 0 /* Outgoing packet */
40 #define JUNIPER_BPF_IN 1 /* Incoming packet */
41 #define JUNIPER_BPF_PKT_IN 0x1 /* Incoming packet */
42 #define JUNIPER_BPF_NO_L2 0x2 /* L2 header stripped */
43 #define JUNIPER_MGC_NUMBER 0x4d4743 /* = "MGC" */
45 #define JUNIPER_LSQ_COOKIE_RE (1 << 3)
46 #define JUNIPER_LSQ_COOKIE_DIR (1 << 2)
47 #define JUNIPER_LSQ_L3_PROTO_SHIFT 4
48 #define JUNIPER_LSQ_L3_PROTO_MASK (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT)
49 #define JUNIPER_LSQ_L3_PROTO_IPV4 (0 << JUNIPER_LSQ_L3_PROTO_SHIFT)
50 #define JUNIPER_LSQ_L3_PROTO_IPV6 (1 << JUNIPER_LSQ_L3_PROTO_SHIFT)
51 #define JUNIPER_LSQ_L3_PROTO_MPLS (2 << JUNIPER_LSQ_L3_PROTO_SHIFT)
52 #define JUNIPER_LSQ_L3_PROTO_ISO (3 << JUNIPER_LSQ_L3_PROTO_SHIFT)
54 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1
55 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2
56 #define JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE 3
57 #define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4
58 #define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5
60 static struct tok juniper_ipsec_type_values
[] = {
61 { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE
, "ESP ENCR-AUTH" },
62 { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE
, "ESP ENCR-AH AUTH" },
63 { JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE
, "ESP AUTH" },
64 { JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE
, "AH AUTH" },
65 { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE
, "ESP ENCR" },
69 static struct tok juniper_direction_values
[] = {
70 { JUNIPER_BPF_IN
, "In"},
71 { JUNIPER_BPF_OUT
, "Out"},
75 struct juniper_cookie_table_t
{
76 u_int32_t pictype
; /* pic type */
77 u_int8_t cookie_len
; /* cookie len */
78 const char *s
; /* pic name */
81 static struct juniper_cookie_table_t juniper_cookie_table
[] = {
82 #ifdef DLT_JUNIPER_ATM1
83 { DLT_JUNIPER_ATM1
, 4, "ATM1"},
85 #ifdef DLT_JUNIPER_ATM2
86 { DLT_JUNIPER_ATM2
, 8, "ATM2"},
88 #ifdef DLT_JUNIPER_MLPPP
89 { DLT_JUNIPER_MLPPP
, 2, "MLPPP"},
91 #ifdef DLT_JUNIPER_MLFR
92 { DLT_JUNIPER_MLFR
, 2, "MLFR"},
94 #ifdef DLT_JUNIPER_MFR
95 { DLT_JUNIPER_MFR
, 4, "MFR"},
97 #ifdef DLT_JUNIPER_PPPOE
98 { DLT_JUNIPER_PPPOE
, 0, "PPPoE"},
100 #ifdef DLT_JUNIPER_PPPOE_ATM
101 { DLT_JUNIPER_PPPOE_ATM
, 0, "PPPoE ATM"},
103 #ifdef DLT_JUNIPER_GGSN
104 { DLT_JUNIPER_GGSN
, 8, "GGSN"},
106 #ifdef DLT_JUNIPER_MONITOR
107 { DLT_JUNIPER_MONITOR
, 8, "MONITOR"},
109 #ifdef DLT_JUNIPER_SERVICES
110 { DLT_JUNIPER_SERVICES
, 8, "AS"},
112 #ifdef DLT_JUNIPER_ES
113 { DLT_JUNIPER_ES
, 0, "ES"},
118 struct juniper_l2info_t
{
125 u_int8_t cookie_type
;
131 #define LS_COOKIE_ID 0x54
132 #define AS_COOKIE_ID 0x47
133 #define LS_MLFR_COOKIE_LEN 4
134 #define ML_MLFR_COOKIE_LEN 2
135 #define LS_MFR_COOKIE_LEN 6
136 #define ATM1_COOKIE_LEN 4
137 #define ATM2_COOKIE_LEN 8
139 #define ATM2_PKT_TYPE_MASK 0x70
140 #define ATM2_GAP_COUNT_MASK 0x3F
142 #define JUNIPER_PROTO_NULL 1
143 #define JUNIPER_PROTO_IPV4 2
144 #define JUNIPER_PROTO_IPV6 6
146 static struct tok juniper_protocol_values
[] = {
147 { JUNIPER_PROTO_NULL
, "Null" },
148 { JUNIPER_PROTO_IPV4
, "IPv4" },
149 { JUNIPER_PROTO_IPV6
, "IPv6" },
153 int ip_heuristic_guess(register const u_char
*, u_int
);
154 int juniper_ppp_heuristic_guess(register const u_char
*, u_int
);
155 static int juniper_parse_header (const u_char
*, const struct pcap_pkthdr
*, struct juniper_l2info_t
*);
157 #ifdef DLT_JUNIPER_GGSN
159 juniper_ggsn_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
161 struct juniper_l2info_t l2info
;
162 struct juniper_ggsn_header
{
170 const struct juniper_ggsn_header
*gh
;
172 l2info
.pictype
= DLT_JUNIPER_GGSN
;
173 if(juniper_parse_header(p
, h
, &l2info
) == 0)
174 return l2info
.header_len
;
176 p
+=l2info
.header_len
;
177 gh
= (struct juniper_ggsn_header
*)p
;
180 printf("proto %s (%u), vlan %u: ",
181 tok2str(juniper_protocol_values
,"Unknown",gh
->proto
),
183 EXTRACT_16BITS(&gh
->vlan_id
[0]));
186 case JUNIPER_PROTO_IPV4
:
187 ip_print(gndo
, p
, l2info
.length
);
190 case JUNIPER_PROTO_IPV6
:
191 ip6_print(p
, l2info
.length
);
196 printf("unknown GGSN proto (%u)", gh
->proto
);
199 return l2info
.header_len
;
203 #ifdef DLT_JUNIPER_ES
205 juniper_es_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
207 struct juniper_l2info_t l2info
;
208 struct juniper_ipsec_header
{
209 u_int8_t sa_index
[2];
216 u_int rewrite_len
,es_type_bundle
;
217 const struct juniper_ipsec_header
*ih
;
219 l2info
.pictype
= DLT_JUNIPER_ES
;
220 if(juniper_parse_header(p
, h
, &l2info
) == 0)
221 return l2info
.header_len
;
223 p
+=l2info
.header_len
;
224 ih
= (struct juniper_ipsec_header
*)p
;
227 case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE
:
228 case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE
:
232 case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE
:
233 case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE
:
234 case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE
:
238 printf("ES Invalid type %u, length %u",
241 return l2info
.header_len
;
244 l2info
.length
-=rewrite_len
;
248 if (!es_type_bundle
) {
249 printf("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n",
250 EXTRACT_16BITS(&ih
->sa_index
),
252 tok2str(juniper_ipsec_type_values
,"Unknown",ih
->type
),
254 EXTRACT_32BITS(&ih
->spi
),
255 ipaddr_string(EXTRACT_32BITS(&ih
->src_ip
)),
256 ipaddr_string(EXTRACT_32BITS(&ih
->dst_ip
)),
259 printf("ES SA, index %u, ttl %u type %s (%u), length %u\n",
260 EXTRACT_16BITS(&ih
->sa_index
),
262 tok2str(juniper_ipsec_type_values
,"Unknown",ih
->type
),
268 ip_print(gndo
, p
, l2info
.length
);
269 return l2info
.header_len
;
273 #ifdef DLT_JUNIPER_MONITOR
275 juniper_monitor_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
277 struct juniper_l2info_t l2info
;
278 struct juniper_monitor_header
{
282 u_int8_t service_id
[4];
284 const struct juniper_monitor_header
*mh
;
286 l2info
.pictype
= DLT_JUNIPER_MONITOR
;
287 if(juniper_parse_header(p
, h
, &l2info
) == 0)
288 return l2info
.header_len
;
290 p
+=l2info
.header_len
;
291 mh
= (struct juniper_monitor_header
*)p
;
294 printf("service-id %u, iif %u, pkt-type %u: ",
295 EXTRACT_32BITS(&mh
->service_id
),
296 EXTRACT_16BITS(&mh
->iif
),
299 /* no proto field - lets guess by first byte of IP header*/
300 ip_heuristic_guess(p
, l2info
.length
);
302 return l2info
.header_len
;
306 #ifdef DLT_JUNIPER_SERVICES
308 juniper_services_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
310 struct juniper_l2info_t l2info
;
311 struct juniper_services_header
{
314 u_int8_t svc_set_id
[2];
317 const struct juniper_services_header
*sh
;
319 l2info
.pictype
= DLT_JUNIPER_SERVICES
;
320 if(juniper_parse_header(p
, h
, &l2info
) == 0)
321 return l2info
.header_len
;
323 p
+=l2info
.header_len
;
324 sh
= (struct juniper_services_header
*)p
;
327 printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
330 EXTRACT_16BITS(&sh
->svc_set_id
),
331 EXTRACT_24BITS(&sh
->dir_iif
[1]));
333 /* no proto field - lets guess by first byte of IP header*/
334 ip_heuristic_guess(p
, l2info
.length
);
336 return l2info
.header_len
;
340 #ifdef DLT_JUNIPER_PPPOE
342 juniper_pppoe_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
344 struct juniper_l2info_t l2info
;
346 l2info
.pictype
= DLT_JUNIPER_PPPOE
;
347 if(juniper_parse_header(p
, h
, &l2info
) == 0)
348 return l2info
.header_len
;
350 p
+=l2info
.header_len
;
351 /* this DLT contains nothing but raw ethernet frames */
352 ether_print(p
, l2info
.length
, l2info
.caplen
);
353 return l2info
.header_len
;
357 #ifdef DLT_JUNIPER_PPPOE_ATM
359 juniper_pppoe_atm_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
361 struct juniper_l2info_t l2info
;
362 u_int16_t extracted_ethertype
;
364 l2info
.pictype
= DLT_JUNIPER_PPPOE_ATM
;
365 if(juniper_parse_header(p
, h
, &l2info
) == 0)
366 return l2info
.header_len
;
368 p
+=l2info
.header_len
;
370 extracted_ethertype
= EXTRACT_16BITS(p
);
371 /* this DLT contains nothing but raw PPPoE frames,
372 * prepended with a type field*/
373 if (ether_encap_print(extracted_ethertype
,
375 l2info
.length
-ETHERTYPE_LEN
,
376 l2info
.caplen
-ETHERTYPE_LEN
,
377 &extracted_ethertype
) == 0)
378 /* ether_type not known, probably it wasn't one */
379 printf("unknown ethertype 0x%04x", extracted_ethertype
);
381 return l2info
.header_len
;
385 #ifdef DLT_JUNIPER_MLPPP
387 juniper_mlppp_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
389 struct juniper_l2info_t l2info
;
391 l2info
.pictype
= DLT_JUNIPER_MLPPP
;
392 if(juniper_parse_header(p
, h
, &l2info
) == 0)
393 return l2info
.header_len
;
395 /* suppress Bundle-ID if frame was captured on a child-link
396 * best indicator if the cookie looks like a proto */
398 EXTRACT_16BITS(&l2info
.cookie
) != PPP_OSI
&&
399 EXTRACT_16BITS(&l2info
.cookie
) != (PPP_ADDRESS
<< 8 | PPP_CONTROL
))
400 printf("Bundle-ID %u: ",l2info
.bundle
);
402 p
+=l2info
.header_len
;
404 /* first try the LSQ protos */
405 switch(l2info
.proto
) {
406 case JUNIPER_LSQ_L3_PROTO_IPV4
:
407 /* IP traffic going to the RE would not have a cookie
408 * -> this must be incoming IS-IS over PPP
410 if (l2info
.cookie
[4] == (JUNIPER_LSQ_COOKIE_RE
|JUNIPER_LSQ_COOKIE_DIR
))
411 ppp_print(p
, l2info
.length
);
413 ip_print(gndo
, p
, l2info
.length
);
414 return l2info
.header_len
;
416 case JUNIPER_LSQ_L3_PROTO_IPV6
:
417 ip6_print(p
,l2info
.length
);
418 return l2info
.header_len
;
420 case JUNIPER_LSQ_L3_PROTO_MPLS
:
421 mpls_print(p
,l2info
.length
);
422 return l2info
.header_len
;
423 case JUNIPER_LSQ_L3_PROTO_ISO
:
424 isoclns_print(p
,l2info
.length
,l2info
.caplen
);
425 return l2info
.header_len
;
430 /* zero length cookie ? */
431 switch (EXTRACT_16BITS(&l2info
.cookie
)) {
433 ppp_print(p
-2,l2info
.length
+2);
435 case (PPP_ADDRESS
<< 8 | PPP_CONTROL
): /* fall through */
437 ppp_print(p
,l2info
.length
);
441 return l2info
.header_len
;
446 #ifdef DLT_JUNIPER_MFR
448 juniper_mfr_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
450 struct juniper_l2info_t l2info
;
452 l2info
.pictype
= DLT_JUNIPER_MFR
;
453 if(juniper_parse_header(p
, h
, &l2info
) == 0)
454 return l2info
.header_len
;
456 p
+=l2info
.header_len
;
457 /* suppress Bundle-ID if frame was captured on a child-link */
458 if (eflag
&& EXTRACT_32BITS(l2info
.cookie
) != 1) printf("Bundle-ID %u, ",l2info
.bundle
);
459 switch (l2info
.proto
) {
460 case (LLCSAP_ISONS
<<8 | LLCSAP_ISONS
):
461 isoclns_print(p
+1, l2info
.length
-1, l2info
.caplen
-1);
463 case (LLC_UI
<<8 | NLPID_Q933
):
464 case (LLC_UI
<<8 | NLPID_IP
):
465 case (LLC_UI
<<8 | NLPID_IP6
):
466 /* pass IP{4,6} to the OSI layer for proper link-layer printing */
467 isoclns_print(p
-1, l2info
.length
+1, l2info
.caplen
+1);
470 printf("unknown protocol 0x%04x, length %u",l2info
.proto
, l2info
.length
);
473 return l2info
.header_len
;
477 #ifdef DLT_JUNIPER_MLFR
479 juniper_mlfr_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
481 struct juniper_l2info_t l2info
;
483 l2info
.pictype
= DLT_JUNIPER_MLFR
;
484 if(juniper_parse_header(p
, h
, &l2info
) == 0)
485 return l2info
.header_len
;
487 p
+=l2info
.header_len
;
489 /* suppress Bundle-ID if frame was captured on a child-link */
490 if (eflag
&& EXTRACT_32BITS(l2info
.cookie
) != 1) printf("Bundle-ID %u, ",l2info
.bundle
);
491 switch (l2info
.proto
) {
494 isoclns_print(p
, l2info
.length
, l2info
.caplen
);
496 case (LLC_UI
<<8 | NLPID_Q933
):
497 case (LLC_UI
<<8 | NLPID_IP
):
498 case (LLC_UI
<<8 | NLPID_IP6
):
499 /* pass IP{4,6} to the OSI layer for proper link-layer printing */
500 isoclns_print(p
-1, l2info
.length
+1, l2info
.caplen
+1);
503 printf("unknown protocol 0x%04x, length %u",l2info
.proto
, l2info
.length
);
506 return l2info
.header_len
;
511 * ATM1 PIC cookie format
513 * +-----+-------------------------+-------------------------------+
514 * |fmtid| vc index | channel ID |
515 * +-----+-------------------------+-------------------------------+
518 #ifdef DLT_JUNIPER_ATM1
520 juniper_atm1_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
522 u_int16_t extracted_ethertype
;
524 struct juniper_l2info_t l2info
;
526 l2info
.pictype
= DLT_JUNIPER_ATM1
;
527 if(juniper_parse_header(p
, h
, &l2info
) == 0)
528 return l2info
.header_len
;
530 p
+=l2info
.header_len
;
532 if (l2info
.cookie
[0] == 0x80) { /* OAM cell ? */
533 oam_print(p
,l2info
.length
,ATM_OAM_NOHEC
);
534 return l2info
.header_len
;
537 if (EXTRACT_24BITS(p
) == 0xfefe03 || /* NLPID encaps ? */
538 EXTRACT_24BITS(p
) == 0xaaaa03) { /* SNAP encaps ? */
540 if (llc_print(p
, l2info
.length
, l2info
.caplen
, NULL
, NULL
,
541 &extracted_ethertype
) != 0)
542 return l2info
.header_len
;
545 if (p
[0] == 0x03) { /* Cisco style NLPID encaps ? */
546 isoclns_print(p
+ 1, l2info
.length
- 1, l2info
.caplen
- 1);
547 /* FIXME check if frame was recognized */
548 return l2info
.header_len
;
551 if(ip_heuristic_guess(p
, l2info
.length
) != 0) /* last try - vcmux encaps ? */
552 return l2info
.header_len
;
554 return l2info
.header_len
;
559 * ATM2 PIC cookie format
561 * +-------------------------------+---------+---+-----+-----------+
562 * | channel ID | reserv |AAL| CCRQ| gap cnt |
563 * +-------------------------------+---------+---+-----+-----------+
566 #ifdef DLT_JUNIPER_ATM2
568 juniper_atm2_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
570 u_int16_t extracted_ethertype
;
571 u_int32_t control_word
;
573 struct juniper_l2info_t l2info
;
575 l2info
.pictype
= DLT_JUNIPER_ATM2
;
576 if(juniper_parse_header(p
, h
, &l2info
) == 0)
577 return l2info
.header_len
;
579 p
+=l2info
.header_len
;
581 if (l2info
.cookie
[7] & ATM2_PKT_TYPE_MASK
) { /* OAM cell ? */
582 control_word
= EXTRACT_32BITS(p
);
583 if(control_word
== 0 || control_word
== 0x08000000) {
584 l2info
.header_len
+= 4;
588 oam_print(p
,l2info
.length
,ATM_OAM_NOHEC
);
589 return l2info
.header_len
;
592 if (EXTRACT_24BITS(p
) == 0xfefe03 || /* NLPID encaps ? */
593 EXTRACT_24BITS(p
) == 0xaaaa03) { /* SNAP encaps ? */
595 if (llc_print(p
, l2info
.length
, l2info
.caplen
, NULL
, NULL
,
596 &extracted_ethertype
) != 0)
597 return l2info
.header_len
;
600 if (l2info
.direction
!= JUNIPER_BPF_PKT_IN
&& /* ether-over-1483 encaps ? */
601 (EXTRACT_32BITS(l2info
.cookie
) & ATM2_GAP_COUNT_MASK
)) {
602 ether_print(p
, l2info
.length
, l2info
.caplen
);
603 return l2info
.header_len
;
606 if (p
[0] == 0x03) { /* Cisco style NLPID encaps ? */
607 isoclns_print(p
+ 1, l2info
.length
- 1, l2info
.caplen
- 1);
608 /* FIXME check if frame was recognized */
609 return l2info
.header_len
;
612 if(juniper_ppp_heuristic_guess(p
, l2info
.length
) != 0) /* PPPoA vcmux encaps ? */
613 return l2info
.header_len
;
615 if(ip_heuristic_guess(p
, l2info
.length
) != 0) /* last try - vcmux encaps ? */
616 return l2info
.header_len
;
618 return l2info
.header_len
;
623 /* try to guess, based on all PPP protos that are supported in
624 * a juniper router if the payload data is encapsulated using PPP */
626 juniper_ppp_heuristic_guess(register const u_char
*p
, u_int length
) {
628 switch(EXTRACT_16BITS(p
)) {
631 case PPP_MPLS_UCAST
:
632 case PPP_MPLS_MCAST
:
644 ppp_print(p
, length
);
648 return 0; /* did not find a ppp header */
651 return 1; /* we printed a ppp packet */
655 ip_heuristic_guess(register const u_char
*p
, u_int length
) {
669 ip_print(gndo
, p
, length
);
688 ip6_print(p
, length
);
692 return 0; /* did not find a ip header */
695 return 1; /* we printed an v4/v6 packet */
699 juniper_parse_header (const u_char
*p
, const struct pcap_pkthdr
*h
, struct juniper_l2info_t
*l2info
) {
701 struct juniper_cookie_table_t
*lp
= juniper_cookie_table
;
704 l2info
->header_len
= 0;
705 l2info
->cookie_len
= 0;
709 l2info
->length
= h
->len
;
710 l2info
->caplen
= h
->caplen
;
711 l2info
->direction
= p
[3]&JUNIPER_BPF_PKT_IN
;
714 if (EXTRACT_24BITS(p
) != JUNIPER_MGC_NUMBER
) /* magic number found ? */
717 l2info
->header_len
= 4;
719 if (eflag
) /* print direction */
720 printf("%3s ",tok2str(juniper_direction_values
,"---",l2info
->direction
));
722 if ((p
[3] & JUNIPER_BPF_NO_L2
) == JUNIPER_BPF_NO_L2
) {
724 printf("no-L2-hdr, ");
726 /* there is no link-layer present -
727 * perform the v4/v6 heuristics
728 * to figure out what it is
731 if(ip_heuristic_guess(p
+8,l2info
->length
-8) == 0)
732 printf("no IP-hdr found!");
734 l2info
->header_len
+=4;
735 return 0; /* stop parsing the output further */
739 p
+=l2info
->header_len
;
740 l2info
->length
-= l2info
->header_len
;
741 l2info
->caplen
-= l2info
->header_len
;
743 /* search through the cookie table and copy values matching for our PIC type */
744 while (lp
->s
!= NULL
) {
745 if (lp
->pictype
== l2info
->pictype
) {
747 l2info
->cookie_len
= lp
->cookie_len
;
748 l2info
->header_len
+= lp
->cookie_len
;
752 l2info
->cookie_type
= LS_COOKIE_ID
;
753 l2info
->cookie_len
+= 2;
754 l2info
->header_len
+= 2;
757 l2info
->cookie_type
= AS_COOKIE_ID
;
758 l2info
->cookie_len
+= 6;
759 l2info
->header_len
+= 6;
763 l2info
->bundle
= l2info
->cookie
[0];
768 printf("%s-PIC, cookie-len %u",
772 if (l2info
->cookie_len
> 0) {
773 TCHECK2(p
[0],l2info
->cookie_len
);
775 printf(", cookie 0x");
776 for (idx
= 0; idx
< l2info
->cookie_len
; idx
++) {
777 l2info
->cookie
[idx
] = p
[idx
]; /* copy cookie data */
778 if (eflag
) printf("%02x",p
[idx
]);
782 if (eflag
) printf(": "); /* print demarc b/w L2/L3*/
785 l2info
->proto
= EXTRACT_16BITS(p
+l2info
->cookie_len
);
790 p
+=l2info
->cookie_len
;
792 /* DLT_ specific parsing */
793 switch(l2info
->pictype
) {
794 case DLT_JUNIPER_MLPPP
:
795 switch (l2info
->cookie_type
) {
797 l2info
->bundle
= l2info
->cookie
[1];
800 l2info
->bundle
= (EXTRACT_16BITS(&l2info
->cookie
[6])>>3)&0xfff;
801 l2info
->proto
= (l2info
->cookie
[5])&JUNIPER_LSQ_L3_PROTO_MASK
;
804 l2info
->bundle
= l2info
->cookie
[0];
808 case DLT_JUNIPER_MLFR
: /* fall through */
809 case DLT_JUNIPER_MFR
:
810 switch (l2info
->cookie_type
) {
812 l2info
->bundle
= l2info
->cookie
[1];
815 l2info
->bundle
= (EXTRACT_16BITS(&l2info
->cookie
[6])>>3)&0xfff;
818 l2info
->bundle
= l2info
->cookie
[0];
821 l2info
->proto
= EXTRACT_16BITS(p
);
822 l2info
->header_len
+= 2;
826 case DLT_JUNIPER_ATM2
:
828 /* ATM cell relay control word present ? */
829 if (l2info
->cookie
[7] & ATM2_PKT_TYPE_MASK
&& *p
& 0x08) {
830 l2info
->header_len
+= 4;
832 printf("control-word 0x%08x ",EXTRACT_32BITS(p
));
835 case DLT_JUNIPER_ATM1
:
841 printf("hlen %u, proto 0x%04x, ",l2info
->header_len
,l2info
->proto
);
843 return 1; /* everything went ok so far. continue parsing */
845 printf("[|juniper_hdr], length %u",h
->len
);
852 * c-style: whitesmith