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 2005-04-06 21:32:41 mcr Exp $ (LBL)";
25 #include <tcpdump-stdinc.h>
30 #include "interface.h"
36 #define JUNIPER_BPF_OUT 0 /* Outgoing packet */
37 #define JUNIPER_BPF_IN 1 /* Incoming packet */
38 #define JUNIPER_BPF_PKT_IN 0x1 /* Incoming packet */
39 #define JUNIPER_BPF_NO_L2 0x2 /* L2 header stripped */
41 #define LS_COOKIE_ID 0x54
45 #define ATM2_PKT_TYPE_MASK 0x70
46 #define ATM2_GAP_COUNT_MASK 0x3F
48 int ip_heuristic_guess(register const u_char
*, u_int
);
49 int juniper_ppp_heuristic_guess(register const u_char
*, u_int
);
50 static int juniper_parse_header (const u_char
*, u_int8_t
*, u_int
);
53 juniper_mlppp_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
55 register u_int length
= h
->len
;
56 register u_int caplen
= h
->caplen
;
57 u_int8_t direction
,bundle
,cookie_len
;
58 u_int32_t cookie
,proto
;
60 if(juniper_parse_header(p
, &direction
,length
) == 0)
67 if (p
[0] == LS_COOKIE_ID
) {
68 cookie
=EXTRACT_32BITS(p
);
69 if (eflag
) printf("LSPIC-MLPPP cookie 0x%08x, ",cookie
);
70 cookie_len
= LS_MLFR_LEN
;
71 bundle
= cookie
& 0xff;
73 cookie
=EXTRACT_16BITS(p
);
74 if (eflag
) printf("MLPIC-MLPPP cookie 0x%04x, ",cookie
);
75 cookie_len
= ML_MLFR_LEN
;
76 bundle
= (cookie
>> 8) & 0xff;
79 proto
= EXTRACT_16BITS(p
+cookie_len
);
84 /* suppress Bundle-ID if frame was captured on a child-link
85 * this may be the case if the cookie looks like a proto */
88 cookie
!= (PPP_ADDRESS
<< 8 | PPP_CONTROL
))
89 printf("Bundle-ID %u, ",bundle
);
93 ppp_print(p
-2,length
+2);
95 case (PPP_ADDRESS
<< 8 | PPP_CONTROL
): /* fall through */
106 juniper_mlfr_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
108 register u_int length
= h
->len
;
109 register u_int caplen
= h
->caplen
;
110 u_int8_t direction
,bundle
,cookie_len
;
111 u_int32_t cookie
,proto
,frelay_len
= 0;
113 if(juniper_parse_header(p
, &direction
,length
) == 0)
120 if (p
[0] == LS_COOKIE_ID
) {
121 cookie
=EXTRACT_32BITS(p
);
122 if (eflag
) printf("LSPIC-MLFR cookie 0x%08x, ",cookie
);
123 cookie_len
= LS_MLFR_LEN
;
124 bundle
= cookie
& 0xff;
126 cookie
=EXTRACT_16BITS(p
);
127 if (eflag
) printf("MLPIC-MLFR cookie 0x%04x, ",cookie
);
128 cookie_len
= ML_MLFR_LEN
;
129 bundle
= (cookie
>> 8) & 0xff;
132 proto
= EXTRACT_16BITS(p
+cookie_len
);
134 length
-= cookie_len
+2;
135 caplen
-= cookie_len
+2;
137 /* suppress Bundle-ID if frame was captured on a child-link */
138 if (eflag
&& cookie
!= 1) printf("Bundle-ID %u, ",bundle
);
143 isoclns_print(p
, length
, caplen
);
145 case (LLC_UI
<<8 | NLPID_Q933
):
146 case (LLC_UI
<<8 | NLPID_IP
):
147 case (LLC_UI
<<8 | NLPID_IP6
):
148 isoclns_print(p
-1, length
+1, caplen
+1); /* pass IP{4,6} to the OSI layer for proper link-layer printing */
151 printf("unknown protocol 0x%04x, length %u",proto
, length
);
154 return cookie_len
+ frelay_len
;
158 * ATM1 PIC cookie format
160 * +-----+-------------------------+-------------------------------+
161 * |fmtid| vc index | channel ID |
162 * +-----+-------------------------+-------------------------------+
166 juniper_atm1_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
168 register u_int length
= h
->len
;
169 register u_int caplen
= h
->caplen
;
170 u_int16_t extracted_ethertype
;
174 if(juniper_parse_header(p
, &direction
,length
) == 0)
181 cookie1
=EXTRACT_32BITS(p
);
184 /* FIXME decode channel-id, vc-index, fmt-id
185 for once lets just hexdump the cookie */
187 printf("ATM1 cookie 0x%08x, ", cookie1
);
194 if ((cookie1
>> 24) == 0x80) { /* OAM cell ? */
199 if (EXTRACT_24BITS(p
) == 0xfefe03 || /* NLPID encaps ? */
200 EXTRACT_24BITS(p
) == 0xaaaa03) { /* SNAP encaps ? */
202 if (llc_print(p
, length
, caplen
, NULL
, NULL
,
203 &extracted_ethertype
) != 0)
207 if (p
[0] == 0x03) { /* Cisco style NLPID encaps ? */
208 isoclns_print(p
+ 1, length
- 1, caplen
- 1);
209 /* FIXME check if frame was recognized */
213 if(ip_heuristic_guess(p
, length
) != 0) /* last try - vcmux encaps ? */
220 * ATM2 PIC cookie format
222 * +-------------------------------+---------+---+-----+-----------+
223 * | channel ID | reserv |AAL| CCRQ| gap cnt |
224 * +-------------------------------+---------+---+-----+-----------+
228 juniper_atm2_print(const struct pcap_pkthdr
*h
, register const u_char
*p
)
230 register u_int length
= h
->len
;
231 register u_int caplen
= h
->caplen
;
232 u_int16_t extracted_ethertype
;
234 u_int32_t cookie1
,cookie2
;
236 if(juniper_parse_header(p
, &direction
,length
) == 0)
243 cookie1
=EXTRACT_32BITS(p
);
244 cookie2
=EXTRACT_32BITS(p
+4);
247 /* FIXME decode channel, fmt-id, ccrq, aal, gap cnt
248 for once lets just hexdump the cookie */
250 printf("ATM2 cookie 0x%08x%08x, ",
252 EXTRACT_32BITS(p
+4));
259 if (cookie2
& ATM2_PKT_TYPE_MASK
) { /* OAM cell ? */
264 if (EXTRACT_24BITS(p
) == 0xfefe03 || /* NLPID encaps ? */
265 EXTRACT_24BITS(p
) == 0xaaaa03) { /* SNAP encaps ? */
267 if (llc_print(p
, length
, caplen
, NULL
, NULL
,
268 &extracted_ethertype
) != 0)
272 if (direction
!= JUNIPER_BPF_PKT_IN
&& /* ether-over-1483 encaps ? */
273 (cookie1
& ATM2_GAP_COUNT_MASK
)) {
274 ether_print(p
, length
, caplen
);
278 if (p
[0] == 0x03) { /* Cisco style NLPID encaps ? */
279 isoclns_print(p
+ 1, length
- 1, caplen
- 1);
280 /* FIXME check if frame was recognized */
284 if(juniper_ppp_heuristic_guess(p
, length
) != 0) /* PPPoA vcmux encaps ? */
287 if(ip_heuristic_guess(p
, length
) != 0) /* last try - vcmux encaps ? */
294 /* try to guess, based on all PPP protos that are supported in
295 * a juniper router if the payload data is encapsulated using PPP */
297 juniper_ppp_heuristic_guess(register const u_char
*p
, u_int length
) {
299 switch(EXTRACT_16BITS(p
)) {
302 case PPP_MPLS_UCAST
:
303 case PPP_MPLS_MCAST
:
315 ppp_print(p
, length
);
319 return 0; /* did not find a ppp header */
322 return 1; /* we printed a ppp packet */
326 ip_heuristic_guess(register const u_char
*p
, u_int length
) {
340 ip_print(gndo
, p
, length
);
359 ip6_print(p
, length
);
363 return 0; /* did not find a ip header */
366 return 1; /* we printed an v4/v6 packet */
370 juniper_parse_header (const u_char
*p
, u_int8_t
*direction
, u_int length
) {
372 *direction
= p
[3]&JUNIPER_BPF_PKT_IN
;
374 if (EXTRACT_24BITS(p
) != 0x4d4743) /* magic number found ? */
377 if (*direction
== JUNIPER_BPF_PKT_IN
) {
379 printf("%3s ", "In");
383 printf("%3s ", "Out");
386 if ((p
[3] & JUNIPER_BPF_NO_L2
) == JUNIPER_BPF_NO_L2
) {
388 printf("no-L2-hdr, ");
390 /* there is no link-layer present -
391 * perform the v4/v6 heuristics
392 * to figure out what it is
394 if(ip_heuristic_guess(p
+8,length
-8) == 0)
395 printf("no IP-hdr found!");
397 return 0; /* stop parsing the output further */
400 return 1; /* everything went ok so far. continue parsing */
406 * c-style: whitesmith