1 /* $NetBSD: print-juniper.c,v 1.2 2007/07/24 11:53:45 drochner Exp $ */
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that: (1) source code
6 * distributions retain the above copyright notice and this paragraph
7 * in its entirety, and (2) distributions including binary code include
8 * the above copyright notice and this paragraph in its entirety in
9 * the documentation or other materials provided with the distribution.
10 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
11 * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
12 * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13 * FOR A PARTICULAR PURPOSE.
15 * Original code by Hannes Gredler (hannes@juniper.net)
18 #include <sys/cdefs.h>
21 static const char rcsid
[] _U_
=
22 "@(#) Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.8.2.22 2006/05/10 22:42:46 guy Exp (LBL)";
24 __RCSID("$NetBSD: print-juniper.c,v 1.2 2007/07/24 11:53:45 drochner Exp $");
32 #include <tcpdump-stdinc.h>
37 #include "interface.h"
38 #include "addrtoname.h"
43 #include "ethertype.h"
46 #define JUNIPER_BPF_OUT 0 /* Outgoing packet */
47 #define JUNIPER_BPF_IN 1 /* Incoming packet */
48 #define JUNIPER_BPF_PKT_IN 0x1 /* Incoming packet */
49 #define JUNIPER_BPF_NO_L2 0x2 /* L2 header stripped */
50 #define JUNIPER_BPF_EXT 0x80 /* extensions present */
51 #define JUNIPER_MGC_NUMBER 0x4d4743 /* = "MGC" */
53 #define JUNIPER_LSQ_COOKIE_RE (1 << 3)
54 #define JUNIPER_LSQ_COOKIE_DIR (1 << 2)
55 #define JUNIPER_LSQ_L3_PROTO_SHIFT 4
56 #define JUNIPER_LSQ_L3_PROTO_MASK (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT)
57 #define JUNIPER_LSQ_L3_PROTO_IPV4 (0 << JUNIPER_LSQ_L3_PROTO_SHIFT)
58 #define JUNIPER_LSQ_L3_PROTO_IPV6 (1 << JUNIPER_LSQ_L3_PROTO_SHIFT)
59 #define JUNIPER_LSQ_L3_PROTO_MPLS (2 << JUNIPER_LSQ_L3_PROTO_SHIFT)
60 #define JUNIPER_LSQ_L3_PROTO_ISO (3 << JUNIPER_LSQ_L3_PROTO_SHIFT)
61 #define AS_PIC_COOKIE_LEN 8
63 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1
64 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2
65 #define JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE 3
66 #define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4
67 #define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5
69 static struct tok juniper_ipsec_type_values
[] = {
70 { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE
, "ESP ENCR-AUTH" },
71 { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE
, "ESP ENCR-AH AUTH" },
72 { JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE
, "ESP AUTH" },
73 { JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE
, "AH AUTH" },
74 { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE
, "ESP ENCR" },
78 static struct tok juniper_direction_values
[] = {
79 { JUNIPER_BPF_IN
, "In"},
80 { JUNIPER_BPF_OUT
, "Out"},
84 struct juniper_cookie_table_t
{
85 u_int32_t pictype
; /* pic type */
86 u_int8_t cookie_len
; /* cookie len */
87 const char *s
; /* pic name */
90 static struct juniper_cookie_table_t juniper_cookie_table
[] = {
91 #ifdef DLT_JUNIPER_ATM1
92 { DLT_JUNIPER_ATM1
, 4, "ATM1"},
94 #ifdef DLT_JUNIPER_ATM2
95 { DLT_JUNIPER_ATM2
, 8, "ATM2"},
97 #ifdef DLT_JUNIPER_MLPPP
98 { DLT_JUNIPER_MLPPP
, 2, "MLPPP"},
100 #ifdef DLT_JUNIPER_MLFR
101 { DLT_JUNIPER_MLFR
, 2, "MLFR"},
103 #ifdef DLT_JUNIPER_MFR
104 { DLT_JUNIPER_MFR
, 4, "MFR"},
106 #ifdef DLT_JUNIPER_PPPOE
107 { DLT_JUNIPER_PPPOE
, 0, "PPPoE"},
109 #ifdef DLT_JUNIPER_PPPOE_ATM
110 { DLT_JUNIPER_PPPOE_ATM
, 0, "PPPoE ATM"},
112 #ifdef DLT_JUNIPER_GGSN
113 { DLT_JUNIPER_GGSN
, 8, "GGSN"},
115 #ifdef DLT_JUNIPER_MONITOR
116 { DLT_JUNIPER_MONITOR
, 8, "MONITOR"},
118 #ifdef DLT_JUNIPER_SERVICES
119 { DLT_JUNIPER_SERVICES
, 8, "AS"},
121 #ifdef DLT_JUNIPER_ES
122 { DLT_JUNIPER_ES
, 0, "ES"},
127 struct juniper_l2info_t
{
134 u_int8_t cookie_type
;
140 #define LS_COOKIE_ID 0x54
141 #define AS_COOKIE_ID 0x47
142 #define LS_MLFR_COOKIE_LEN 4
143 #define ML_MLFR_COOKIE_LEN 2
144 #define LS_MFR_COOKIE_LEN 6
145 #define ATM1_COOKIE_LEN 4
146 #define ATM2_COOKIE_LEN 8
148 #define ATM2_PKT_TYPE_MASK 0x70
149 #define ATM2_GAP_COUNT_MASK 0x3F
151 #define JUNIPER_PROTO_NULL 1
152 #define JUNIPER_PROTO_IPV4 2
153 #define JUNIPER_PROTO_IPV6 6
155 #define MFR_BE_MASK 0xc0
157 static struct tok juniper_protocol_values
[] = {
158 { JUNIPER_PROTO_NULL
, "Null" },
159 { JUNIPER_PROTO_IPV4
, "IPv4" },
160 { JUNIPER_PROTO_IPV6
, "IPv6" },
164 int ip_heuristic_guess(register const u_char
*, u_int
);
165 int juniper_ppp_heuristic_guess(register const u_char
*, u_int
);
166 static int juniper_parse_header (const u_char
*, const struct pcap_pkthdr
*, struct juniper_l2info_t
*);
168 #ifdef DLT_JUNIPER_GGSN
170 juniper_ggsn_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
172 struct juniper_l2info_t l2info
;
173 struct juniper_ggsn_header
{
181 const struct juniper_ggsn_header
*gh
;
183 l2info
.pictype
= DLT_JUNIPER_GGSN
;
184 if(juniper_parse_header(p
, h
, &l2info
) == 0)
185 return l2info
.header_len
;
187 p
+=l2info
.header_len
;
188 gh
= (struct juniper_ggsn_header
*)p
;
191 printf("proto %s (%u), vlan %u: ",
192 tok2str(juniper_protocol_values
,"Unknown",gh
->proto
),
194 EXTRACT_16BITS(&gh
->vlan_id
[0]));
197 case JUNIPER_PROTO_IPV4
:
198 ip_print(gndo
, p
, l2info
.length
);
201 case JUNIPER_PROTO_IPV6
:
202 ip6_print(p
, l2info
.length
);
207 printf("unknown GGSN proto (%u)", gh
->proto
);
210 return l2info
.header_len
;
214 #ifdef DLT_JUNIPER_ES
216 juniper_es_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
218 struct juniper_l2info_t l2info
;
219 struct juniper_ipsec_header
{
220 u_int8_t sa_index
[2];
227 u_int rewrite_len
,es_type_bundle
;
228 const struct juniper_ipsec_header
*ih
;
230 l2info
.pictype
= DLT_JUNIPER_ES
;
231 if(juniper_parse_header(p
, h
, &l2info
) == 0)
232 return l2info
.header_len
;
234 p
+=l2info
.header_len
;
235 ih
= (struct juniper_ipsec_header
*)p
;
238 case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE
:
239 case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE
:
243 case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE
:
244 case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE
:
245 case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE
:
249 printf("ES Invalid type %u, length %u",
252 return l2info
.header_len
;
255 l2info
.length
-=rewrite_len
;
259 if (!es_type_bundle
) {
260 printf("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n",
261 EXTRACT_16BITS(&ih
->sa_index
),
263 tok2str(juniper_ipsec_type_values
,"Unknown",ih
->type
),
265 EXTRACT_32BITS(&ih
->spi
),
266 ipaddr_string(&ih
->src_ip
),
267 ipaddr_string(&ih
->dst_ip
),
270 printf("ES SA, index %u, ttl %u type %s (%u), length %u\n",
271 EXTRACT_16BITS(&ih
->sa_index
),
273 tok2str(juniper_ipsec_type_values
,"Unknown",ih
->type
),
279 ip_print(gndo
, p
, l2info
.length
);
280 return l2info
.header_len
;
284 #ifdef DLT_JUNIPER_MONITOR
286 juniper_monitor_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
288 struct juniper_l2info_t l2info
;
289 struct juniper_monitor_header
{
293 u_int8_t service_id
[4];
295 const struct juniper_monitor_header
*mh
;
297 l2info
.pictype
= DLT_JUNIPER_MONITOR
;
298 if(juniper_parse_header(p
, h
, &l2info
) == 0)
299 return l2info
.header_len
;
301 p
+=l2info
.header_len
;
302 mh
= (struct juniper_monitor_header
*)p
;
305 printf("service-id %u, iif %u, pkt-type %u: ",
306 EXTRACT_32BITS(&mh
->service_id
),
307 EXTRACT_16BITS(&mh
->iif
),
310 /* no proto field - lets guess by first byte of IP header*/
311 ip_heuristic_guess(p
, l2info
.length
);
313 return l2info
.header_len
;
317 #ifdef DLT_JUNIPER_SERVICES
319 juniper_services_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
321 struct juniper_l2info_t l2info
;
322 struct juniper_services_header
{
325 u_int8_t svc_set_id
[2];
328 const struct juniper_services_header
*sh
;
330 l2info
.pictype
= DLT_JUNIPER_SERVICES
;
331 if(juniper_parse_header(p
, h
, &l2info
) == 0)
332 return l2info
.header_len
;
334 p
+=l2info
.header_len
;
335 sh
= (struct juniper_services_header
*)p
;
338 printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
341 EXTRACT_16BITS(&sh
->svc_set_id
),
342 EXTRACT_24BITS(&sh
->dir_iif
[1]));
344 /* no proto field - lets guess by first byte of IP header*/
345 ip_heuristic_guess(p
, l2info
.length
);
347 return l2info
.header_len
;
351 #ifdef DLT_JUNIPER_PPPOE
353 juniper_pppoe_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
355 struct juniper_l2info_t l2info
;
357 l2info
.pictype
= DLT_JUNIPER_PPPOE
;
358 if(juniper_parse_header(p
, h
, &l2info
) == 0)
359 return l2info
.header_len
;
361 p
+=l2info
.header_len
;
362 /* this DLT contains nothing but raw ethernet frames */
363 ether_print(p
, l2info
.length
, l2info
.caplen
);
364 return l2info
.header_len
;
368 #ifdef DLT_JUNIPER_ETHER
370 juniper_ether_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
372 struct juniper_l2info_t l2info
;
374 l2info
.pictype
= DLT_JUNIPER_ETHER
;
375 if(juniper_parse_header(p
, h
, &l2info
) == 0)
376 return l2info
.header_len
;
378 p
+=l2info
.header_len
;
379 /* this DLT contains nothing but raw Ethernet frames */
380 ether_print(p
, l2info
.length
, l2info
.caplen
);
381 return l2info
.header_len
;
385 #ifdef DLT_JUNIPER_PPP
387 juniper_ppp_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
389 struct juniper_l2info_t l2info
;
391 l2info
.pictype
= DLT_JUNIPER_PPP
;
392 if(juniper_parse_header(p
, h
, &l2info
) == 0)
393 return l2info
.header_len
;
395 p
+=l2info
.header_len
;
396 /* this DLT contains nothing but raw ppp frames */
397 ppp_print(p
, l2info
.length
);
398 return l2info
.header_len
;
402 #ifdef DLT_JUNIPER_FRELAY
404 juniper_frelay_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
406 struct juniper_l2info_t l2info
;
408 l2info
.pictype
= DLT_JUNIPER_FRELAY
;
409 if(juniper_parse_header(p
, h
, &l2info
) == 0)
410 return l2info
.header_len
;
412 p
+=l2info
.header_len
;
413 /* this DLT contains nothing but raw frame-relay frames */
414 fr_print(p
, l2info
.length
);
415 return l2info
.header_len
;
419 #ifdef DLT_JUNIPER_CHDLC
421 juniper_chdlc_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
423 struct juniper_l2info_t l2info
;
425 l2info
.pictype
= DLT_JUNIPER_CHDLC
;
426 if(juniper_parse_header(p
, h
, &l2info
) == 0)
427 return l2info
.header_len
;
429 p
+=l2info
.header_len
;
430 /* this DLT contains nothing but raw c-hdlc frames */
431 chdlc_print(p
, l2info
.length
);
432 return l2info
.header_len
;
436 #ifdef DLT_JUNIPER_PPPOE_ATM
438 juniper_pppoe_atm_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
440 struct juniper_l2info_t l2info
;
441 u_int16_t extracted_ethertype
;
443 l2info
.pictype
= DLT_JUNIPER_PPPOE_ATM
;
444 if(juniper_parse_header(p
, h
, &l2info
) == 0)
445 return l2info
.header_len
;
447 p
+=l2info
.header_len
;
449 extracted_ethertype
= EXTRACT_16BITS(p
);
450 /* this DLT contains nothing but raw PPPoE frames,
451 * prepended with a type field*/
452 if (ether_encap_print(extracted_ethertype
,
454 l2info
.length
-ETHERTYPE_LEN
,
455 l2info
.caplen
-ETHERTYPE_LEN
,
456 &extracted_ethertype
) == 0)
457 /* ether_type not known, probably it wasn't one */
458 printf("unknown ethertype 0x%04x", extracted_ethertype
);
460 return l2info
.header_len
;
464 #ifdef DLT_JUNIPER_MLPPP
466 juniper_mlppp_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
468 struct juniper_l2info_t l2info
;
470 l2info
.pictype
= DLT_JUNIPER_MLPPP
;
471 if(juniper_parse_header(p
, h
, &l2info
) == 0)
472 return l2info
.header_len
;
474 /* suppress Bundle-ID if frame was captured on a child-link
475 * best indicator if the cookie looks like a proto */
477 EXTRACT_16BITS(&l2info
.cookie
) != PPP_OSI
&&
478 EXTRACT_16BITS(&l2info
.cookie
) != (PPP_ADDRESS
<< 8 | PPP_CONTROL
))
479 printf("Bundle-ID %u: ",l2info
.bundle
);
481 p
+=l2info
.header_len
;
483 /* first try the LSQ protos */
484 switch(l2info
.proto
) {
485 case JUNIPER_LSQ_L3_PROTO_IPV4
:
486 /* IP traffic going to the RE would not have a cookie
487 * -> this must be incoming IS-IS over PPP
489 if (l2info
.cookie
[4] == (JUNIPER_LSQ_COOKIE_RE
|JUNIPER_LSQ_COOKIE_DIR
))
490 ppp_print(p
, l2info
.length
);
492 ip_print(gndo
, p
, l2info
.length
);
493 return l2info
.header_len
;
495 case JUNIPER_LSQ_L3_PROTO_IPV6
:
496 ip6_print(p
,l2info
.length
);
497 return l2info
.header_len
;
499 case JUNIPER_LSQ_L3_PROTO_MPLS
:
500 mpls_print(p
,l2info
.length
);
501 return l2info
.header_len
;
502 case JUNIPER_LSQ_L3_PROTO_ISO
:
503 isoclns_print(p
,l2info
.length
,l2info
.caplen
);
504 return l2info
.header_len
;
509 /* zero length cookie ? */
510 switch (EXTRACT_16BITS(&l2info
.cookie
)) {
512 ppp_print(p
-2,l2info
.length
+2);
514 case (PPP_ADDRESS
<< 8 | PPP_CONTROL
): /* fall through */
516 ppp_print(p
,l2info
.length
);
520 return l2info
.header_len
;
525 #ifdef DLT_JUNIPER_MFR
527 juniper_mfr_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
529 struct juniper_l2info_t l2info
;
531 l2info
.pictype
= DLT_JUNIPER_MFR
;
532 if(juniper_parse_header(p
, h
, &l2info
) == 0)
533 return l2info
.header_len
;
535 p
+=l2info
.header_len
;
538 if (l2info
.cookie_len
== 0) {
539 mfr_print(p
,l2info
.length
);
540 return l2info
.header_len
;
543 /* first try the LSQ protos */
544 if (l2info
.cookie_len
== AS_PIC_COOKIE_LEN
) {
545 switch(l2info
.proto
) {
546 case JUNIPER_LSQ_L3_PROTO_IPV4
:
547 ip_print(gndo
, p
, l2info
.length
);
548 return l2info
.header_len
;
550 case JUNIPER_LSQ_L3_PROTO_IPV6
:
551 ip6_print(p
,l2info
.length
);
552 return l2info
.header_len
;
554 case JUNIPER_LSQ_L3_PROTO_MPLS
:
555 mpls_print(p
,l2info
.length
);
556 return l2info
.header_len
;
557 case JUNIPER_LSQ_L3_PROTO_ISO
:
558 isoclns_print(p
,l2info
.length
,l2info
.caplen
);
559 return l2info
.header_len
;
563 return l2info
.header_len
;
566 /* suppress Bundle-ID if frame was captured on a child-link */
567 if (eflag
&& EXTRACT_32BITS(l2info
.cookie
) != 1) printf("Bundle-ID %u, ",l2info
.bundle
);
568 switch (l2info
.proto
) {
569 case (LLCSAP_ISONS
<<8 | LLCSAP_ISONS
):
570 isoclns_print(p
+1, l2info
.length
-1, l2info
.caplen
-1);
572 case (LLC_UI
<<8 | NLPID_Q933
):
573 case (LLC_UI
<<8 | NLPID_IP
):
574 case (LLC_UI
<<8 | NLPID_IP6
):
575 /* pass IP{4,6} to the OSI layer for proper link-layer printing */
576 isoclns_print(p
-1, l2info
.length
+1, l2info
.caplen
+1);
579 printf("unknown protocol 0x%04x, length %u",l2info
.proto
, l2info
.length
);
582 return l2info
.header_len
;
586 #ifdef DLT_JUNIPER_MLFR
588 juniper_mlfr_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
590 struct juniper_l2info_t l2info
;
592 l2info
.pictype
= DLT_JUNIPER_MLFR
;
593 if(juniper_parse_header(p
, h
, &l2info
) == 0)
594 return l2info
.header_len
;
596 p
+=l2info
.header_len
;
598 /* suppress Bundle-ID if frame was captured on a child-link */
599 if (eflag
&& EXTRACT_32BITS(l2info
.cookie
) != 1) printf("Bundle-ID %u, ",l2info
.bundle
);
600 switch (l2info
.proto
) {
603 isoclns_print(p
, l2info
.length
, l2info
.caplen
);
605 case (LLC_UI
<<8 | NLPID_Q933
):
606 case (LLC_UI
<<8 | NLPID_IP
):
607 case (LLC_UI
<<8 | NLPID_IP6
):
608 /* pass IP{4,6} to the OSI layer for proper link-layer printing */
609 isoclns_print(p
-1, l2info
.length
+1, l2info
.caplen
+1);
612 printf("unknown protocol 0x%04x, length %u",l2info
.proto
, l2info
.length
);
615 return l2info
.header_len
;
620 * ATM1 PIC cookie format
622 * +-----+-------------------------+-------------------------------+
623 * |fmtid| vc index | channel ID |
624 * +-----+-------------------------+-------------------------------+
627 #ifdef DLT_JUNIPER_ATM1
629 juniper_atm1_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
631 u_int16_t extracted_ethertype
;
633 struct juniper_l2info_t l2info
;
635 l2info
.pictype
= DLT_JUNIPER_ATM1
;
636 if(juniper_parse_header(p
, h
, &l2info
) == 0)
637 return l2info
.header_len
;
639 p
+=l2info
.header_len
;
641 if (l2info
.cookie
[0] == 0x80) { /* OAM cell ? */
642 oam_print(p
,l2info
.length
,ATM_OAM_NOHEC
);
643 return l2info
.header_len
;
646 if (EXTRACT_24BITS(p
) == 0xfefe03 || /* NLPID encaps ? */
647 EXTRACT_24BITS(p
) == 0xaaaa03) { /* SNAP encaps ? */
649 if (llc_print(p
, l2info
.length
, l2info
.caplen
, NULL
, NULL
,
650 &extracted_ethertype
) != 0)
651 return l2info
.header_len
;
654 if (p
[0] == 0x03) { /* Cisco style NLPID encaps ? */
655 isoclns_print(p
+ 1, l2info
.length
- 1, l2info
.caplen
- 1);
656 /* FIXME check if frame was recognized */
657 return l2info
.header_len
;
660 if(ip_heuristic_guess(p
, l2info
.length
) != 0) /* last try - vcmux encaps ? */
661 return l2info
.header_len
;
663 return l2info
.header_len
;
668 * ATM2 PIC cookie format
670 * +-------------------------------+---------+---+-----+-----------+
671 * | channel ID | reserv |AAL| CCRQ| gap cnt |
672 * +-------------------------------+---------+---+-----+-----------+
675 #ifdef DLT_JUNIPER_ATM2
677 juniper_atm2_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
679 u_int16_t extracted_ethertype
;
681 struct juniper_l2info_t l2info
;
683 l2info
.pictype
= DLT_JUNIPER_ATM2
;
684 if(juniper_parse_header(p
, h
, &l2info
) == 0)
685 return l2info
.header_len
;
687 p
+=l2info
.header_len
;
689 if (l2info
.cookie
[7] & ATM2_PKT_TYPE_MASK
) { /* OAM cell ? */
690 oam_print(p
,l2info
.length
,ATM_OAM_NOHEC
);
691 return l2info
.header_len
;
694 if (EXTRACT_24BITS(p
) == 0xfefe03 || /* NLPID encaps ? */
695 EXTRACT_24BITS(p
) == 0xaaaa03) { /* SNAP encaps ? */
697 if (llc_print(p
, l2info
.length
, l2info
.caplen
, NULL
, NULL
,
698 &extracted_ethertype
) != 0)
699 return l2info
.header_len
;
702 if (l2info
.direction
!= JUNIPER_BPF_PKT_IN
&& /* ether-over-1483 encaps ? */
703 (EXTRACT_32BITS(l2info
.cookie
) & ATM2_GAP_COUNT_MASK
)) {
704 ether_print(p
, l2info
.length
, l2info
.caplen
);
705 return l2info
.header_len
;
708 if (p
[0] == 0x03) { /* Cisco style NLPID encaps ? */
709 isoclns_print(p
+ 1, l2info
.length
- 1, l2info
.caplen
- 1);
710 /* FIXME check if frame was recognized */
711 return l2info
.header_len
;
714 if(juniper_ppp_heuristic_guess(p
, l2info
.length
) != 0) /* PPPoA vcmux encaps ? */
715 return l2info
.header_len
;
717 if(ip_heuristic_guess(p
, l2info
.length
) != 0) /* last try - vcmux encaps ? */
718 return l2info
.header_len
;
720 return l2info
.header_len
;
725 /* try to guess, based on all PPP protos that are supported in
726 * a juniper router if the payload data is encapsulated using PPP */
728 juniper_ppp_heuristic_guess(register const u_char
*p
, u_int length
) {
730 switch(EXTRACT_16BITS(p
)) {
733 case PPP_MPLS_UCAST
:
734 case PPP_MPLS_MCAST
:
746 ppp_print(p
, length
);
750 return 0; /* did not find a ppp header */
753 return 1; /* we printed a ppp packet */
757 ip_heuristic_guess(register const u_char
*p
, u_int length
) {
771 ip_print(gndo
, p
, length
);
790 ip6_print(p
, length
);
794 return 0; /* did not find a ip header */
797 return 1; /* we printed an v4/v6 packet */
801 juniper_parse_header (const u_char
*p
, const struct pcap_pkthdr
*h
, struct juniper_l2info_t
*l2info
) {
803 struct juniper_cookie_table_t
*lp
= juniper_cookie_table
;
805 #ifdef DLT_JUNIPER_ATM2
806 u_int32_t control_word
;
809 l2info
->header_len
= 0;
810 l2info
->cookie_len
= 0;
814 l2info
->length
= h
->len
;
815 l2info
->caplen
= h
->caplen
;
816 l2info
->direction
= p
[3]&JUNIPER_BPF_PKT_IN
;
819 if (EXTRACT_24BITS(p
) != JUNIPER_MGC_NUMBER
) { /* magic number found ? */
820 printf("no magic-number found!");
824 if (eflag
) /* print direction */
825 printf("%3s ",tok2str(juniper_direction_values
,"---",l2info
->direction
));
827 /* extensions present ? - calculate how much bytes to skip */
828 if ((p
[3] & JUNIPER_BPF_EXT
) == JUNIPER_BPF_EXT
) {
829 offset
= 6 + EXTRACT_16BITS(p
+4);
831 printf("ext-len %u, ",EXTRACT_16BITS(p
+4));
835 if ((p
[3] & JUNIPER_BPF_NO_L2
) == JUNIPER_BPF_NO_L2
) {
837 printf("no-L2-hdr, ");
839 /* there is no link-layer present -
840 * perform the v4/v6 heuristics
841 * to figure out what it is
843 TCHECK2(p
[offset
+4],1);
844 if(ip_heuristic_guess(p
+offset
+4,l2info
->length
-(offset
+4)) == 0)
845 printf("no IP-hdr found!");
847 l2info
->header_len
=offset
+4;
848 return 0; /* stop parsing the output further */
851 l2info
->header_len
= offset
;
852 p
+=l2info
->header_len
;
853 l2info
->length
-= l2info
->header_len
;
854 l2info
->caplen
-= l2info
->header_len
;
856 /* search through the cookie table and copy values matching for our PIC type */
857 while (lp
->s
!= NULL
) {
858 if (lp
->pictype
== l2info
->pictype
) {
860 l2info
->cookie_len
+= lp
->cookie_len
;
864 l2info
->cookie_type
= LS_COOKIE_ID
;
865 l2info
->cookie_len
+= 2;
868 l2info
->cookie_type
= AS_COOKIE_ID
;
869 l2info
->cookie_len
= 8;
873 l2info
->bundle
= l2info
->cookie
[0];
878 #ifdef DLT_JUNIPER_MFR
879 /* MFR child links don't carry cookies */
880 if (l2info
->pictype
== DLT_JUNIPER_MFR
&&
881 (p
[0] & MFR_BE_MASK
) == MFR_BE_MASK
) {
882 l2info
->cookie_len
= 0;
886 l2info
->header_len
+= l2info
->cookie_len
;
887 l2info
->length
-= l2info
->cookie_len
;
888 l2info
->caplen
-= l2info
->cookie_len
;
891 printf("%s-PIC, cookie-len %u",
895 if (l2info
->cookie_len
> 0) {
896 TCHECK2(p
[0],l2info
->cookie_len
);
898 printf(", cookie 0x");
899 for (idx
= 0; idx
< l2info
->cookie_len
; idx
++) {
900 l2info
->cookie
[idx
] = p
[idx
]; /* copy cookie data */
901 if (eflag
) printf("%02x",p
[idx
]);
905 if (eflag
) printf(": "); /* print demarc b/w L2/L3*/
908 l2info
->proto
= EXTRACT_16BITS(p
+l2info
->cookie_len
);
913 p
+=l2info
->cookie_len
;
915 /* DLT_ specific parsing */
916 switch(l2info
->pictype
) {
917 #ifdef DLT_JUNIPER_MLPPP
918 case DLT_JUNIPER_MLPPP
:
919 switch (l2info
->cookie_type
) {
921 l2info
->bundle
= l2info
->cookie
[1];
924 l2info
->bundle
= (EXTRACT_16BITS(&l2info
->cookie
[6])>>3)&0xfff;
925 l2info
->proto
= (l2info
->cookie
[5])&JUNIPER_LSQ_L3_PROTO_MASK
;
928 l2info
->bundle
= l2info
->cookie
[0];
933 #ifdef DLT_JUNIPER_MLFR
934 case DLT_JUNIPER_MLFR
:
935 switch (l2info
->cookie_type
) {
937 l2info
->bundle
= l2info
->cookie
[1];
938 l2info
->proto
= EXTRACT_16BITS(p
);
939 l2info
->header_len
+= 2;
944 l2info
->bundle
= (EXTRACT_16BITS(&l2info
->cookie
[6])>>3)&0xfff;
945 l2info
->proto
= (l2info
->cookie
[5])&JUNIPER_LSQ_L3_PROTO_MASK
;
948 l2info
->bundle
= l2info
->cookie
[0];
949 l2info
->header_len
+= 2;
956 #ifdef DLT_JUNIPER_MFR
957 case DLT_JUNIPER_MFR
:
958 switch (l2info
->cookie_type
) {
960 l2info
->bundle
= l2info
->cookie
[1];
961 l2info
->proto
= EXTRACT_16BITS(p
);
962 l2info
->header_len
+= 2;
967 l2info
->bundle
= (EXTRACT_16BITS(&l2info
->cookie
[6])>>3)&0xfff;
968 l2info
->proto
= (l2info
->cookie
[5])&JUNIPER_LSQ_L3_PROTO_MASK
;
971 l2info
->bundle
= l2info
->cookie
[0];
976 #ifdef DLT_JUNIPER_ATM2
977 case DLT_JUNIPER_ATM2
:
979 /* ATM cell relay control word present ? */
980 if (l2info
->cookie
[7] & ATM2_PKT_TYPE_MASK
) {
981 control_word
= EXTRACT_32BITS(p
);
982 /* some control word heuristics */
983 switch(control_word
) {
984 case 0: /* zero control word */
985 case 0x08000000: /* < JUNOS 7.4 control-word */
986 case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/
987 l2info
->header_len
+= 4;
994 printf("control-word 0x%08x ", control_word
);
998 #ifdef DLT_JUNIPER_ATM1
999 case DLT_JUNIPER_ATM1
:
1002 #ifdef DLT_JUNIPER_PPP
1003 case DLT_JUNIPER_PPP
:
1006 #ifdef DLT_JUNIPER_CHDLC
1007 case DLT_JUNIPER_CHDLC
:
1010 #ifdef DLT_JUNIPER_ETHER
1011 case DLT_JUNIPER_ETHER
:
1014 #ifdef DLT_JUNIPER_FRELAY
1015 case DLT_JUNIPER_FRELAY
:
1020 printf("Unknown Juniper DLT_ type %u: ", l2info
->pictype
);
1025 printf("hlen %u, proto 0x%04x, ",l2info
->header_len
,l2info
->proto
);
1027 return 1; /* everything went ok so far. continue parsing */
1029 printf("[|juniper_hdr], length %u",h
->len
);
1036 * c-style: whitesmith