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.30 2006-02-24 12:18:03 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_BPF_IIF 0x4 /* IIF is valid */
44 #define JUNIPER_BPF_FILTER 0x40 /* BPF filtering is supported */
45 #define JUNIPER_BPF_EXT 0x80 /* extensions present */
46 #define JUNIPER_MGC_NUMBER 0x4d4743 /* = "MGC" */
48 #define JUNIPER_LSQ_COOKIE_RE (1 << 3)
49 #define JUNIPER_LSQ_COOKIE_DIR (1 << 2)
50 #define JUNIPER_LSQ_L3_PROTO_SHIFT 4
51 #define JUNIPER_LSQ_L3_PROTO_MASK (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT)
52 #define JUNIPER_LSQ_L3_PROTO_IPV4 (0 << JUNIPER_LSQ_L3_PROTO_SHIFT)
53 #define JUNIPER_LSQ_L3_PROTO_IPV6 (1 << JUNIPER_LSQ_L3_PROTO_SHIFT)
54 #define JUNIPER_LSQ_L3_PROTO_MPLS (2 << JUNIPER_LSQ_L3_PROTO_SHIFT)
55 #define JUNIPER_LSQ_L3_PROTO_ISO (3 << JUNIPER_LSQ_L3_PROTO_SHIFT)
56 #define AS_PIC_COOKIE_LEN 8
58 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1
59 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2
60 #define JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE 3
61 #define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4
62 #define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5
64 static struct tok juniper_ipsec_type_values
[] = {
65 { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE
, "ESP ENCR-AUTH" },
66 { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE
, "ESP ENCR-AH AUTH" },
67 { JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE
, "ESP AUTH" },
68 { JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE
, "AH AUTH" },
69 { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE
, "ESP ENCR" },
73 static struct tok juniper_direction_values
[] = {
74 { JUNIPER_BPF_IN
, "In"},
75 { JUNIPER_BPF_OUT
, "Out"},
79 /* codepoints for encoding extensions to a .pcap file */
81 JUNIPER_EXT_TLV_IFD_IDX
= 1,
82 JUNIPER_EXT_TLV_IFD_NAME
= 2,
83 JUNIPER_EXT_TLV_IFD_MEDIATYPE
= 3,
84 JUNIPER_EXT_TLV_IFL_IDX
= 4,
85 JUNIPER_EXT_TLV_IFL_UNIT
= 5,
86 JUNIPER_EXT_TLV_IFL_ENCAPS
= 6,
87 JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE
= 7,
88 JUNIPER_EXT_TLV_TTP_IFL_ENCAPS
= 8
91 /* 1 byte type and 1-byte length */
92 #define JUNIPER_EXT_TLV_OVERHEAD 2
94 struct tok jnx_ext_tlv_values
[] = {
95 { JUNIPER_EXT_TLV_IFD_IDX
, "Device Interface Index" },
96 { JUNIPER_EXT_TLV_IFD_NAME
,"Device Interface Name" },
97 { JUNIPER_EXT_TLV_IFD_MEDIATYPE
, "Device Media Type" },
98 { JUNIPER_EXT_TLV_IFL_IDX
, "Logical Interface Index" },
99 { JUNIPER_EXT_TLV_IFL_UNIT
,"Logical Unit Number" },
100 { JUNIPER_EXT_TLV_IFL_ENCAPS
, "Logical Interface Encapsulation" },
101 { JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE
, "TTP derived Device Media Type" },
102 { JUNIPER_EXT_TLV_TTP_IFL_ENCAPS
, "TTP derived Logical Interface Encapsulation" },
106 struct tok jnx_flag_values
[] = {
107 { JUNIPER_BPF_EXT
, "Ext" },
108 { JUNIPER_BPF_FILTER
, "Filter" },
109 { JUNIPER_BPF_IIF
, "IIF" },
110 { JUNIPER_BPF_NO_L2
, "no-L2" },
111 { JUNIPER_BPF_PKT_IN
, "In" },
115 struct juniper_cookie_table_t
{
116 u_int32_t pictype
; /* pic type */
117 u_int8_t cookie_len
; /* cookie len */
118 const char *s
; /* pic name */
121 static struct juniper_cookie_table_t juniper_cookie_table
[] = {
122 #ifdef DLT_JUNIPER_ATM1
123 { DLT_JUNIPER_ATM1
, 4, "ATM1"},
125 #ifdef DLT_JUNIPER_ATM2
126 { DLT_JUNIPER_ATM2
, 8, "ATM2"},
128 #ifdef DLT_JUNIPER_MLPPP
129 { DLT_JUNIPER_MLPPP
, 2, "MLPPP"},
131 #ifdef DLT_JUNIPER_MLFR
132 { DLT_JUNIPER_MLFR
, 2, "MLFR"},
134 #ifdef DLT_JUNIPER_MFR
135 { DLT_JUNIPER_MFR
, 4, "MFR"},
137 #ifdef DLT_JUNIPER_PPPOE
138 { DLT_JUNIPER_PPPOE
, 0, "PPPoE"},
140 #ifdef DLT_JUNIPER_PPPOE_ATM
141 { DLT_JUNIPER_PPPOE_ATM
, 0, "PPPoE ATM"},
143 #ifdef DLT_JUNIPER_GGSN
144 { DLT_JUNIPER_GGSN
, 8, "GGSN"},
146 #ifdef DLT_JUNIPER_MONITOR
147 { DLT_JUNIPER_MONITOR
, 8, "MONITOR"},
149 #ifdef DLT_JUNIPER_SERVICES
150 { DLT_JUNIPER_SERVICES
, 8, "AS"},
152 #ifdef DLT_JUNIPER_ES
153 { DLT_JUNIPER_ES
, 0, "ES"},
158 struct juniper_l2info_t
{
165 u_int8_t cookie_type
;
172 #define LS_COOKIE_ID 0x54
173 #define AS_COOKIE_ID 0x47
174 #define LS_MLFR_COOKIE_LEN 4
175 #define ML_MLFR_COOKIE_LEN 2
176 #define LS_MFR_COOKIE_LEN 6
177 #define ATM1_COOKIE_LEN 4
178 #define ATM2_COOKIE_LEN 8
180 #define ATM2_PKT_TYPE_MASK 0x70
181 #define ATM2_GAP_COUNT_MASK 0x3F
183 #define JUNIPER_PROTO_NULL 1
184 #define JUNIPER_PROTO_IPV4 2
185 #define JUNIPER_PROTO_IPV6 6
187 #define MFR_BE_MASK 0xc0
189 static struct tok juniper_protocol_values
[] = {
190 { JUNIPER_PROTO_NULL
, "Null" },
191 { JUNIPER_PROTO_IPV4
, "IPv4" },
192 { JUNIPER_PROTO_IPV6
, "IPv6" },
196 int ip_heuristic_guess(register const u_char
*, u_int
);
197 int juniper_ppp_heuristic_guess(register const u_char
*, u_int
);
198 int juniper_read_tlv_value(const u_char
*, u_int
, u_int
);
199 static int juniper_parse_header (const u_char
*, const struct pcap_pkthdr
*, struct juniper_l2info_t
*);
201 #ifdef DLT_JUNIPER_GGSN
203 juniper_ggsn_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
205 struct juniper_l2info_t l2info
;
206 struct juniper_ggsn_header
{
214 const struct juniper_ggsn_header
*gh
;
216 l2info
.pictype
= DLT_JUNIPER_GGSN
;
217 if(juniper_parse_header(p
, h
, &l2info
) == 0)
218 return l2info
.header_len
;
220 p
+=l2info
.header_len
;
221 gh
= (struct juniper_ggsn_header
*)p
;
224 printf("proto %s (%u), vlan %u: ",
225 tok2str(juniper_protocol_values
,"Unknown",gh
->proto
),
227 EXTRACT_16BITS(&gh
->vlan_id
[0]));
230 case JUNIPER_PROTO_IPV4
:
231 ip_print(gndo
, p
, l2info
.length
);
234 case JUNIPER_PROTO_IPV6
:
235 ip6_print(p
, l2info
.length
);
240 printf("unknown GGSN proto (%u)", gh
->proto
);
243 return l2info
.header_len
;
247 #ifdef DLT_JUNIPER_ES
249 juniper_es_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
251 struct juniper_l2info_t l2info
;
252 struct juniper_ipsec_header
{
253 u_int8_t sa_index
[2];
260 u_int rewrite_len
,es_type_bundle
;
261 const struct juniper_ipsec_header
*ih
;
263 l2info
.pictype
= DLT_JUNIPER_ES
;
264 if(juniper_parse_header(p
, h
, &l2info
) == 0)
265 return l2info
.header_len
;
267 p
+=l2info
.header_len
;
268 ih
= (struct juniper_ipsec_header
*)p
;
271 case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE
:
272 case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE
:
276 case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE
:
277 case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE
:
278 case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE
:
282 printf("ES Invalid type %u, length %u",
285 return l2info
.header_len
;
288 l2info
.length
-=rewrite_len
;
292 if (!es_type_bundle
) {
293 printf("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n",
294 EXTRACT_16BITS(&ih
->sa_index
),
296 tok2str(juniper_ipsec_type_values
,"Unknown",ih
->type
),
298 EXTRACT_32BITS(&ih
->spi
),
299 ipaddr_string(EXTRACT_32BITS(&ih
->src_ip
)),
300 ipaddr_string(EXTRACT_32BITS(&ih
->dst_ip
)),
303 printf("ES SA, index %u, ttl %u type %s (%u), length %u\n",
304 EXTRACT_16BITS(&ih
->sa_index
),
306 tok2str(juniper_ipsec_type_values
,"Unknown",ih
->type
),
312 ip_print(gndo
, p
, l2info
.length
);
313 return l2info
.header_len
;
317 #ifdef DLT_JUNIPER_MONITOR
319 juniper_monitor_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
321 struct juniper_l2info_t l2info
;
322 struct juniper_monitor_header
{
326 u_int8_t service_id
[4];
328 const struct juniper_monitor_header
*mh
;
330 l2info
.pictype
= DLT_JUNIPER_MONITOR
;
331 if(juniper_parse_header(p
, h
, &l2info
) == 0)
332 return l2info
.header_len
;
334 p
+=l2info
.header_len
;
335 mh
= (struct juniper_monitor_header
*)p
;
338 printf("service-id %u, iif %u, pkt-type %u: ",
339 EXTRACT_32BITS(&mh
->service_id
),
340 EXTRACT_16BITS(&mh
->iif
),
343 /* no proto field - lets guess by first byte of IP header*/
344 ip_heuristic_guess(p
, l2info
.length
);
346 return l2info
.header_len
;
350 #ifdef DLT_JUNIPER_SERVICES
352 juniper_services_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
354 struct juniper_l2info_t l2info
;
355 struct juniper_services_header
{
358 u_int8_t svc_set_id
[2];
361 const struct juniper_services_header
*sh
;
363 l2info
.pictype
= DLT_JUNIPER_SERVICES
;
364 if(juniper_parse_header(p
, h
, &l2info
) == 0)
365 return l2info
.header_len
;
367 p
+=l2info
.header_len
;
368 sh
= (struct juniper_services_header
*)p
;
371 printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
374 EXTRACT_16BITS(&sh
->svc_set_id
),
375 EXTRACT_24BITS(&sh
->dir_iif
[1]));
377 /* no proto field - lets guess by first byte of IP header*/
378 ip_heuristic_guess(p
, l2info
.length
);
380 return l2info
.header_len
;
384 #ifdef DLT_JUNIPER_PPPOE
386 juniper_pppoe_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
388 struct juniper_l2info_t l2info
;
390 l2info
.pictype
= DLT_JUNIPER_PPPOE
;
391 if(juniper_parse_header(p
, h
, &l2info
) == 0)
392 return l2info
.header_len
;
394 p
+=l2info
.header_len
;
395 /* this DLT contains nothing but raw ethernet frames */
396 ether_print(p
, l2info
.length
, l2info
.caplen
);
397 return l2info
.header_len
;
401 #ifdef DLT_JUNIPER_ETHER
403 juniper_ether_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
405 struct juniper_l2info_t l2info
;
407 l2info
.pictype
= DLT_JUNIPER_ETHER
;
408 if(juniper_parse_header(p
, h
, &l2info
) == 0)
409 return l2info
.header_len
;
411 p
+=l2info
.header_len
;
412 /* this DLT contains nothing but raw Ethernet frames */
413 ether_print(p
, l2info
.length
, l2info
.caplen
);
414 return l2info
.header_len
;
418 #ifdef DLT_JUNIPER_PPP
420 juniper_ppp_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
422 struct juniper_l2info_t l2info
;
424 l2info
.pictype
= DLT_JUNIPER_PPP
;
425 if(juniper_parse_header(p
, h
, &l2info
) == 0)
426 return l2info
.header_len
;
428 p
+=l2info
.header_len
;
429 /* this DLT contains nothing but raw ppp frames */
430 ppp_print(p
, l2info
.length
);
431 return l2info
.header_len
;
435 #ifdef DLT_JUNIPER_FRELAY
437 juniper_frelay_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
439 struct juniper_l2info_t l2info
;
441 l2info
.pictype
= DLT_JUNIPER_FRELAY
;
442 if(juniper_parse_header(p
, h
, &l2info
) == 0)
443 return l2info
.header_len
;
445 p
+=l2info
.header_len
;
446 /* this DLT contains nothing but raw frame-relay frames */
447 fr_print(p
, l2info
.length
);
448 return l2info
.header_len
;
452 #ifdef DLT_JUNIPER_CHDLC
454 juniper_chdlc_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
456 struct juniper_l2info_t l2info
;
458 l2info
.pictype
= DLT_JUNIPER_CHDLC
;
459 if(juniper_parse_header(p
, h
, &l2info
) == 0)
460 return l2info
.header_len
;
462 p
+=l2info
.header_len
;
463 /* this DLT contains nothing but raw c-hdlc frames */
464 chdlc_print(p
, l2info
.length
);
465 return l2info
.header_len
;
469 #ifdef DLT_JUNIPER_PPPOE_ATM
471 juniper_pppoe_atm_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
473 struct juniper_l2info_t l2info
;
474 u_int16_t extracted_ethertype
;
476 l2info
.pictype
= DLT_JUNIPER_PPPOE_ATM
;
477 if(juniper_parse_header(p
, h
, &l2info
) == 0)
478 return l2info
.header_len
;
480 p
+=l2info
.header_len
;
482 extracted_ethertype
= EXTRACT_16BITS(p
);
483 /* this DLT contains nothing but raw PPPoE frames,
484 * prepended with a type field*/
485 if (ether_encap_print(extracted_ethertype
,
487 l2info
.length
-ETHERTYPE_LEN
,
488 l2info
.caplen
-ETHERTYPE_LEN
,
489 &extracted_ethertype
) == 0)
490 /* ether_type not known, probably it wasn't one */
491 printf("unknown ethertype 0x%04x", extracted_ethertype
);
493 return l2info
.header_len
;
497 #ifdef DLT_JUNIPER_MLPPP
499 juniper_mlppp_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
501 struct juniper_l2info_t l2info
;
503 l2info
.pictype
= DLT_JUNIPER_MLPPP
;
504 if(juniper_parse_header(p
, h
, &l2info
) == 0)
505 return l2info
.header_len
;
507 /* suppress Bundle-ID if frame was captured on a child-link
508 * best indicator if the cookie looks like a proto */
510 EXTRACT_16BITS(&l2info
.cookie
) != PPP_OSI
&&
511 EXTRACT_16BITS(&l2info
.cookie
) != (PPP_ADDRESS
<< 8 | PPP_CONTROL
))
512 printf("Bundle-ID %u: ",l2info
.bundle
);
514 p
+=l2info
.header_len
;
516 /* first try the LSQ protos */
517 switch(l2info
.proto
) {
518 case JUNIPER_LSQ_L3_PROTO_IPV4
:
519 /* IP traffic going to the RE would not have a cookie
520 * -> this must be incoming IS-IS over PPP
522 if (l2info
.cookie
[4] == (JUNIPER_LSQ_COOKIE_RE
|JUNIPER_LSQ_COOKIE_DIR
))
523 ppp_print(p
, l2info
.length
);
525 ip_print(gndo
, p
, l2info
.length
);
526 return l2info
.header_len
;
528 case JUNIPER_LSQ_L3_PROTO_IPV6
:
529 ip6_print(p
,l2info
.length
);
530 return l2info
.header_len
;
532 case JUNIPER_LSQ_L3_PROTO_MPLS
:
533 mpls_print(p
,l2info
.length
);
534 return l2info
.header_len
;
535 case JUNIPER_LSQ_L3_PROTO_ISO
:
536 isoclns_print(p
,l2info
.length
,l2info
.caplen
);
537 return l2info
.header_len
;
542 /* zero length cookie ? */
543 switch (EXTRACT_16BITS(&l2info
.cookie
)) {
545 ppp_print(p
-2,l2info
.length
+2);
547 case (PPP_ADDRESS
<< 8 | PPP_CONTROL
): /* fall through */
549 ppp_print(p
,l2info
.length
);
553 return l2info
.header_len
;
558 #ifdef DLT_JUNIPER_MFR
560 juniper_mfr_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
562 struct juniper_l2info_t l2info
;
564 l2info
.pictype
= DLT_JUNIPER_MFR
;
565 if(juniper_parse_header(p
, h
, &l2info
) == 0)
566 return l2info
.header_len
;
568 p
+=l2info
.header_len
;
571 if (l2info
.cookie_len
== 0) {
572 mfr_print(p
,l2info
.length
);
573 return l2info
.header_len
;
576 /* first try the LSQ protos */
577 if (l2info
.cookie_len
== AS_PIC_COOKIE_LEN
) {
578 switch(l2info
.proto
) {
579 case JUNIPER_LSQ_L3_PROTO_IPV4
:
580 ip_print(gndo
, p
, l2info
.length
);
581 return l2info
.header_len
;
583 case JUNIPER_LSQ_L3_PROTO_IPV6
:
584 ip6_print(p
,l2info
.length
);
585 return l2info
.header_len
;
587 case JUNIPER_LSQ_L3_PROTO_MPLS
:
588 mpls_print(p
,l2info
.length
);
589 return l2info
.header_len
;
590 case JUNIPER_LSQ_L3_PROTO_ISO
:
591 isoclns_print(p
,l2info
.length
,l2info
.caplen
);
592 return l2info
.header_len
;
596 return l2info
.header_len
;
599 /* suppress Bundle-ID if frame was captured on a child-link */
600 if (eflag
&& EXTRACT_32BITS(l2info
.cookie
) != 1) printf("Bundle-ID %u, ",l2info
.bundle
);
601 switch (l2info
.proto
) {
602 case (LLCSAP_ISONS
<<8 | LLCSAP_ISONS
):
603 isoclns_print(p
+1, l2info
.length
-1, l2info
.caplen
-1);
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
;
619 #ifdef DLT_JUNIPER_MLFR
621 juniper_mlfr_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
623 struct juniper_l2info_t l2info
;
625 l2info
.pictype
= DLT_JUNIPER_MLFR
;
626 if(juniper_parse_header(p
, h
, &l2info
) == 0)
627 return l2info
.header_len
;
629 p
+=l2info
.header_len
;
631 /* suppress Bundle-ID if frame was captured on a child-link */
632 if (eflag
&& EXTRACT_32BITS(l2info
.cookie
) != 1) printf("Bundle-ID %u, ",l2info
.bundle
);
633 switch (l2info
.proto
) {
636 isoclns_print(p
, l2info
.length
, l2info
.caplen
);
638 case (LLC_UI
<<8 | NLPID_Q933
):
639 case (LLC_UI
<<8 | NLPID_IP
):
640 case (LLC_UI
<<8 | NLPID_IP6
):
641 /* pass IP{4,6} to the OSI layer for proper link-layer printing */
642 isoclns_print(p
-1, l2info
.length
+1, l2info
.caplen
+1);
645 printf("unknown protocol 0x%04x, length %u",l2info
.proto
, l2info
.length
);
648 return l2info
.header_len
;
653 * ATM1 PIC cookie format
655 * +-----+-------------------------+-------------------------------+
656 * |fmtid| vc index | channel ID |
657 * +-----+-------------------------+-------------------------------+
660 #ifdef DLT_JUNIPER_ATM1
662 juniper_atm1_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
664 u_int16_t extracted_ethertype
;
666 struct juniper_l2info_t l2info
;
668 l2info
.pictype
= DLT_JUNIPER_ATM1
;
669 if(juniper_parse_header(p
, h
, &l2info
) == 0)
670 return l2info
.header_len
;
672 p
+=l2info
.header_len
;
674 if (l2info
.cookie
[0] == 0x80) { /* OAM cell ? */
675 oam_print(p
,l2info
.length
,ATM_OAM_NOHEC
);
676 return l2info
.header_len
;
679 if (EXTRACT_24BITS(p
) == 0xfefe03 || /* NLPID encaps ? */
680 EXTRACT_24BITS(p
) == 0xaaaa03) { /* SNAP encaps ? */
682 if (llc_print(p
, l2info
.length
, l2info
.caplen
, NULL
, NULL
,
683 &extracted_ethertype
) != 0)
684 return l2info
.header_len
;
687 if (p
[0] == 0x03) { /* Cisco style NLPID encaps ? */
688 isoclns_print(p
+ 1, l2info
.length
- 1, l2info
.caplen
- 1);
689 /* FIXME check if frame was recognized */
690 return l2info
.header_len
;
693 if(ip_heuristic_guess(p
, l2info
.length
) != 0) /* last try - vcmux encaps ? */
694 return l2info
.header_len
;
696 return l2info
.header_len
;
701 * ATM2 PIC cookie format
703 * +-------------------------------+---------+---+-----+-----------+
704 * | channel ID | reserv |AAL| CCRQ| gap cnt |
705 * +-------------------------------+---------+---+-----+-----------+
708 #ifdef DLT_JUNIPER_ATM2
710 juniper_atm2_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
712 u_int16_t extracted_ethertype
;
714 struct juniper_l2info_t l2info
;
716 l2info
.pictype
= DLT_JUNIPER_ATM2
;
717 if(juniper_parse_header(p
, h
, &l2info
) == 0)
718 return l2info
.header_len
;
720 p
+=l2info
.header_len
;
722 if (l2info
.cookie
[7] & ATM2_PKT_TYPE_MASK
) { /* OAM cell ? */
723 oam_print(p
,l2info
.length
,ATM_OAM_NOHEC
);
724 return l2info
.header_len
;
727 if (EXTRACT_24BITS(p
) == 0xfefe03 || /* NLPID encaps ? */
728 EXTRACT_24BITS(p
) == 0xaaaa03) { /* SNAP encaps ? */
730 if (llc_print(p
, l2info
.length
, l2info
.caplen
, NULL
, NULL
,
731 &extracted_ethertype
) != 0)
732 return l2info
.header_len
;
735 if (l2info
.direction
!= JUNIPER_BPF_PKT_IN
&& /* ether-over-1483 encaps ? */
736 (EXTRACT_32BITS(l2info
.cookie
) & ATM2_GAP_COUNT_MASK
)) {
737 ether_print(p
, l2info
.length
, l2info
.caplen
);
738 return l2info
.header_len
;
741 if (p
[0] == 0x03) { /* Cisco style NLPID encaps ? */
742 isoclns_print(p
+ 1, l2info
.length
- 1, l2info
.caplen
- 1);
743 /* FIXME check if frame was recognized */
744 return l2info
.header_len
;
747 if(juniper_ppp_heuristic_guess(p
, l2info
.length
) != 0) /* PPPoA vcmux encaps ? */
748 return l2info
.header_len
;
750 if(ip_heuristic_guess(p
, l2info
.length
) != 0) /* last try - vcmux encaps ? */
751 return l2info
.header_len
;
753 return l2info
.header_len
;
758 /* try to guess, based on all PPP protos that are supported in
759 * a juniper router if the payload data is encapsulated using PPP */
761 juniper_ppp_heuristic_guess(register const u_char
*p
, u_int length
) {
763 switch(EXTRACT_16BITS(p
)) {
766 case PPP_MPLS_UCAST
:
767 case PPP_MPLS_MCAST
:
779 ppp_print(p
, length
);
783 return 0; /* did not find a ppp header */
786 return 1; /* we printed a ppp packet */
790 ip_heuristic_guess(register const u_char
*p
, u_int length
) {
804 ip_print(gndo
, p
, length
);
823 ip6_print(p
, length
);
827 return 0; /* did not find a ip header */
830 return 1; /* we printed an v4/v6 packet */
834 juniper_read_tlv_value(const u_char
*p
, u_int tlv_type
, u_int tlv_len
) {
838 /* TLVs < 128 are little endian encoded */
839 if (tlv_type
< 128) {
845 tlv_value
= EXTRACT_LE_16BITS(p
);
848 tlv_value
= EXTRACT_LE_24BITS(p
);
851 tlv_value
= EXTRACT_LE_32BITS(p
);
858 /* TLVs >= 128 are big endian encoded */
864 tlv_value
= EXTRACT_16BITS(p
);
867 tlv_value
= EXTRACT_24BITS(p
);
870 tlv_value
= EXTRACT_32BITS(p
);
881 juniper_parse_header (const u_char
*p
, const struct pcap_pkthdr
*h
, struct juniper_l2info_t
*l2info
) {
883 struct juniper_cookie_table_t
*lp
= juniper_cookie_table
;
884 u_int idx
, jnx_ext_len
, jnx_header_len
= 0;
885 u_int8_t tlv_type
,tlv_len
;
886 u_int32_t control_word
;
891 l2info
->header_len
= 0;
892 l2info
->cookie_len
= 0;
896 l2info
->length
= h
->len
;
897 l2info
->caplen
= h
->caplen
;
899 l2info
->flags
= p
[3];
900 l2info
->direction
= p
[3]&JUNIPER_BPF_PKT_IN
;
902 if (EXTRACT_24BITS(p
) != JUNIPER_MGC_NUMBER
) { /* magic number found ? */
903 printf("no magic-number found!");
907 if (eflag
) /* print direction */
908 printf("%3s ",tok2str(juniper_direction_values
,"---",l2info
->direction
));
910 /* magic number + flags */
914 printf("\n\tJuniper PCAP Flags [%s]",
915 bittok2str(jnx_flag_values
, "none", l2info
->flags
));
917 /* extensions present ? - calculate how much bytes to skip */
918 if ((l2info
->flags
& JUNIPER_BPF_EXT
) == JUNIPER_BPF_EXT
) {
920 tptr
= p
+jnx_header_len
;
922 /* ok to read extension length ? */
924 jnx_ext_len
= EXTRACT_16BITS(tptr
);
928 /* nail up the total length -
929 * just in case something goes wrong
930 * with TLV parsing */
931 jnx_header_len
+= jnx_ext_len
;
934 printf(", PCAP Extension(s) total length %u",
937 TCHECK2(tptr
[0], jnx_ext_len
);
938 while (jnx_ext_len
> JUNIPER_EXT_TLV_OVERHEAD
) {
939 tlv_type
= *(tptr
++);
944 if (tlv_type
== 0 || tlv_len
== 0)
948 printf("\n\t %s Extension TLV #%u, length %u, value ",
949 tok2str(jnx_ext_tlv_values
,"Unknown",tlv_type
),
953 tlv_value
= juniper_read_tlv_value(tptr
, tlv_type
, tlv_len
);
955 case JUNIPER_EXT_TLV_IFD_NAME
:
959 case JUNIPER_EXT_TLV_IFD_MEDIATYPE
: /* fall through */
960 case JUNIPER_EXT_TLV_IFL_ENCAPS
:
961 case JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE
:
962 case JUNIPER_EXT_TLV_TTP_IFL_ENCAPS
:
963 case JUNIPER_EXT_TLV_IFL_IDX
:
964 case JUNIPER_EXT_TLV_IFL_UNIT
:
965 case JUNIPER_EXT_TLV_IFD_IDX
:
967 if (tlv_value
!= -1) {
969 printf("%u",tlv_value
);
975 jnx_ext_len
-= tlv_len
+JUNIPER_EXT_TLV_OVERHEAD
;
979 printf("\n\t-----original packet-----\n\t");
982 if ((l2info
->flags
& JUNIPER_BPF_NO_L2
) == JUNIPER_BPF_NO_L2
) {
984 printf("no-L2-hdr, ");
986 /* there is no link-layer present -
987 * perform the v4/v6 heuristics
988 * to figure out what it is
990 TCHECK2(p
[jnx_header_len
+4],1);
991 if(ip_heuristic_guess(p
+jnx_header_len
+4,l2info
->length
-(jnx_header_len
+4)) == 0)
992 printf("no IP-hdr found!");
994 l2info
->header_len
=jnx_header_len
+4;
995 return 0; /* stop parsing the output further */
998 l2info
->header_len
= jnx_header_len
;
999 p
+=l2info
->header_len
;
1000 l2info
->length
-= l2info
->header_len
;
1001 l2info
->caplen
-= l2info
->header_len
;
1003 /* search through the cookie table and copy values matching for our PIC type */
1004 while (lp
->s
!= NULL
) {
1005 if (lp
->pictype
== l2info
->pictype
) {
1007 l2info
->cookie_len
+= lp
->cookie_len
;
1011 l2info
->cookie_type
= LS_COOKIE_ID
;
1012 l2info
->cookie_len
+= 2;
1015 l2info
->cookie_type
= AS_COOKIE_ID
;
1016 l2info
->cookie_len
= 8;
1020 l2info
->bundle
= l2info
->cookie
[0];
1025 #ifdef DLT_JUNIPER_MFR
1026 /* MFR child links don't carry cookies */
1027 if (l2info
->pictype
== DLT_JUNIPER_MFR
&&
1028 (p
[0] & MFR_BE_MASK
) == MFR_BE_MASK
) {
1029 l2info
->cookie_len
= 0;
1033 l2info
->header_len
+= l2info
->cookie_len
;
1034 l2info
->length
-= l2info
->cookie_len
;
1035 l2info
->caplen
-= l2info
->cookie_len
;
1038 printf("%s-PIC, cookie-len %u",
1040 l2info
->cookie_len
);
1042 if (l2info
->cookie_len
> 0) {
1043 TCHECK2(p
[0],l2info
->cookie_len
);
1045 printf(", cookie 0x");
1046 for (idx
= 0; idx
< l2info
->cookie_len
; idx
++) {
1047 l2info
->cookie
[idx
] = p
[idx
]; /* copy cookie data */
1048 if (eflag
) printf("%02x",p
[idx
]);
1052 if (eflag
) printf(": "); /* print demarc b/w L2/L3*/
1055 l2info
->proto
= EXTRACT_16BITS(p
+l2info
->cookie_len
);
1060 p
+=l2info
->cookie_len
;
1062 /* DLT_ specific parsing */
1063 switch(l2info
->pictype
) {
1064 #ifdef DLT_JUNIPER_MLPPP
1065 case DLT_JUNIPER_MLPPP
:
1066 switch (l2info
->cookie_type
) {
1068 l2info
->bundle
= l2info
->cookie
[1];
1071 l2info
->bundle
= (EXTRACT_16BITS(&l2info
->cookie
[6])>>3)&0xfff;
1072 l2info
->proto
= (l2info
->cookie
[5])&JUNIPER_LSQ_L3_PROTO_MASK
;
1075 l2info
->bundle
= l2info
->cookie
[0];
1080 #ifdef DLT_JUNIPER_MLFR
1081 case DLT_JUNIPER_MLFR
:
1082 switch (l2info
->cookie_type
) {
1084 l2info
->bundle
= l2info
->cookie
[1];
1085 l2info
->proto
= EXTRACT_16BITS(p
);
1086 l2info
->header_len
+= 2;
1087 l2info
->length
-= 2;
1088 l2info
->caplen
-= 2;
1091 l2info
->bundle
= (EXTRACT_16BITS(&l2info
->cookie
[6])>>3)&0xfff;
1092 l2info
->proto
= (l2info
->cookie
[5])&JUNIPER_LSQ_L3_PROTO_MASK
;
1095 l2info
->bundle
= l2info
->cookie
[0];
1096 l2info
->header_len
+= 2;
1097 l2info
->length
-= 2;
1098 l2info
->caplen
-= 2;
1103 #ifdef DLT_JUNIPER_MFR
1104 case DLT_JUNIPER_MFR
:
1105 switch (l2info
->cookie_type
) {
1107 l2info
->bundle
= l2info
->cookie
[1];
1108 l2info
->proto
= EXTRACT_16BITS(p
);
1109 l2info
->header_len
+= 2;
1110 l2info
->length
-= 2;
1111 l2info
->caplen
-= 2;
1114 l2info
->bundle
= (EXTRACT_16BITS(&l2info
->cookie
[6])>>3)&0xfff;
1115 l2info
->proto
= (l2info
->cookie
[5])&JUNIPER_LSQ_L3_PROTO_MASK
;
1118 l2info
->bundle
= l2info
->cookie
[0];
1123 #ifdef DLT_JUNIPER_ATM2
1124 case DLT_JUNIPER_ATM2
:
1126 /* ATM cell relay control word present ? */
1127 if (l2info
->cookie
[7] & ATM2_PKT_TYPE_MASK
) {
1128 control_word
= EXTRACT_32BITS(p
);
1129 /* some control word heuristics */
1130 switch(control_word
) {
1131 case 0: /* zero control word */
1132 case 0x08000000: /* < JUNOS 7.4 control-word */
1133 case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/
1134 l2info
->header_len
+= 4;
1141 printf("control-word 0x%08x ", control_word
);
1145 #ifdef DLT_JUNIPER_ATM1
1146 case DLT_JUNIPER_ATM1
:
1149 #ifdef DLT_JUNIPER_PPP
1150 case DLT_JUNIPER_PPP
:
1153 #ifdef DLT_JUNIPER_CHDLC
1154 case DLT_JUNIPER_CHDLC
:
1157 #ifdef DLT_JUNIPER_ETHER
1158 case DLT_JUNIPER_ETHER
:
1161 #ifdef DLT_JUNIPER_FRELAY
1162 case DLT_JUNIPER_FRELAY
:
1167 printf("Unknown Juniper DLT_ type %u: ", l2info
->pictype
);
1172 printf("hlen %u, proto 0x%04x, ",l2info
->header_len
,l2info
->proto
);
1174 return 1; /* everything went ok so far. continue parsing */
1176 printf("[|juniper_hdr], length %u",h
->len
);
1183 * c-style: whitesmith