Expand PMF_FN_* macros.
[netbsd-mini2440.git] / dist / tcpdump / print-juniper.c
blob6cfbb136dc472901c5a36c5d252340b9bb240574
1 /* $NetBSD: print-juniper.c,v 1.2 2007/07/24 11:53:45 drochner Exp $ */
3 /*
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>
19 #ifndef lint
20 #if 0
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)";
23 #else
24 __RCSID("$NetBSD: print-juniper.c,v 1.2 2007/07/24 11:53:45 drochner Exp $");
25 #endif
26 #endif
28 #ifdef HAVE_CONFIG_H
29 #include "config.h"
30 #endif
32 #include <tcpdump-stdinc.h>
34 #include <pcap.h>
35 #include <stdio.h>
37 #include "interface.h"
38 #include "addrtoname.h"
39 #include "extract.h"
40 #include "ppp.h"
41 #include "llc.h"
42 #include "nlpid.h"
43 #include "ethertype.h"
44 #include "atm.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" },
75 { 0, NULL}
78 static struct tok juniper_direction_values[] = {
79 { JUNIPER_BPF_IN, "In"},
80 { JUNIPER_BPF_OUT, "Out"},
81 { 0, NULL}
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"},
93 #endif
94 #ifdef DLT_JUNIPER_ATM2
95 { DLT_JUNIPER_ATM2, 8, "ATM2"},
96 #endif
97 #ifdef DLT_JUNIPER_MLPPP
98 { DLT_JUNIPER_MLPPP, 2, "MLPPP"},
99 #endif
100 #ifdef DLT_JUNIPER_MLFR
101 { DLT_JUNIPER_MLFR, 2, "MLFR"},
102 #endif
103 #ifdef DLT_JUNIPER_MFR
104 { DLT_JUNIPER_MFR, 4, "MFR"},
105 #endif
106 #ifdef DLT_JUNIPER_PPPOE
107 { DLT_JUNIPER_PPPOE, 0, "PPPoE"},
108 #endif
109 #ifdef DLT_JUNIPER_PPPOE_ATM
110 { DLT_JUNIPER_PPPOE_ATM, 0, "PPPoE ATM"},
111 #endif
112 #ifdef DLT_JUNIPER_GGSN
113 { DLT_JUNIPER_GGSN, 8, "GGSN"},
114 #endif
115 #ifdef DLT_JUNIPER_MONITOR
116 { DLT_JUNIPER_MONITOR, 8, "MONITOR"},
117 #endif
118 #ifdef DLT_JUNIPER_SERVICES
119 { DLT_JUNIPER_SERVICES, 8, "AS"},
120 #endif
121 #ifdef DLT_JUNIPER_ES
122 { DLT_JUNIPER_ES, 0, "ES"},
123 #endif
124 { 0, 0, NULL }
127 struct juniper_l2info_t {
128 u_int32_t length;
129 u_int32_t caplen;
130 u_int32_t pictype;
131 u_int8_t direction;
132 u_int8_t header_len;
133 u_int8_t cookie_len;
134 u_int8_t cookie_type;
135 u_int8_t cookie[8];
136 u_int8_t bundle;
137 u_int16_t proto;
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" },
161 { 0, NULL}
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
169 u_int
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 {
174 u_int8_t svc_id;
175 u_int8_t flags_len;
176 u_int8_t proto;
177 u_int8_t flags;
178 u_int8_t vlan_id[2];
179 u_int8_t res[2];
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;
190 if (eflag)
191 printf("proto %s (%u), vlan %u: ",
192 tok2str(juniper_protocol_values,"Unknown",gh->proto),
193 gh->proto,
194 EXTRACT_16BITS(&gh->vlan_id[0]));
196 switch (gh->proto) {
197 case JUNIPER_PROTO_IPV4:
198 ip_print(gndo, p, l2info.length);
199 break;
200 #ifdef INET6
201 case JUNIPER_PROTO_IPV6:
202 ip6_print(p, l2info.length);
203 break;
204 #endif /* INET6 */
205 default:
206 if (!eflag)
207 printf("unknown GGSN proto (%u)", gh->proto);
210 return l2info.header_len;
212 #endif
214 #ifdef DLT_JUNIPER_ES
215 u_int
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];
221 u_int8_t ttl;
222 u_int8_t type;
223 u_int8_t spi[4];
224 u_int8_t src_ip[4];
225 u_int8_t dst_ip[4];
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;
237 switch (ih->type) {
238 case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE:
239 case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE:
240 rewrite_len = 0;
241 es_type_bundle = 1;
242 break;
243 case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE:
244 case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE:
245 case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE:
246 rewrite_len = 16;
247 es_type_bundle = 0;
248 default:
249 printf("ES Invalid type %u, length %u",
250 ih->type,
251 l2info.length);
252 return l2info.header_len;
255 l2info.length-=rewrite_len;
256 p+=rewrite_len;
258 if (eflag) {
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),
262 ih->ttl,
263 tok2str(juniper_ipsec_type_values,"Unknown",ih->type),
264 ih->type,
265 EXTRACT_32BITS(&ih->spi),
266 ipaddr_string(&ih->src_ip),
267 ipaddr_string(&ih->dst_ip),
268 l2info.length);
269 } else {
270 printf("ES SA, index %u, ttl %u type %s (%u), length %u\n",
271 EXTRACT_16BITS(&ih->sa_index),
272 ih->ttl,
273 tok2str(juniper_ipsec_type_values,"Unknown",ih->type),
274 ih->type,
275 l2info.length);
279 ip_print(gndo, p, l2info.length);
280 return l2info.header_len;
282 #endif
284 #ifdef DLT_JUNIPER_MONITOR
285 u_int
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 {
290 u_int8_t pkt_type;
291 u_int8_t padding;
292 u_int8_t iif[2];
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;
304 if (eflag)
305 printf("service-id %u, iif %u, pkt-type %u: ",
306 EXTRACT_32BITS(&mh->service_id),
307 EXTRACT_16BITS(&mh->iif),
308 mh->pkt_type);
310 /* no proto field - lets guess by first byte of IP header*/
311 ip_heuristic_guess(p, l2info.length);
313 return l2info.header_len;
315 #endif
317 #ifdef DLT_JUNIPER_SERVICES
318 u_int
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 {
323 u_int8_t svc_id;
324 u_int8_t flags_len;
325 u_int8_t svc_set_id[2];
326 u_int8_t dir_iif[4];
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;
337 if (eflag)
338 printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
339 sh->svc_id,
340 sh->flags_len,
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;
349 #endif
351 #ifdef DLT_JUNIPER_PPPOE
352 u_int
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;
366 #endif
368 #ifdef DLT_JUNIPER_ETHER
369 u_int
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;
383 #endif
385 #ifdef DLT_JUNIPER_PPP
386 u_int
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;
400 #endif
402 #ifdef DLT_JUNIPER_FRELAY
403 u_int
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;
417 #endif
419 #ifdef DLT_JUNIPER_CHDLC
420 u_int
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;
434 #endif
436 #ifdef DLT_JUNIPER_PPPOE_ATM
437 u_int
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,
453 p+ETHERTYPE_LEN,
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;
462 #endif
464 #ifdef DLT_JUNIPER_MLPPP
465 u_int
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 */
476 if (eflag &&
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);
491 else
492 ip_print(gndo, p, l2info.length);
493 return l2info.header_len;
494 #ifdef INET6
495 case JUNIPER_LSQ_L3_PROTO_IPV6:
496 ip6_print(p,l2info.length);
497 return l2info.header_len;
498 #endif
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;
505 default:
506 break;
509 /* zero length cookie ? */
510 switch (EXTRACT_16BITS(&l2info.cookie)) {
511 case PPP_OSI:
512 ppp_print(p-2,l2info.length+2);
513 break;
514 case (PPP_ADDRESS << 8 | PPP_CONTROL): /* fall through */
515 default:
516 ppp_print(p,l2info.length);
517 break;
520 return l2info.header_len;
522 #endif
525 #ifdef DLT_JUNIPER_MFR
526 u_int
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;
537 /* child-link ? */
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;
549 #ifdef INET6
550 case JUNIPER_LSQ_L3_PROTO_IPV6:
551 ip6_print(p,l2info.length);
552 return l2info.header_len;
553 #endif
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;
560 default:
561 break;
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);
571 break;
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);
577 break;
578 default:
579 printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length);
582 return l2info.header_len;
584 #endif
586 #ifdef DLT_JUNIPER_MLFR
587 u_int
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) {
601 case (LLC_UI):
602 case (LLC_UI<<8):
603 isoclns_print(p, l2info.length, l2info.caplen);
604 break;
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);
610 break;
611 default:
612 printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length);
615 return l2info.header_len;
617 #endif
620 * ATM1 PIC cookie format
622 * +-----+-------------------------+-------------------------------+
623 * |fmtid| vc index | channel ID |
624 * +-----+-------------------------+-------------------------------+
627 #ifdef DLT_JUNIPER_ATM1
628 u_int
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;
665 #endif
668 * ATM2 PIC cookie format
670 * +-------------------------------+---------+---+-----+-----------+
671 * | channel ID | reserv |AAL| CCRQ| gap cnt |
672 * +-------------------------------+---------+---+-----+-----------+
675 #ifdef DLT_JUNIPER_ATM2
676 u_int
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;
722 #endif
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)) {
731 case PPP_IP :
732 case PPP_OSI :
733 case PPP_MPLS_UCAST :
734 case PPP_MPLS_MCAST :
735 case PPP_IPCP :
736 case PPP_OSICP :
737 case PPP_MPLSCP :
738 case PPP_LCP :
739 case PPP_PAP :
740 case PPP_CHAP :
741 case PPP_ML :
742 #ifdef INET6
743 case PPP_IPV6 :
744 case PPP_IPV6CP :
745 #endif
746 ppp_print(p, length);
747 break;
749 default:
750 return 0; /* did not find a ppp header */
751 break;
753 return 1; /* we printed a ppp packet */
757 ip_heuristic_guess(register const u_char *p, u_int length) {
759 switch(p[0]) {
760 case 0x45:
761 case 0x46:
762 case 0x47:
763 case 0x48:
764 case 0x49:
765 case 0x4a:
766 case 0x4b:
767 case 0x4c:
768 case 0x4d:
769 case 0x4e:
770 case 0x4f:
771 ip_print(gndo, p, length);
772 break;
773 #ifdef INET6
774 case 0x60:
775 case 0x61:
776 case 0x62:
777 case 0x63:
778 case 0x64:
779 case 0x65:
780 case 0x66:
781 case 0x67:
782 case 0x68:
783 case 0x69:
784 case 0x6a:
785 case 0x6b:
786 case 0x6c:
787 case 0x6d:
788 case 0x6e:
789 case 0x6f:
790 ip6_print(p, length);
791 break;
792 #endif
793 default:
794 return 0; /* did not find a ip header */
795 break;
797 return 1; /* we printed an v4/v6 packet */
800 static int
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;
804 u_int idx, offset;
805 #ifdef DLT_JUNIPER_ATM2
806 u_int32_t control_word;
807 #endif
809 l2info->header_len = 0;
810 l2info->cookie_len = 0;
811 l2info->proto = 0;
814 l2info->length = h->len;
815 l2info->caplen = h->caplen;
816 l2info->direction = p[3]&JUNIPER_BPF_PKT_IN;
818 TCHECK2(p[0],4);
819 if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */
820 printf("no magic-number found!");
821 return 0;
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);
830 if (eflag>1)
831 printf("ext-len %u, ",EXTRACT_16BITS(p+4));
832 } else
833 offset = 4;
835 if ((p[3] & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) {
836 if (eflag)
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;
862 switch (p[0]) {
863 case LS_COOKIE_ID:
864 l2info->cookie_type = LS_COOKIE_ID;
865 l2info->cookie_len += 2;
866 break;
867 case AS_COOKIE_ID:
868 l2info->cookie_type = AS_COOKIE_ID;
869 l2info->cookie_len = 8;
870 break;
872 default:
873 l2info->bundle = l2info->cookie[0];
874 break;
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;
884 #endif
886 l2info->header_len += l2info->cookie_len;
887 l2info->length -= l2info->cookie_len;
888 l2info->caplen -= l2info->cookie_len;
890 if (eflag)
891 printf("%s-PIC, cookie-len %u",
892 lp->s,
893 l2info->cookie_len);
895 if (l2info->cookie_len > 0) {
896 TCHECK2(p[0],l2info->cookie_len);
897 if (eflag)
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);
909 break;
911 ++lp;
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) {
920 case LS_COOKIE_ID:
921 l2info->bundle = l2info->cookie[1];
922 break;
923 case AS_COOKIE_ID:
924 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
925 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
926 break;
927 default:
928 l2info->bundle = l2info->cookie[0];
929 break;
931 break;
932 #endif
933 #ifdef DLT_JUNIPER_MLFR
934 case DLT_JUNIPER_MLFR:
935 switch (l2info->cookie_type) {
936 case LS_COOKIE_ID:
937 l2info->bundle = l2info->cookie[1];
938 l2info->proto = EXTRACT_16BITS(p);
939 l2info->header_len += 2;
940 l2info->length -= 2;
941 l2info->caplen -= 2;
942 break;
943 case AS_COOKIE_ID:
944 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
945 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
946 break;
947 default:
948 l2info->bundle = l2info->cookie[0];
949 l2info->header_len += 2;
950 l2info->length -= 2;
951 l2info->caplen -= 2;
952 break;
954 break;
955 #endif
956 #ifdef DLT_JUNIPER_MFR
957 case DLT_JUNIPER_MFR:
958 switch (l2info->cookie_type) {
959 case LS_COOKIE_ID:
960 l2info->bundle = l2info->cookie[1];
961 l2info->proto = EXTRACT_16BITS(p);
962 l2info->header_len += 2;
963 l2info->length -= 2;
964 l2info->caplen -= 2;
965 break;
966 case AS_COOKIE_ID:
967 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
968 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
969 break;
970 default:
971 l2info->bundle = l2info->cookie[0];
972 break;
974 break;
975 #endif
976 #ifdef DLT_JUNIPER_ATM2
977 case DLT_JUNIPER_ATM2:
978 TCHECK2(p[0],4);
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;
988 break;
989 default:
990 break;
993 if (eflag)
994 printf("control-word 0x%08x ", control_word);
996 break;
997 #endif
998 #ifdef DLT_JUNIPER_ATM1
999 case DLT_JUNIPER_ATM1:
1000 break;
1001 #endif
1002 #ifdef DLT_JUNIPER_PPP
1003 case DLT_JUNIPER_PPP:
1004 break;
1005 #endif
1006 #ifdef DLT_JUNIPER_CHDLC
1007 case DLT_JUNIPER_CHDLC:
1008 break;
1009 #endif
1010 #ifdef DLT_JUNIPER_ETHER
1011 case DLT_JUNIPER_ETHER:
1012 break;
1013 #endif
1014 #ifdef DLT_JUNIPER_FRELAY
1015 case DLT_JUNIPER_FRELAY:
1016 break;
1017 #endif
1019 default:
1020 printf("Unknown Juniper DLT_ type %u: ", l2info->pictype);
1021 break;
1024 if (eflag > 1)
1025 printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto);
1027 return 1; /* everything went ok so far. continue parsing */
1028 trunc:
1029 printf("[|juniper_hdr], length %u",h->len);
1030 return 0;
1035 * Local Variables:
1036 * c-style: whitesmith
1037 * c-basic-offset: 4
1038 * End: