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.8.2.22 2006/05/10 22:42:46 guy 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_BPF_EXT 0x80 /* extensions present */
44 #define JUNIPER_MGC_NUMBER 0x4d4743 /* = "MGC" */
46 #define JUNIPER_LSQ_COOKIE_RE (1 << 3)
47 #define JUNIPER_LSQ_COOKIE_DIR (1 << 2)
48 #define JUNIPER_LSQ_L3_PROTO_SHIFT 4
49 #define JUNIPER_LSQ_L3_PROTO_MASK (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT)
50 #define JUNIPER_LSQ_L3_PROTO_IPV4 (0 << JUNIPER_LSQ_L3_PROTO_SHIFT)
51 #define JUNIPER_LSQ_L3_PROTO_IPV6 (1 << JUNIPER_LSQ_L3_PROTO_SHIFT)
52 #define JUNIPER_LSQ_L3_PROTO_MPLS (2 << JUNIPER_LSQ_L3_PROTO_SHIFT)
53 #define JUNIPER_LSQ_L3_PROTO_ISO (3 << JUNIPER_LSQ_L3_PROTO_SHIFT)
54 #define AS_PIC_COOKIE_LEN 8
56 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1
57 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2
58 #define JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE 3
59 #define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4
60 #define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5
62 static struct tok juniper_ipsec_type_values
[] = {
63 { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE
, "ESP ENCR-AUTH" },
64 { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE
, "ESP ENCR-AH AUTH" },
65 { JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE
, "ESP AUTH" },
66 { JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE
, "AH AUTH" },
67 { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE
, "ESP ENCR" },
71 static struct tok juniper_direction_values
[] = {
72 { JUNIPER_BPF_IN
, "In"},
73 { JUNIPER_BPF_OUT
, "Out"},
77 struct juniper_cookie_table_t
{
78 u_int32_t pictype
; /* pic type */
79 u_int8_t cookie_len
; /* cookie len */
80 const char *s
; /* pic name */
83 static struct juniper_cookie_table_t juniper_cookie_table
[] = {
84 #ifdef DLT_JUNIPER_ATM1
85 { DLT_JUNIPER_ATM1
, 4, "ATM1"},
87 #ifdef DLT_JUNIPER_ATM2
88 { DLT_JUNIPER_ATM2
, 8, "ATM2"},
90 #ifdef DLT_JUNIPER_MLPPP
91 { DLT_JUNIPER_MLPPP
, 2, "MLPPP"},
93 #ifdef DLT_JUNIPER_MLFR
94 { DLT_JUNIPER_MLFR
, 2, "MLFR"},
96 #ifdef DLT_JUNIPER_MFR
97 { DLT_JUNIPER_MFR
, 4, "MFR"},
99 #ifdef DLT_JUNIPER_PPPOE
100 { DLT_JUNIPER_PPPOE
, 0, "PPPoE"},
102 #ifdef DLT_JUNIPER_PPPOE_ATM
103 { DLT_JUNIPER_PPPOE_ATM
, 0, "PPPoE ATM"},
105 #ifdef DLT_JUNIPER_GGSN
106 { DLT_JUNIPER_GGSN
, 8, "GGSN"},
108 #ifdef DLT_JUNIPER_MONITOR
109 { DLT_JUNIPER_MONITOR
, 8, "MONITOR"},
111 #ifdef DLT_JUNIPER_SERVICES
112 { DLT_JUNIPER_SERVICES
, 8, "AS"},
114 #ifdef DLT_JUNIPER_ES
115 { DLT_JUNIPER_ES
, 0, "ES"},
120 struct juniper_l2info_t
{
127 u_int8_t cookie_type
;
133 #define LS_COOKIE_ID 0x54
134 #define AS_COOKIE_ID 0x47
135 #define LS_MLFR_COOKIE_LEN 4
136 #define ML_MLFR_COOKIE_LEN 2
137 #define LS_MFR_COOKIE_LEN 6
138 #define ATM1_COOKIE_LEN 4
139 #define ATM2_COOKIE_LEN 8
141 #define ATM2_PKT_TYPE_MASK 0x70
142 #define ATM2_GAP_COUNT_MASK 0x3F
144 #define JUNIPER_PROTO_NULL 1
145 #define JUNIPER_PROTO_IPV4 2
146 #define JUNIPER_PROTO_IPV6 6
148 #define MFR_BE_MASK 0xc0
150 static struct tok juniper_protocol_values
[] = {
151 { JUNIPER_PROTO_NULL
, "Null" },
152 { JUNIPER_PROTO_IPV4
, "IPv4" },
153 { JUNIPER_PROTO_IPV6
, "IPv6" },
157 int ip_heuristic_guess(register const u_char
*, u_int
);
158 int juniper_ppp_heuristic_guess(register const u_char
*, u_int
);
159 static int juniper_parse_header (const u_char
*, const struct pcap_pkthdr
*, struct juniper_l2info_t
*);
161 #ifdef DLT_JUNIPER_GGSN
163 juniper_ggsn_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
165 struct juniper_l2info_t l2info
;
166 struct juniper_ggsn_header
{
174 const struct juniper_ggsn_header
*gh
;
176 l2info
.pictype
= DLT_JUNIPER_GGSN
;
177 if(juniper_parse_header(p
, h
, &l2info
) == 0)
178 return l2info
.header_len
;
180 p
+=l2info
.header_len
;
181 gh
= (struct juniper_ggsn_header
*)p
;
184 printf("proto %s (%u), vlan %u: ",
185 tok2str(juniper_protocol_values
,"Unknown",gh
->proto
),
187 EXTRACT_16BITS(&gh
->vlan_id
[0]));
190 case JUNIPER_PROTO_IPV4
:
191 ip_print(gndo
, p
, l2info
.length
);
194 case JUNIPER_PROTO_IPV6
:
195 ip6_print(p
, l2info
.length
);
200 printf("unknown GGSN proto (%u)", gh
->proto
);
203 return l2info
.header_len
;
207 #ifdef DLT_JUNIPER_ES
209 juniper_es_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
211 struct juniper_l2info_t l2info
;
212 struct juniper_ipsec_header
{
213 u_int8_t sa_index
[2];
220 u_int rewrite_len
,es_type_bundle
;
221 const struct juniper_ipsec_header
*ih
;
223 l2info
.pictype
= DLT_JUNIPER_ES
;
224 if(juniper_parse_header(p
, h
, &l2info
) == 0)
225 return l2info
.header_len
;
227 p
+=l2info
.header_len
;
228 ih
= (struct juniper_ipsec_header
*)p
;
231 case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE
:
232 case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE
:
236 case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE
:
237 case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE
:
238 case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE
:
242 printf("ES Invalid type %u, length %u",
245 return l2info
.header_len
;
248 l2info
.length
-=rewrite_len
;
252 if (!es_type_bundle
) {
253 printf("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n",
254 EXTRACT_16BITS(&ih
->sa_index
),
256 tok2str(juniper_ipsec_type_values
,"Unknown",ih
->type
),
258 EXTRACT_32BITS(&ih
->spi
),
259 ipaddr_string(EXTRACT_32BITS(&ih
->src_ip
)),
260 ipaddr_string(EXTRACT_32BITS(&ih
->dst_ip
)),
263 printf("ES SA, index %u, ttl %u type %s (%u), length %u\n",
264 EXTRACT_16BITS(&ih
->sa_index
),
266 tok2str(juniper_ipsec_type_values
,"Unknown",ih
->type
),
272 ip_print(gndo
, p
, l2info
.length
);
273 return l2info
.header_len
;
277 #ifdef DLT_JUNIPER_MONITOR
279 juniper_monitor_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
281 struct juniper_l2info_t l2info
;
282 struct juniper_monitor_header
{
286 u_int8_t service_id
[4];
288 const struct juniper_monitor_header
*mh
;
290 l2info
.pictype
= DLT_JUNIPER_MONITOR
;
291 if(juniper_parse_header(p
, h
, &l2info
) == 0)
292 return l2info
.header_len
;
294 p
+=l2info
.header_len
;
295 mh
= (struct juniper_monitor_header
*)p
;
298 printf("service-id %u, iif %u, pkt-type %u: ",
299 EXTRACT_32BITS(&mh
->service_id
),
300 EXTRACT_16BITS(&mh
->iif
),
303 /* no proto field - lets guess by first byte of IP header*/
304 ip_heuristic_guess(p
, l2info
.length
);
306 return l2info
.header_len
;
310 #ifdef DLT_JUNIPER_SERVICES
312 juniper_services_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
314 struct juniper_l2info_t l2info
;
315 struct juniper_services_header
{
318 u_int8_t svc_set_id
[2];
321 const struct juniper_services_header
*sh
;
323 l2info
.pictype
= DLT_JUNIPER_SERVICES
;
324 if(juniper_parse_header(p
, h
, &l2info
) == 0)
325 return l2info
.header_len
;
327 p
+=l2info
.header_len
;
328 sh
= (struct juniper_services_header
*)p
;
331 printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
334 EXTRACT_16BITS(&sh
->svc_set_id
),
335 EXTRACT_24BITS(&sh
->dir_iif
[1]));
337 /* no proto field - lets guess by first byte of IP header*/
338 ip_heuristic_guess(p
, l2info
.length
);
340 return l2info
.header_len
;
344 #ifdef DLT_JUNIPER_PPPOE
346 juniper_pppoe_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
348 struct juniper_l2info_t l2info
;
350 l2info
.pictype
= DLT_JUNIPER_PPPOE
;
351 if(juniper_parse_header(p
, h
, &l2info
) == 0)
352 return l2info
.header_len
;
354 p
+=l2info
.header_len
;
355 /* this DLT contains nothing but raw ethernet frames */
356 ether_print(p
, l2info
.length
, l2info
.caplen
);
357 return l2info
.header_len
;
361 #ifdef DLT_JUNIPER_ETHER
363 juniper_ether_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
365 struct juniper_l2info_t l2info
;
367 l2info
.pictype
= DLT_JUNIPER_ETHER
;
368 if(juniper_parse_header(p
, h
, &l2info
) == 0)
369 return l2info
.header_len
;
371 p
+=l2info
.header_len
;
372 /* this DLT contains nothing but raw Ethernet frames */
373 ether_print(p
, l2info
.length
, l2info
.caplen
);
374 return l2info
.header_len
;
378 #ifdef DLT_JUNIPER_PPP
380 juniper_ppp_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
382 struct juniper_l2info_t l2info
;
384 l2info
.pictype
= DLT_JUNIPER_PPP
;
385 if(juniper_parse_header(p
, h
, &l2info
) == 0)
386 return l2info
.header_len
;
388 p
+=l2info
.header_len
;
389 /* this DLT contains nothing but raw ppp frames */
390 ppp_print(p
, l2info
.length
);
391 return l2info
.header_len
;
395 #ifdef DLT_JUNIPER_FRELAY
397 juniper_frelay_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
399 struct juniper_l2info_t l2info
;
401 l2info
.pictype
= DLT_JUNIPER_FRELAY
;
402 if(juniper_parse_header(p
, h
, &l2info
) == 0)
403 return l2info
.header_len
;
405 p
+=l2info
.header_len
;
406 /* this DLT contains nothing but raw frame-relay frames */
407 fr_print(p
, l2info
.length
);
408 return l2info
.header_len
;
412 #ifdef DLT_JUNIPER_CHDLC
414 juniper_chdlc_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
416 struct juniper_l2info_t l2info
;
418 l2info
.pictype
= DLT_JUNIPER_CHDLC
;
419 if(juniper_parse_header(p
, h
, &l2info
) == 0)
420 return l2info
.header_len
;
422 p
+=l2info
.header_len
;
423 /* this DLT contains nothing but raw c-hdlc frames */
424 chdlc_print(p
, l2info
.length
);
425 return l2info
.header_len
;
429 #ifdef DLT_JUNIPER_PPPOE_ATM
431 juniper_pppoe_atm_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
433 struct juniper_l2info_t l2info
;
434 u_int16_t extracted_ethertype
;
436 l2info
.pictype
= DLT_JUNIPER_PPPOE_ATM
;
437 if(juniper_parse_header(p
, h
, &l2info
) == 0)
438 return l2info
.header_len
;
440 p
+=l2info
.header_len
;
442 extracted_ethertype
= EXTRACT_16BITS(p
);
443 /* this DLT contains nothing but raw PPPoE frames,
444 * prepended with a type field*/
445 if (ether_encap_print(extracted_ethertype
,
447 l2info
.length
-ETHERTYPE_LEN
,
448 l2info
.caplen
-ETHERTYPE_LEN
,
449 &extracted_ethertype
) == 0)
450 /* ether_type not known, probably it wasn't one */
451 printf("unknown ethertype 0x%04x", extracted_ethertype
);
453 return l2info
.header_len
;
457 #ifdef DLT_JUNIPER_MLPPP
459 juniper_mlppp_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
461 struct juniper_l2info_t l2info
;
463 l2info
.pictype
= DLT_JUNIPER_MLPPP
;
464 if(juniper_parse_header(p
, h
, &l2info
) == 0)
465 return l2info
.header_len
;
467 /* suppress Bundle-ID if frame was captured on a child-link
468 * best indicator if the cookie looks like a proto */
470 EXTRACT_16BITS(&l2info
.cookie
) != PPP_OSI
&&
471 EXTRACT_16BITS(&l2info
.cookie
) != (PPP_ADDRESS
<< 8 | PPP_CONTROL
))
472 printf("Bundle-ID %u: ",l2info
.bundle
);
474 p
+=l2info
.header_len
;
476 /* first try the LSQ protos */
477 switch(l2info
.proto
) {
478 case JUNIPER_LSQ_L3_PROTO_IPV4
:
479 /* IP traffic going to the RE would not have a cookie
480 * -> this must be incoming IS-IS over PPP
482 if (l2info
.cookie
[4] == (JUNIPER_LSQ_COOKIE_RE
|JUNIPER_LSQ_COOKIE_DIR
))
483 ppp_print(p
, l2info
.length
);
485 ip_print(gndo
, p
, l2info
.length
);
486 return l2info
.header_len
;
488 case JUNIPER_LSQ_L3_PROTO_IPV6
:
489 ip6_print(p
,l2info
.length
);
490 return l2info
.header_len
;
492 case JUNIPER_LSQ_L3_PROTO_MPLS
:
493 mpls_print(p
,l2info
.length
);
494 return l2info
.header_len
;
495 case JUNIPER_LSQ_L3_PROTO_ISO
:
496 isoclns_print(p
,l2info
.length
,l2info
.caplen
);
497 return l2info
.header_len
;
502 /* zero length cookie ? */
503 switch (EXTRACT_16BITS(&l2info
.cookie
)) {
505 ppp_print(p
-2,l2info
.length
+2);
507 case (PPP_ADDRESS
<< 8 | PPP_CONTROL
): /* fall through */
509 ppp_print(p
,l2info
.length
);
513 return l2info
.header_len
;
518 #ifdef DLT_JUNIPER_MFR
520 juniper_mfr_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
522 struct juniper_l2info_t l2info
;
524 l2info
.pictype
= DLT_JUNIPER_MFR
;
525 if(juniper_parse_header(p
, h
, &l2info
) == 0)
526 return l2info
.header_len
;
528 p
+=l2info
.header_len
;
531 if (l2info
.cookie_len
== 0) {
532 mfr_print(p
,l2info
.length
);
533 return l2info
.header_len
;
536 /* first try the LSQ protos */
537 if (l2info
.cookie_len
== AS_PIC_COOKIE_LEN
) {
538 switch(l2info
.proto
) {
539 case JUNIPER_LSQ_L3_PROTO_IPV4
:
540 ip_print(gndo
, p
, l2info
.length
);
541 return l2info
.header_len
;
543 case JUNIPER_LSQ_L3_PROTO_IPV6
:
544 ip6_print(p
,l2info
.length
);
545 return l2info
.header_len
;
547 case JUNIPER_LSQ_L3_PROTO_MPLS
:
548 mpls_print(p
,l2info
.length
);
549 return l2info
.header_len
;
550 case JUNIPER_LSQ_L3_PROTO_ISO
:
551 isoclns_print(p
,l2info
.length
,l2info
.caplen
);
552 return l2info
.header_len
;
556 return l2info
.header_len
;
559 /* suppress Bundle-ID if frame was captured on a child-link */
560 if (eflag
&& EXTRACT_32BITS(l2info
.cookie
) != 1) printf("Bundle-ID %u, ",l2info
.bundle
);
561 switch (l2info
.proto
) {
562 case (LLCSAP_ISONS
<<8 | LLCSAP_ISONS
):
563 isoclns_print(p
+1, l2info
.length
-1, l2info
.caplen
-1);
565 case (LLC_UI
<<8 | NLPID_Q933
):
566 case (LLC_UI
<<8 | NLPID_IP
):
567 case (LLC_UI
<<8 | NLPID_IP6
):
568 /* pass IP{4,6} to the OSI layer for proper link-layer printing */
569 isoclns_print(p
-1, l2info
.length
+1, l2info
.caplen
+1);
572 printf("unknown protocol 0x%04x, length %u",l2info
.proto
, l2info
.length
);
575 return l2info
.header_len
;
579 #ifdef DLT_JUNIPER_MLFR
581 juniper_mlfr_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
583 struct juniper_l2info_t l2info
;
585 l2info
.pictype
= DLT_JUNIPER_MLFR
;
586 if(juniper_parse_header(p
, h
, &l2info
) == 0)
587 return l2info
.header_len
;
589 p
+=l2info
.header_len
;
591 /* suppress Bundle-ID if frame was captured on a child-link */
592 if (eflag
&& EXTRACT_32BITS(l2info
.cookie
) != 1) printf("Bundle-ID %u, ",l2info
.bundle
);
593 switch (l2info
.proto
) {
596 isoclns_print(p
, l2info
.length
, l2info
.caplen
);
598 case (LLC_UI
<<8 | NLPID_Q933
):
599 case (LLC_UI
<<8 | NLPID_IP
):
600 case (LLC_UI
<<8 | NLPID_IP6
):
601 /* pass IP{4,6} to the OSI layer for proper link-layer printing */
602 isoclns_print(p
-1, l2info
.length
+1, l2info
.caplen
+1);
605 printf("unknown protocol 0x%04x, length %u",l2info
.proto
, l2info
.length
);
608 return l2info
.header_len
;
613 * ATM1 PIC cookie format
615 * +-----+-------------------------+-------------------------------+
616 * |fmtid| vc index | channel ID |
617 * +-----+-------------------------+-------------------------------+
620 #ifdef DLT_JUNIPER_ATM1
622 juniper_atm1_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
624 u_int16_t extracted_ethertype
;
626 struct juniper_l2info_t l2info
;
628 l2info
.pictype
= DLT_JUNIPER_ATM1
;
629 if(juniper_parse_header(p
, h
, &l2info
) == 0)
630 return l2info
.header_len
;
632 p
+=l2info
.header_len
;
634 if (l2info
.cookie
[0] == 0x80) { /* OAM cell ? */
635 oam_print(p
,l2info
.length
,ATM_OAM_NOHEC
);
636 return l2info
.header_len
;
639 if (EXTRACT_24BITS(p
) == 0xfefe03 || /* NLPID encaps ? */
640 EXTRACT_24BITS(p
) == 0xaaaa03) { /* SNAP encaps ? */
642 if (llc_print(p
, l2info
.length
, l2info
.caplen
, NULL
, NULL
,
643 &extracted_ethertype
) != 0)
644 return l2info
.header_len
;
647 if (p
[0] == 0x03) { /* Cisco style NLPID encaps ? */
648 isoclns_print(p
+ 1, l2info
.length
- 1, l2info
.caplen
- 1);
649 /* FIXME check if frame was recognized */
650 return l2info
.header_len
;
653 if(ip_heuristic_guess(p
, l2info
.length
) != 0) /* last try - vcmux encaps ? */
654 return l2info
.header_len
;
656 return l2info
.header_len
;
661 * ATM2 PIC cookie format
663 * +-------------------------------+---------+---+-----+-----------+
664 * | channel ID | reserv |AAL| CCRQ| gap cnt |
665 * +-------------------------------+---------+---+-----+-----------+
668 #ifdef DLT_JUNIPER_ATM2
670 juniper_atm2_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
672 u_int16_t extracted_ethertype
;
674 struct juniper_l2info_t l2info
;
676 l2info
.pictype
= DLT_JUNIPER_ATM2
;
677 if(juniper_parse_header(p
, h
, &l2info
) == 0)
678 return l2info
.header_len
;
680 p
+=l2info
.header_len
;
682 if (l2info
.cookie
[7] & ATM2_PKT_TYPE_MASK
) { /* OAM cell ? */
683 oam_print(p
,l2info
.length
,ATM_OAM_NOHEC
);
684 return l2info
.header_len
;
687 if (EXTRACT_24BITS(p
) == 0xfefe03 || /* NLPID encaps ? */
688 EXTRACT_24BITS(p
) == 0xaaaa03) { /* SNAP encaps ? */
690 if (llc_print(p
, l2info
.length
, l2info
.caplen
, NULL
, NULL
,
691 &extracted_ethertype
) != 0)
692 return l2info
.header_len
;
695 if (l2info
.direction
!= JUNIPER_BPF_PKT_IN
&& /* ether-over-1483 encaps ? */
696 (EXTRACT_32BITS(l2info
.cookie
) & ATM2_GAP_COUNT_MASK
)) {
697 ether_print(p
, l2info
.length
, l2info
.caplen
);
698 return l2info
.header_len
;
701 if (p
[0] == 0x03) { /* Cisco style NLPID encaps ? */
702 isoclns_print(p
+ 1, l2info
.length
- 1, l2info
.caplen
- 1);
703 /* FIXME check if frame was recognized */
704 return l2info
.header_len
;
707 if(juniper_ppp_heuristic_guess(p
, l2info
.length
) != 0) /* PPPoA vcmux encaps ? */
708 return l2info
.header_len
;
710 if(ip_heuristic_guess(p
, l2info
.length
) != 0) /* last try - vcmux encaps ? */
711 return l2info
.header_len
;
713 return l2info
.header_len
;
718 /* try to guess, based on all PPP protos that are supported in
719 * a juniper router if the payload data is encapsulated using PPP */
721 juniper_ppp_heuristic_guess(register const u_char
*p
, u_int length
) {
723 switch(EXTRACT_16BITS(p
)) {
726 case PPP_MPLS_UCAST
:
727 case PPP_MPLS_MCAST
:
739 ppp_print(p
, length
);
743 return 0; /* did not find a ppp header */
746 return 1; /* we printed a ppp packet */
750 ip_heuristic_guess(register const u_char
*p
, u_int length
) {
764 ip_print(gndo
, p
, length
);
783 ip6_print(p
, length
);
787 return 0; /* did not find a ip header */
790 return 1; /* we printed an v4/v6 packet */
794 juniper_parse_header (const u_char
*p
, const struct pcap_pkthdr
*h
, struct juniper_l2info_t
*l2info
) {
796 struct juniper_cookie_table_t
*lp
= juniper_cookie_table
;
798 #ifdef DLT_JUNIPER_ATM2
799 u_int32_t control_word
;
802 l2info
->header_len
= 0;
803 l2info
->cookie_len
= 0;
807 l2info
->length
= h
->len
;
808 l2info
->caplen
= h
->caplen
;
809 l2info
->direction
= p
[3]&JUNIPER_BPF_PKT_IN
;
812 if (EXTRACT_24BITS(p
) != JUNIPER_MGC_NUMBER
) { /* magic number found ? */
813 printf("no magic-number found!");
817 if (eflag
) /* print direction */
818 printf("%3s ",tok2str(juniper_direction_values
,"---",l2info
->direction
));
820 /* extensions present ? - calculate how much bytes to skip */
821 if ((p
[3] & JUNIPER_BPF_EXT
) == JUNIPER_BPF_EXT
) {
822 offset
= 6 + EXTRACT_16BITS(p
+4);
824 printf("ext-len %u, ",EXTRACT_16BITS(p
+4));
828 if ((p
[3] & JUNIPER_BPF_NO_L2
) == JUNIPER_BPF_NO_L2
) {
830 printf("no-L2-hdr, ");
832 /* there is no link-layer present -
833 * perform the v4/v6 heuristics
834 * to figure out what it is
836 TCHECK2(p
[offset
+4],1);
837 if(ip_heuristic_guess(p
+offset
+4,l2info
->length
-(offset
+4)) == 0)
838 printf("no IP-hdr found!");
840 l2info
->header_len
=offset
+4;
841 return 0; /* stop parsing the output further */
844 l2info
->header_len
= offset
;
845 p
+=l2info
->header_len
;
846 l2info
->length
-= l2info
->header_len
;
847 l2info
->caplen
-= l2info
->header_len
;
849 /* search through the cookie table and copy values matching for our PIC type */
850 while (lp
->s
!= NULL
) {
851 if (lp
->pictype
== l2info
->pictype
) {
853 l2info
->cookie_len
+= lp
->cookie_len
;
857 l2info
->cookie_type
= LS_COOKIE_ID
;
858 l2info
->cookie_len
+= 2;
861 l2info
->cookie_type
= AS_COOKIE_ID
;
862 l2info
->cookie_len
= 8;
866 l2info
->bundle
= l2info
->cookie
[0];
871 #ifdef DLT_JUNIPER_MFR
872 /* MFR child links don't carry cookies */
873 if (l2info
->pictype
== DLT_JUNIPER_MFR
&&
874 (p
[0] & MFR_BE_MASK
) == MFR_BE_MASK
) {
875 l2info
->cookie_len
= 0;
879 l2info
->header_len
+= l2info
->cookie_len
;
880 l2info
->length
-= l2info
->cookie_len
;
881 l2info
->caplen
-= l2info
->cookie_len
;
884 printf("%s-PIC, cookie-len %u",
888 if (l2info
->cookie_len
> 0) {
889 TCHECK2(p
[0],l2info
->cookie_len
);
891 printf(", cookie 0x");
892 for (idx
= 0; idx
< l2info
->cookie_len
; idx
++) {
893 l2info
->cookie
[idx
] = p
[idx
]; /* copy cookie data */
894 if (eflag
) printf("%02x",p
[idx
]);
898 if (eflag
) printf(": "); /* print demarc b/w L2/L3*/
901 l2info
->proto
= EXTRACT_16BITS(p
+l2info
->cookie_len
);
906 p
+=l2info
->cookie_len
;
908 /* DLT_ specific parsing */
909 switch(l2info
->pictype
) {
910 #ifdef DLT_JUNIPER_MLPPP
911 case DLT_JUNIPER_MLPPP
:
912 switch (l2info
->cookie_type
) {
914 l2info
->bundle
= l2info
->cookie
[1];
917 l2info
->bundle
= (EXTRACT_16BITS(&l2info
->cookie
[6])>>3)&0xfff;
918 l2info
->proto
= (l2info
->cookie
[5])&JUNIPER_LSQ_L3_PROTO_MASK
;
921 l2info
->bundle
= l2info
->cookie
[0];
926 #ifdef DLT_JUNIPER_MLFR
927 case DLT_JUNIPER_MLFR
:
928 switch (l2info
->cookie_type
) {
930 l2info
->bundle
= l2info
->cookie
[1];
931 l2info
->proto
= EXTRACT_16BITS(p
);
932 l2info
->header_len
+= 2;
937 l2info
->bundle
= (EXTRACT_16BITS(&l2info
->cookie
[6])>>3)&0xfff;
938 l2info
->proto
= (l2info
->cookie
[5])&JUNIPER_LSQ_L3_PROTO_MASK
;
941 l2info
->bundle
= l2info
->cookie
[0];
942 l2info
->header_len
+= 2;
949 #ifdef DLT_JUNIPER_MFR
950 case DLT_JUNIPER_MFR
:
951 switch (l2info
->cookie_type
) {
953 l2info
->bundle
= l2info
->cookie
[1];
954 l2info
->proto
= EXTRACT_16BITS(p
);
955 l2info
->header_len
+= 2;
960 l2info
->bundle
= (EXTRACT_16BITS(&l2info
->cookie
[6])>>3)&0xfff;
961 l2info
->proto
= (l2info
->cookie
[5])&JUNIPER_LSQ_L3_PROTO_MASK
;
964 l2info
->bundle
= l2info
->cookie
[0];
969 #ifdef DLT_JUNIPER_ATM2
970 case DLT_JUNIPER_ATM2
:
972 /* ATM cell relay control word present ? */
973 if (l2info
->cookie
[7] & ATM2_PKT_TYPE_MASK
) {
974 control_word
= EXTRACT_32BITS(p
);
975 /* some control word heuristics */
976 switch(control_word
) {
977 case 0: /* zero control word */
978 case 0x08000000: /* < JUNOS 7.4 control-word */
979 case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/
980 l2info
->header_len
+= 4;
987 printf("control-word 0x%08x ", control_word
);
991 #ifdef DLT_JUNIPER_ATM1
992 case DLT_JUNIPER_ATM1
:
995 #ifdef DLT_JUNIPER_PPP
996 case DLT_JUNIPER_PPP
:
999 #ifdef DLT_JUNIPER_CHDLC
1000 case DLT_JUNIPER_CHDLC
:
1003 #ifdef DLT_JUNIPER_ETHER
1004 case DLT_JUNIPER_ETHER
:
1007 #ifdef DLT_JUNIPER_FRELAY
1008 case DLT_JUNIPER_FRELAY
:
1013 printf("Unknown Juniper DLT_ type %u: ", l2info
->pictype
);
1018 printf("hlen %u, proto 0x%04x, ",l2info
->header_len
,l2info
->proto
);
1020 return 1; /* everything went ok so far. continue parsing */
1022 printf("[|juniper_hdr], length %u",h
->len
);
1029 * c-style: whitesmith