Deleted Added
sdiff udiff text old ( 146773 ) new ( 147899 )
full compact
1/*
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.
12 *
13 * Original code by Hannes Gredler (hannes@juniper.net)
14 */
15
16#ifndef lint
17static const char rcsid[] _U_ =
18 "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.8 2005/04/06 21:32:41 mcr Exp $ (LBL)";
19#endif
20
21#ifdef HAVE_CONFIG_H
22#include "config.h"
23#endif
24
25#include <tcpdump-stdinc.h>
26
27#include <pcap.h>
28#include <stdio.h>
29
30#include "interface.h"
31#include "extract.h"
32#include "ppp.h"
33#include "llc.h"
34#include "nlpid.h"
35
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 */
40
41#define LS_COOKIE_ID 0x54
42#define LS_MLFR_LEN 4
43#define ML_MLFR_LEN 2
44
45#define ATM2_PKT_TYPE_MASK 0x70
46#define ATM2_GAP_COUNT_MASK 0x3F
47
48int ip_heuristic_guess(register const u_char *, u_int);
49int juniper_ppp_heuristic_guess(register const u_char *, u_int);
50static int juniper_parse_header (const u_char *, u_int8_t *, u_int);
51
52u_int
53juniper_mlppp_print(const struct pcap_pkthdr *h, register const u_char *p)
54{
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;
59
60 if(juniper_parse_header(p, &direction,length) == 0)
61 return 0;
62
63 p+=4;
64 length-=4;
65 caplen-=4;
66
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;
72 } else {
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;
77 }
78
79 proto = EXTRACT_16BITS(p+cookie_len);
80 p += cookie_len;
81 length-= cookie_len;
82 caplen-= cookie_len;
83
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 */
86 if (eflag &&
87 cookie != PPP_OSI &&
88 cookie != (PPP_ADDRESS << 8 | PPP_CONTROL))
89 printf("Bundle-ID %u, ",bundle);
90
91 switch (cookie) {
92 case PPP_OSI:
93 ppp_print(p-2,length+2);
94 break;
95 case (PPP_ADDRESS << 8 | PPP_CONTROL): /* fall through */
96 default:
97 ppp_print(p,length);
98 break;
99 }
100
101 return cookie_len;
102}
103
104
105u_int
106juniper_mlfr_print(const struct pcap_pkthdr *h, register const u_char *p)
107{
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;
112
113 if(juniper_parse_header(p, &direction,length) == 0)
114 return 0;
115
116 p+=4;
117 length-=4;
118 caplen-=4;
119
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;
125 } else {
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;
130 }
131
132 proto = EXTRACT_16BITS(p+cookie_len);
133 p += cookie_len+2;
134 length-= cookie_len+2;
135 caplen-= cookie_len+2;
136
137 /* suppress Bundle-ID if frame was captured on a child-link */
138 if (eflag && cookie != 1) printf("Bundle-ID %u, ",bundle);
139
140 switch (proto) {
141 case (LLC_UI):
142 case (LLC_UI<<8):
143 isoclns_print(p, length, caplen);
144 break;
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 */
149 break;
150 default:
151 printf("unknown protocol 0x%04x, length %u",proto, length);
152 }
153
154 return cookie_len + frelay_len;
155}
156
157/*
158 * ATM1 PIC cookie format
159 *
160 * +-----+-------------------------+-------------------------------+
161 * |fmtid| vc index | channel ID |
162 * +-----+-------------------------+-------------------------------+
163 */
164
165u_int
166juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p)
167{
168 register u_int length = h->len;
169 register u_int caplen = h->caplen;
170 u_int16_t extracted_ethertype;
171 u_int8_t direction;
172 u_int32_t cookie1;
173
174 if(juniper_parse_header(p, &direction,length) == 0)
175 return 0;
176
177 p+=4;
178 length-=4;
179 caplen-=4;
180
181 cookie1=EXTRACT_32BITS(p);
182
183 if (eflag) {
184 /* FIXME decode channel-id, vc-index, fmt-id
185 for once lets just hexdump the cookie */
186
187 printf("ATM1 cookie 0x%08x, ", cookie1);
188 }
189
190 p+=4;
191 length-=4;
192 caplen-=4;
193
194 if ((cookie1 >> 24) == 0x80) { /* OAM cell ? */
195 oam_print(p,length);
196 return 0;
197 }
198
199 if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
200 EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
201
202 if (llc_print(p, length, caplen, NULL, NULL,
203 &extracted_ethertype) != 0)
204 return 8;
205 }
206
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 */
210 return 8;
211 }
212
213 if(ip_heuristic_guess(p, length) != 0) /* last try - vcmux encaps ? */
214 return 0;
215
216 return (8);
217}
218
219/*
220 * ATM2 PIC cookie format
221 *
222 * +-------------------------------+---------+---+-----+-----------+
223 * | channel ID | reserv |AAL| CCRQ| gap cnt |
224 * +-------------------------------+---------+---+-----+-----------+
225 */
226
227u_int
228juniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p)
229{
230 register u_int length = h->len;
231 register u_int caplen = h->caplen;
232 u_int16_t extracted_ethertype;
233 u_int8_t direction;
234 u_int32_t cookie1,cookie2;
235
236 if(juniper_parse_header(p, &direction,length) == 0)
237 return 0;
238
239 p+=4;
240 length-=4;
241 caplen-=4;
242
243 cookie1=EXTRACT_32BITS(p);
244 cookie2=EXTRACT_32BITS(p+4);
245
246 if (eflag) {
247 /* FIXME decode channel, fmt-id, ccrq, aal, gap cnt
248 for once lets just hexdump the cookie */
249
250 printf("ATM2 cookie 0x%08x%08x, ",
251 EXTRACT_32BITS(p),
252 EXTRACT_32BITS(p+4));
253 }
254
255 p+=8;
256 length-=8;
257 caplen-=8;
258
259 if (cookie2 & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */
260 oam_print(p,length);
261 return 12;
262 }
263
264 if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
265 EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
266
267 if (llc_print(p, length, caplen, NULL, NULL,
268 &extracted_ethertype) != 0)
269 return 12;
270 }
271
272 if (direction != JUNIPER_BPF_PKT_IN && /* ether-over-1483 encaps ? */
273 (cookie1 & ATM2_GAP_COUNT_MASK)) {
274 ether_print(p, length, caplen);
275 return 12;
276 }
277
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 */
281 return 12;
282 }
283
284 if(juniper_ppp_heuristic_guess(p, length) != 0) /* PPPoA vcmux encaps ? */
285 return 12;
286
287 if(ip_heuristic_guess(p, length) != 0) /* last try - vcmux encaps ? */
288 return 12;
289
290 return (12);
291}
292
293
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 */
296int
297juniper_ppp_heuristic_guess(register const u_char *p, u_int length) {
298
299 switch(EXTRACT_16BITS(p)) {
300 case PPP_IP :
301 case PPP_OSI :
302 case PPP_MPLS_UCAST :
303 case PPP_MPLS_MCAST :
304 case PPP_IPCP :
305 case PPP_OSICP :
306 case PPP_MPLSCP :
307 case PPP_LCP :
308 case PPP_PAP :
309 case PPP_CHAP :
310 case PPP_ML :
311#ifdef INET6
312 case PPP_IPV6 :
313 case PPP_IPV6CP :
314#endif
315 ppp_print(p, length);
316 break;
317
318 default:
319 return 0; /* did not find a ppp header */
320 break;
321 }
322 return 1; /* we printed a ppp packet */
323}
324
325int
326ip_heuristic_guess(register const u_char *p, u_int length) {
327
328 switch(p[0]) {
329 case 0x45:
330 case 0x46:
331 case 0x47:
332 case 0x48:
333 case 0x49:
334 case 0x4a:
335 case 0x4b:
336 case 0x4c:
337 case 0x4d:
338 case 0x4e:
339 case 0x4f:
340 ip_print(gndo, p, length);
341 break;
342#ifdef INET6
343 case 0x60:
344 case 0x61:
345 case 0x62:
346 case 0x63:
347 case 0x64:
348 case 0x65:
349 case 0x66:
350 case 0x67:
351 case 0x68:
352 case 0x69:
353 case 0x6a:
354 case 0x6b:
355 case 0x6c:
356 case 0x6d:
357 case 0x6e:
358 case 0x6f:
359 ip6_print(p, length);
360 break;
361#endif
362 default:
363 return 0; /* did not find a ip header */
364 break;
365 }
366 return 1; /* we printed an v4/v6 packet */
367}
368
369static int
370juniper_parse_header (const u_char *p, u_int8_t *direction, u_int length) {
371
372 *direction = p[3]&JUNIPER_BPF_PKT_IN;
373
374 if (EXTRACT_24BITS(p) != 0x4d4743) /* magic number found ? */
375 return -1;
376
377 if (*direction == JUNIPER_BPF_PKT_IN) {
378 if (eflag)
379 printf("%3s ", "In");
380 }
381 else {
382 if (eflag)
383 printf("%3s ", "Out");
384 }
385
386 if ((p[3] & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) {
387 if (eflag)
388 printf("no-L2-hdr, ");
389
390 /* there is no link-layer present -
391 * perform the v4/v6 heuristics
392 * to figure out what it is
393 */
394 if(ip_heuristic_guess(p+8,length-8) == 0)
395 printf("no IP-hdr found!");
396
397 return 0; /* stop parsing the output further */
398
399 }
400 return 1; /* everything went ok so far. continue parsing */
401}
402
403
404/*
405 * Local Variables:
406 * c-style: whitesmith
407 * c-basic-offset: 8
408 * End:
409 */