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 (at) juniper.net) 14 */ 15 16 #ifndef lint 17 static const char rcsid[] _U_ = 18 "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.8.2.22 2006/05/10 22:42:46 guy 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 "addrtoname.h" 32 #include "extract.h" 33 #include "ppp.h" 34 #include "llc.h" 35 #include "nlpid.h" 36 #include "ethertype.h" 37 #include "atm.h" 38 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_EXT 0x80 /* extensions present */ 44 #define JUNIPER_MGC_NUMBER 0x4d4743 /* = "MGC" */ 45 46 #define JUNIPER_LSQ_COOKIE_RE (1 << 3) 47 #define JUNIPER_LSQ_COOKIE_DIR (1 << 2) 48 #define JUNIPER_LSQ_L3_PROTO_SHIFT 4 49 #define JUNIPER_LSQ_L3_PROTO_MASK (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT) 50 #define JUNIPER_LSQ_L3_PROTO_IPV4 (0 << JUNIPER_LSQ_L3_PROTO_SHIFT) 51 #define JUNIPER_LSQ_L3_PROTO_IPV6 (1 << JUNIPER_LSQ_L3_PROTO_SHIFT) 52 #define JUNIPER_LSQ_L3_PROTO_MPLS (2 << JUNIPER_LSQ_L3_PROTO_SHIFT) 53 #define JUNIPER_LSQ_L3_PROTO_ISO (3 << JUNIPER_LSQ_L3_PROTO_SHIFT) 54 #define AS_PIC_COOKIE_LEN 8 55 56 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1 57 #define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2 58 #define JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE 3 59 #define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4 60 #define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5 61 62 static struct tok juniper_ipsec_type_values[] = { 63 { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE, "ESP ENCR-AUTH" }, 64 { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE, "ESP ENCR-AH AUTH" }, 65 { JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE, "ESP AUTH" }, 66 { JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE, "AH AUTH" }, 67 { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE, "ESP ENCR" }, 68 { 0, NULL} 69 }; 70 71 static struct tok juniper_direction_values[] = { 72 { JUNIPER_BPF_IN, "In"}, 73 { JUNIPER_BPF_OUT, "Out"}, 74 { 0, NULL} 75 }; 76 77 struct juniper_cookie_table_t { 78 u_int32_t pictype; /* pic type */ 79 u_int8_t cookie_len; /* cookie len */ 80 const char *s; /* pic name */ 81 }; 82 83 static struct juniper_cookie_table_t juniper_cookie_table[] = { 84 #ifdef DLT_JUNIPER_ATM1 85 { DLT_JUNIPER_ATM1, 4, "ATM1"}, 86 #endif 87 #ifdef DLT_JUNIPER_ATM2 88 { DLT_JUNIPER_ATM2, 8, "ATM2"}, 89 #endif 90 #ifdef DLT_JUNIPER_MLPPP 91 { DLT_JUNIPER_MLPPP, 2, "MLPPP"}, 92 #endif 93 #ifdef DLT_JUNIPER_MLFR 94 { DLT_JUNIPER_MLFR, 2, "MLFR"}, 95 #endif 96 #ifdef DLT_JUNIPER_MFR 97 { DLT_JUNIPER_MFR, 4, "MFR"}, 98 #endif 99 #ifdef DLT_JUNIPER_PPPOE 100 { DLT_JUNIPER_PPPOE, 0, "PPPoE"}, 101 #endif 102 #ifdef DLT_JUNIPER_PPPOE_ATM 103 { DLT_JUNIPER_PPPOE_ATM, 0, "PPPoE ATM"}, 104 #endif 105 #ifdef DLT_JUNIPER_GGSN 106 { DLT_JUNIPER_GGSN, 8, "GGSN"}, 107 #endif 108 #ifdef DLT_JUNIPER_MONITOR 109 { DLT_JUNIPER_MONITOR, 8, "MONITOR"}, 110 #endif 111 #ifdef DLT_JUNIPER_SERVICES 112 { DLT_JUNIPER_SERVICES, 8, "AS"}, 113 #endif 114 #ifdef DLT_JUNIPER_ES 115 { DLT_JUNIPER_ES, 0, "ES"}, 116 #endif 117 { 0, 0, NULL } 118 }; 119 120 struct juniper_l2info_t { 121 u_int32_t length; 122 u_int32_t caplen; 123 u_int32_t pictype; 124 u_int8_t direction; 125 u_int8_t header_len; 126 u_int8_t cookie_len; 127 u_int8_t cookie_type; 128 u_int8_t cookie[8]; 129 u_int8_t bundle; 130 u_int16_t proto; 131 }; 132 133 #define LS_COOKIE_ID 0x54 134 #define AS_COOKIE_ID 0x47 135 #define LS_MLFR_COOKIE_LEN 4 136 #define ML_MLFR_COOKIE_LEN 2 137 #define LS_MFR_COOKIE_LEN 6 138 #define ATM1_COOKIE_LEN 4 139 #define ATM2_COOKIE_LEN 8 140 141 #define ATM2_PKT_TYPE_MASK 0x70 142 #define ATM2_GAP_COUNT_MASK 0x3F 143 144 #define JUNIPER_PROTO_NULL 1 145 #define JUNIPER_PROTO_IPV4 2 146 #define JUNIPER_PROTO_IPV6 6 147 148 #define MFR_BE_MASK 0xc0 149 150 static struct tok juniper_protocol_values[] = { 151 { JUNIPER_PROTO_NULL, "Null" }, 152 { JUNIPER_PROTO_IPV4, "IPv4" }, 153 { JUNIPER_PROTO_IPV6, "IPv6" }, 154 { 0, NULL} 155 }; 156 157 int ip_heuristic_guess(register const u_char *, u_int); 158 int juniper_ppp_heuristic_guess(register const u_char *, u_int); 159 static int juniper_parse_header (const u_char *, const struct pcap_pkthdr *, struct juniper_l2info_t *); 160 161 #ifdef DLT_JUNIPER_GGSN 162 u_int 163 juniper_ggsn_print(const struct pcap_pkthdr *h, register const u_char *p) 164 { 165 struct juniper_l2info_t l2info; 166 struct juniper_ggsn_header { 167 u_int8_t svc_id; 168 u_int8_t flags_len; 169 u_int8_t proto; 170 u_int8_t flags; 171 u_int8_t vlan_id[2]; 172 u_int8_t res[2]; 173 }; 174 const struct juniper_ggsn_header *gh; 175 176 l2info.pictype = DLT_JUNIPER_GGSN; 177 if(juniper_parse_header(p, h, &l2info) == 0) 178 return l2info.header_len; 179 180 p+=l2info.header_len; 181 gh = (struct juniper_ggsn_header *)p; 182 183 if (eflag) 184 printf("proto %s (%u), vlan %u: ", 185 tok2str(juniper_protocol_values,"Unknown",gh->proto), 186 gh->proto, 187 EXTRACT_16BITS(&gh->vlan_id[0])); 188 189 switch (gh->proto) { 190 case JUNIPER_PROTO_IPV4: 191 ip_print(gndo, p, l2info.length); 192 break; 193 #ifdef INET6 194 case JUNIPER_PROTO_IPV6: 195 ip6_print(p, l2info.length); 196 break; 197 #endif /* INET6 */ 198 default: 199 if (!eflag) 200 printf("unknown GGSN proto (%u)", gh->proto); 201 } 202 203 return l2info.header_len; 204 } 205 #endif 206 207 #ifdef DLT_JUNIPER_ES 208 u_int 209 juniper_es_print(const struct pcap_pkthdr *h, register const u_char *p) 210 { 211 struct juniper_l2info_t l2info; 212 struct juniper_ipsec_header { 213 u_int8_t sa_index[2]; 214 u_int8_t ttl; 215 u_int8_t type; 216 u_int8_t spi[4]; 217 u_int8_t src_ip[4]; 218 u_int8_t dst_ip[4]; 219 }; 220 u_int rewrite_len,es_type_bundle; 221 const struct juniper_ipsec_header *ih; 222 223 l2info.pictype = DLT_JUNIPER_ES; 224 if(juniper_parse_header(p, h, &l2info) == 0) 225 return l2info.header_len; 226 227 p+=l2info.header_len; 228 ih = (struct juniper_ipsec_header *)p; 229 230 switch (ih->type) { 231 case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE: 232 case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE: 233 rewrite_len = 0; 234 es_type_bundle = 1; 235 break; 236 case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE: 237 case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE: 238 case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE: 239 rewrite_len = 16; 240 es_type_bundle = 0; 241 default: 242 printf("ES Invalid type %u, length %u", 243 ih->type, 244 l2info.length); 245 return l2info.header_len; 246 } 247 248 l2info.length-=rewrite_len; 249 p+=rewrite_len; 250 251 if (eflag) { 252 if (!es_type_bundle) { 253 printf("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n", 254 EXTRACT_16BITS(&ih->sa_index), 255 ih->ttl, 256 tok2str(juniper_ipsec_type_values,"Unknown",ih->type), 257 ih->type, 258 EXTRACT_32BITS(&ih->spi), 259 ipaddr_string(EXTRACT_32BITS(&ih->src_ip)), 260 ipaddr_string(EXTRACT_32BITS(&ih->dst_ip)), 261 l2info.length); 262 } else { 263 printf("ES SA, index %u, ttl %u type %s (%u), length %u\n", 264 EXTRACT_16BITS(&ih->sa_index), 265 ih->ttl, 266 tok2str(juniper_ipsec_type_values,"Unknown",ih->type), 267 ih->type, 268 l2info.length); 269 } 270 } 271 272 ip_print(gndo, p, l2info.length); 273 return l2info.header_len; 274 } 275 #endif 276 277 #ifdef DLT_JUNIPER_MONITOR 278 u_int 279 juniper_monitor_print(const struct pcap_pkthdr *h, register const u_char *p) 280 { 281 struct juniper_l2info_t l2info; 282 struct juniper_monitor_header { 283 u_int8_t pkt_type; 284 u_int8_t padding; 285 u_int8_t iif[2]; 286 u_int8_t service_id[4]; 287 }; 288 const struct juniper_monitor_header *mh; 289 290 l2info.pictype = DLT_JUNIPER_MONITOR; 291 if(juniper_parse_header(p, h, &l2info) == 0) 292 return l2info.header_len; 293 294 p+=l2info.header_len; 295 mh = (struct juniper_monitor_header *)p; 296 297 if (eflag) 298 printf("service-id %u, iif %u, pkt-type %u: ", 299 EXTRACT_32BITS(&mh->service_id), 300 EXTRACT_16BITS(&mh->iif), 301 mh->pkt_type); 302 303 /* no proto field - lets guess by first byte of IP header*/ 304 ip_heuristic_guess(p, l2info.length); 305 306 return l2info.header_len; 307 } 308 #endif 309 310 #ifdef DLT_JUNIPER_SERVICES 311 u_int 312 juniper_services_print(const struct pcap_pkthdr *h, register const u_char *p) 313 { 314 struct juniper_l2info_t l2info; 315 struct juniper_services_header { 316 u_int8_t svc_id; 317 u_int8_t flags_len; 318 u_int8_t svc_set_id[2]; 319 u_int8_t dir_iif[4]; 320 }; 321 const struct juniper_services_header *sh; 322 323 l2info.pictype = DLT_JUNIPER_SERVICES; 324 if(juniper_parse_header(p, h, &l2info) == 0) 325 return l2info.header_len; 326 327 p+=l2info.header_len; 328 sh = (struct juniper_services_header *)p; 329 330 if (eflag) 331 printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ", 332 sh->svc_id, 333 sh->flags_len, 334 EXTRACT_16BITS(&sh->svc_set_id), 335 EXTRACT_24BITS(&sh->dir_iif[1])); 336 337 /* no proto field - lets guess by first byte of IP header*/ 338 ip_heuristic_guess(p, l2info.length); 339 340 return l2info.header_len; 341 } 342 #endif 343 344 #ifdef DLT_JUNIPER_PPPOE 345 u_int 346 juniper_pppoe_print(const struct pcap_pkthdr *h, register const u_char *p) 347 { 348 struct juniper_l2info_t l2info; 349 350 l2info.pictype = DLT_JUNIPER_PPPOE; 351 if(juniper_parse_header(p, h, &l2info) == 0) 352 return l2info.header_len; 353 354 p+=l2info.header_len; 355 /* this DLT contains nothing but raw ethernet frames */ 356 ether_print(p, l2info.length, l2info.caplen); 357 return l2info.header_len; 358 } 359 #endif 360 361 #ifdef DLT_JUNIPER_ETHER 362 u_int 363 juniper_ether_print(const struct pcap_pkthdr *h, register const u_char *p) 364 { 365 struct juniper_l2info_t l2info; 366 367 l2info.pictype = DLT_JUNIPER_ETHER; 368 if(juniper_parse_header(p, h, &l2info) == 0) 369 return l2info.header_len; 370 371 p+=l2info.header_len; 372 /* this DLT contains nothing but raw Ethernet frames */ 373 ether_print(p, l2info.length, l2info.caplen); 374 return l2info.header_len; 375 } 376 #endif 377 378 #ifdef DLT_JUNIPER_PPP 379 u_int 380 juniper_ppp_print(const struct pcap_pkthdr *h, register const u_char *p) 381 { 382 struct juniper_l2info_t l2info; 383 384 l2info.pictype = DLT_JUNIPER_PPP; 385 if(juniper_parse_header(p, h, &l2info) == 0) 386 return l2info.header_len; 387 388 p+=l2info.header_len; 389 /* this DLT contains nothing but raw ppp frames */ 390 ppp_print(p, l2info.length); 391 return l2info.header_len; 392 } 393 #endif 394 395 #ifdef DLT_JUNIPER_FRELAY 396 u_int 397 juniper_frelay_print(const struct pcap_pkthdr *h, register const u_char *p) 398 { 399 struct juniper_l2info_t l2info; 400 401 l2info.pictype = DLT_JUNIPER_FRELAY; 402 if(juniper_parse_header(p, h, &l2info) == 0) 403 return l2info.header_len; 404 405 p+=l2info.header_len; 406 /* this DLT contains nothing but raw frame-relay frames */ 407 fr_print(p, l2info.length); 408 return l2info.header_len; 409 } 410 #endif 411 412 #ifdef DLT_JUNIPER_CHDLC 413 u_int 414 juniper_chdlc_print(const struct pcap_pkthdr *h, register const u_char *p) 415 { 416 struct juniper_l2info_t l2info; 417 418 l2info.pictype = DLT_JUNIPER_CHDLC; 419 if(juniper_parse_header(p, h, &l2info) == 0) 420 return l2info.header_len; 421 422 p+=l2info.header_len; 423 /* this DLT contains nothing but raw c-hdlc frames */ 424 chdlc_print(p, l2info.length); 425 return l2info.header_len; 426 } 427 #endif 428 429 #ifdef DLT_JUNIPER_PPPOE_ATM 430 u_int 431 juniper_pppoe_atm_print(const struct pcap_pkthdr *h, register const u_char *p) 432 { 433 struct juniper_l2info_t l2info; 434 u_int16_t extracted_ethertype; 435 436 l2info.pictype = DLT_JUNIPER_PPPOE_ATM; 437 if(juniper_parse_header(p, h, &l2info) == 0) 438 return l2info.header_len; 439 440 p+=l2info.header_len; 441 442 extracted_ethertype = EXTRACT_16BITS(p); 443 /* this DLT contains nothing but raw PPPoE frames, 444 * prepended with a type field*/ 445 if (ether_encap_print(extracted_ethertype, 446 p+ETHERTYPE_LEN, 447 l2info.length-ETHERTYPE_LEN, 448 l2info.caplen-ETHERTYPE_LEN, 449 &extracted_ethertype) == 0) 450 /* ether_type not known, probably it wasn't one */ 451 printf("unknown ethertype 0x%04x", extracted_ethertype); 452 453 return l2info.header_len; 454 } 455 #endif 456 457 #ifdef DLT_JUNIPER_MLPPP 458 u_int 459 juniper_mlppp_print(const struct pcap_pkthdr *h, register const u_char *p) 460 { 461 struct juniper_l2info_t l2info; 462 463 l2info.pictype = DLT_JUNIPER_MLPPP; 464 if(juniper_parse_header(p, h, &l2info) == 0) 465 return l2info.header_len; 466 467 /* suppress Bundle-ID if frame was captured on a child-link 468 * best indicator if the cookie looks like a proto */ 469 if (eflag && 470 EXTRACT_16BITS(&l2info.cookie) != PPP_OSI && 471 EXTRACT_16BITS(&l2info.cookie) != (PPP_ADDRESS << 8 | PPP_CONTROL)) 472 printf("Bundle-ID %u: ",l2info.bundle); 473 474 p+=l2info.header_len; 475 476 /* first try the LSQ protos */ 477 switch(l2info.proto) { 478 case JUNIPER_LSQ_L3_PROTO_IPV4: 479 /* IP traffic going to the RE would not have a cookie 480 * -> this must be incoming IS-IS over PPP 481 */ 482 if (l2info.cookie[4] == (JUNIPER_LSQ_COOKIE_RE|JUNIPER_LSQ_COOKIE_DIR)) 483 ppp_print(p, l2info.length); 484 else 485 ip_print(gndo, p, l2info.length); 486 return l2info.header_len; 487 #ifdef INET6 488 case JUNIPER_LSQ_L3_PROTO_IPV6: 489 ip6_print(p,l2info.length); 490 return l2info.header_len; 491 #endif 492 case JUNIPER_LSQ_L3_PROTO_MPLS: 493 mpls_print(p,l2info.length); 494 return l2info.header_len; 495 case JUNIPER_LSQ_L3_PROTO_ISO: 496 isoclns_print(p,l2info.length,l2info.caplen); 497 return l2info.header_len; 498 default: 499 break; 500 } 501 502 /* zero length cookie ? */ 503 switch (EXTRACT_16BITS(&l2info.cookie)) { 504 case PPP_OSI: 505 ppp_print(p-2,l2info.length+2); 506 break; 507 case (PPP_ADDRESS << 8 | PPP_CONTROL): /* fall through */ 508 default: 509 ppp_print(p,l2info.length); 510 break; 511 } 512 513 return l2info.header_len; 514 } 515 #endif 516 517 518 #ifdef DLT_JUNIPER_MFR 519 u_int 520 juniper_mfr_print(const struct pcap_pkthdr *h, register const u_char *p) 521 { 522 struct juniper_l2info_t l2info; 523 524 l2info.pictype = DLT_JUNIPER_MFR; 525 if(juniper_parse_header(p, h, &l2info) == 0) 526 return l2info.header_len; 527 528 p+=l2info.header_len; 529 530 /* child-link ? */ 531 if (l2info.cookie_len == 0) { 532 mfr_print(p,l2info.length); 533 return l2info.header_len; 534 } 535 536 /* first try the LSQ protos */ 537 if (l2info.cookie_len == AS_PIC_COOKIE_LEN) { 538 switch(l2info.proto) { 539 case JUNIPER_LSQ_L3_PROTO_IPV4: 540 ip_print(gndo, p, l2info.length); 541 return l2info.header_len; 542 #ifdef INET6 543 case JUNIPER_LSQ_L3_PROTO_IPV6: 544 ip6_print(p,l2info.length); 545 return l2info.header_len; 546 #endif 547 case JUNIPER_LSQ_L3_PROTO_MPLS: 548 mpls_print(p,l2info.length); 549 return l2info.header_len; 550 case JUNIPER_LSQ_L3_PROTO_ISO: 551 isoclns_print(p,l2info.length,l2info.caplen); 552 return l2info.header_len; 553 default: 554 break; 555 } 556 return l2info.header_len; 557 } 558 559 /* suppress Bundle-ID if frame was captured on a child-link */ 560 if (eflag && EXTRACT_32BITS(l2info.cookie) != 1) printf("Bundle-ID %u, ",l2info.bundle); 561 switch (l2info.proto) { 562 case (LLCSAP_ISONS<<8 | LLCSAP_ISONS): 563 isoclns_print(p+1, l2info.length-1, l2info.caplen-1); 564 break; 565 case (LLC_UI<<8 | NLPID_Q933): 566 case (LLC_UI<<8 | NLPID_IP): 567 case (LLC_UI<<8 | NLPID_IP6): 568 /* pass IP{4,6} to the OSI layer for proper link-layer printing */ 569 isoclns_print(p-1, l2info.length+1, l2info.caplen+1); 570 break; 571 default: 572 printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length); 573 } 574 575 return l2info.header_len; 576 } 577 #endif 578 579 #ifdef DLT_JUNIPER_MLFR 580 u_int 581 juniper_mlfr_print(const struct pcap_pkthdr *h, register const u_char *p) 582 { 583 struct juniper_l2info_t l2info; 584 585 l2info.pictype = DLT_JUNIPER_MLFR; 586 if(juniper_parse_header(p, h, &l2info) == 0) 587 return l2info.header_len; 588 589 p+=l2info.header_len; 590 591 /* suppress Bundle-ID if frame was captured on a child-link */ 592 if (eflag && EXTRACT_32BITS(l2info.cookie) != 1) printf("Bundle-ID %u, ",l2info.bundle); 593 switch (l2info.proto) { 594 case (LLC_UI): 595 case (LLC_UI<<8): 596 isoclns_print(p, l2info.length, l2info.caplen); 597 break; 598 case (LLC_UI<<8 | NLPID_Q933): 599 case (LLC_UI<<8 | NLPID_IP): 600 case (LLC_UI<<8 | NLPID_IP6): 601 /* pass IP{4,6} to the OSI layer for proper link-layer printing */ 602 isoclns_print(p-1, l2info.length+1, l2info.caplen+1); 603 break; 604 default: 605 printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length); 606 } 607 608 return l2info.header_len; 609 } 610 #endif 611 612 /* 613 * ATM1 PIC cookie format 614 * 615 * +-----+-------------------------+-------------------------------+ 616 * |fmtid| vc index | channel ID | 617 * +-----+-------------------------+-------------------------------+ 618 */ 619 620 #ifdef DLT_JUNIPER_ATM1 621 u_int 622 juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p) 623 { 624 u_int16_t extracted_ethertype; 625 626 struct juniper_l2info_t l2info; 627 628 l2info.pictype = DLT_JUNIPER_ATM1; 629 if(juniper_parse_header(p, h, &l2info) == 0) 630 return l2info.header_len; 631 632 p+=l2info.header_len; 633 634 if (l2info.cookie[0] == 0x80) { /* OAM cell ? */ 635 oam_print(p,l2info.length,ATM_OAM_NOHEC); 636 return l2info.header_len; 637 } 638 639 if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ 640 EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ 641 642 if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL, 643 &extracted_ethertype) != 0) 644 return l2info.header_len; 645 } 646 647 if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ 648 isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1); 649 /* FIXME check if frame was recognized */ 650 return l2info.header_len; 651 } 652 653 if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */ 654 return l2info.header_len; 655 656 return l2info.header_len; 657 } 658 #endif 659 660 /* 661 * ATM2 PIC cookie format 662 * 663 * +-------------------------------+---------+---+-----+-----------+ 664 * | channel ID | reserv |AAL| CCRQ| gap cnt | 665 * +-------------------------------+---------+---+-----+-----------+ 666 */ 667 668 #ifdef DLT_JUNIPER_ATM2 669 u_int 670 juniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p) 671 { 672 u_int16_t extracted_ethertype; 673 674 struct juniper_l2info_t l2info; 675 676 l2info.pictype = DLT_JUNIPER_ATM2; 677 if(juniper_parse_header(p, h, &l2info) == 0) 678 return l2info.header_len; 679 680 p+=l2info.header_len; 681 682 if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */ 683 oam_print(p,l2info.length,ATM_OAM_NOHEC); 684 return l2info.header_len; 685 } 686 687 if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ 688 EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ 689 690 if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL, 691 &extracted_ethertype) != 0) 692 return l2info.header_len; 693 } 694 695 if (l2info.direction != JUNIPER_BPF_PKT_IN && /* ether-over-1483 encaps ? */ 696 (EXTRACT_32BITS(l2info.cookie) & ATM2_GAP_COUNT_MASK)) { 697 ether_print(p, l2info.length, l2info.caplen); 698 return l2info.header_len; 699 } 700 701 if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */ 702 isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1); 703 /* FIXME check if frame was recognized */ 704 return l2info.header_len; 705 } 706 707 if(juniper_ppp_heuristic_guess(p, l2info.length) != 0) /* PPPoA vcmux encaps ? */ 708 return l2info.header_len; 709 710 if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */ 711 return l2info.header_len; 712 713 return l2info.header_len; 714 } 715 #endif 716 717 718 /* try to guess, based on all PPP protos that are supported in 719 * a juniper router if the payload data is encapsulated using PPP */ 720 int 721 juniper_ppp_heuristic_guess(register const u_char *p, u_int length) { 722 723 switch(EXTRACT_16BITS(p)) { 724 case PPP_IP : 725 case PPP_OSI : 726 case PPP_MPLS_UCAST : 727 case PPP_MPLS_MCAST : 728 case PPP_IPCP : 729 case PPP_OSICP : 730 case PPP_MPLSCP : 731 case PPP_LCP : 732 case PPP_PAP : 733 case PPP_CHAP : 734 case PPP_ML : 735 #ifdef INET6 736 case PPP_IPV6 : 737 case PPP_IPV6CP : 738 #endif 739 ppp_print(p, length); 740 break; 741 742 default: 743 return 0; /* did not find a ppp header */ 744 break; 745 } 746 return 1; /* we printed a ppp packet */ 747 } 748 749 int 750 ip_heuristic_guess(register const u_char *p, u_int length) { 751 752 switch(p[0]) { 753 case 0x45: 754 case 0x46: 755 case 0x47: 756 case 0x48: 757 case 0x49: 758 case 0x4a: 759 case 0x4b: 760 case 0x4c: 761 case 0x4d: 762 case 0x4e: 763 case 0x4f: 764 ip_print(gndo, p, length); 765 break; 766 #ifdef INET6 767 case 0x60: 768 case 0x61: 769 case 0x62: 770 case 0x63: 771 case 0x64: 772 case 0x65: 773 case 0x66: 774 case 0x67: 775 case 0x68: 776 case 0x69: 777 case 0x6a: 778 case 0x6b: 779 case 0x6c: 780 case 0x6d: 781 case 0x6e: 782 case 0x6f: 783 ip6_print(p, length); 784 break; 785 #endif 786 default: 787 return 0; /* did not find a ip header */ 788 break; 789 } 790 return 1; /* we printed an v4/v6 packet */ 791 } 792 793 static int 794 juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) { 795 796 struct juniper_cookie_table_t *lp = juniper_cookie_table; 797 u_int idx, offset; 798 #ifdef DLT_JUNIPER_ATM2 799 u_int32_t control_word; 800 #endif 801 802 l2info->header_len = 0; 803 l2info->cookie_len = 0; 804 l2info->proto = 0; 805 806 807 l2info->length = h->len; 808 l2info->caplen = h->caplen; 809 l2info->direction = p[3]&JUNIPER_BPF_PKT_IN; 810 811 TCHECK2(p[0],4); 812 if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */ 813 printf("no magic-number found!"); 814 return 0; 815 } 816 817 if (eflag) /* print direction */ 818 printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction)); 819 820 /* extensions present ? - calculate how much bytes to skip */ 821 if ((p[3] & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) { 822 offset = 6 + EXTRACT_16BITS(p+4); 823 if (eflag>1) 824 printf("ext-len %u, ",EXTRACT_16BITS(p+4)); 825 } else 826 offset = 4; 827 828 if ((p[3] & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) { 829 if (eflag) 830 printf("no-L2-hdr, "); 831 832 /* there is no link-layer present - 833 * perform the v4/v6 heuristics 834 * to figure out what it is 835 */ 836 TCHECK2(p[offset+4],1); 837 if(ip_heuristic_guess(p+offset+4,l2info->length-(offset+4)) == 0) 838 printf("no IP-hdr found!"); 839 840 l2info->header_len=offset+4; 841 return 0; /* stop parsing the output further */ 842 843 } 844 l2info->header_len = offset; 845 p+=l2info->header_len; 846 l2info->length -= l2info->header_len; 847 l2info->caplen -= l2info->header_len; 848 849 /* search through the cookie table and copy values matching for our PIC type */ 850 while (lp->s != NULL) { 851 if (lp->pictype == l2info->pictype) { 852 853 l2info->cookie_len += lp->cookie_len; 854 855 switch (p[0]) { 856 case LS_COOKIE_ID: 857 l2info->cookie_type = LS_COOKIE_ID; 858 l2info->cookie_len += 2; 859 break; 860 case AS_COOKIE_ID: 861 l2info->cookie_type = AS_COOKIE_ID; 862 l2info->cookie_len = 8; 863 break; 864 865 default: 866 l2info->bundle = l2info->cookie[0]; 867 break; 868 } 869 870 871 #ifdef DLT_JUNIPER_MFR 872 /* MFR child links don't carry cookies */ 873 if (l2info->pictype == DLT_JUNIPER_MFR && 874 (p[0] & MFR_BE_MASK) == MFR_BE_MASK) { 875 l2info->cookie_len = 0; 876 } 877 #endif 878 879 l2info->header_len += l2info->cookie_len; 880 l2info->length -= l2info->cookie_len; 881 l2info->caplen -= l2info->cookie_len; 882 883 if (eflag) 884 printf("%s-PIC, cookie-len %u", 885 lp->s, 886 l2info->cookie_len); 887 888 if (l2info->cookie_len > 0) { 889 TCHECK2(p[0],l2info->cookie_len); 890 if (eflag) 891 printf(", cookie 0x"); 892 for (idx = 0; idx < l2info->cookie_len; idx++) { 893 l2info->cookie[idx] = p[idx]; /* copy cookie data */ 894 if (eflag) printf("%02x",p[idx]); 895 } 896 } 897 898 if (eflag) printf(": "); /* print demarc b/w L2/L3*/ 899 900 901 l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); 902 break; 903 } 904 ++lp; 905 } 906 p+=l2info->cookie_len; 907 908 /* DLT_ specific parsing */ 909 switch(l2info->pictype) { 910 #ifdef DLT_JUNIPER_MLPPP 911 case DLT_JUNIPER_MLPPP: 912 switch (l2info->cookie_type) { 913 case LS_COOKIE_ID: 914 l2info->bundle = l2info->cookie[1]; 915 break; 916 case AS_COOKIE_ID: 917 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; 918 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; 919 break; 920 default: 921 l2info->bundle = l2info->cookie[0]; 922 break; 923 } 924 break; 925 #endif 926 #ifdef DLT_JUNIPER_MLFR 927 case DLT_JUNIPER_MLFR: 928 switch (l2info->cookie_type) { 929 case LS_COOKIE_ID: 930 l2info->bundle = l2info->cookie[1]; 931 l2info->proto = EXTRACT_16BITS(p); 932 l2info->header_len += 2; 933 l2info->length -= 2; 934 l2info->caplen -= 2; 935 break; 936 case AS_COOKIE_ID: 937 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; 938 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; 939 break; 940 default: 941 l2info->bundle = l2info->cookie[0]; 942 l2info->header_len += 2; 943 l2info->length -= 2; 944 l2info->caplen -= 2; 945 break; 946 } 947 break; 948 #endif 949 #ifdef DLT_JUNIPER_MFR 950 case DLT_JUNIPER_MFR: 951 switch (l2info->cookie_type) { 952 case LS_COOKIE_ID: 953 l2info->bundle = l2info->cookie[1]; 954 l2info->proto = EXTRACT_16BITS(p); 955 l2info->header_len += 2; 956 l2info->length -= 2; 957 l2info->caplen -= 2; 958 break; 959 case AS_COOKIE_ID: 960 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; 961 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; 962 break; 963 default: 964 l2info->bundle = l2info->cookie[0]; 965 break; 966 } 967 break; 968 #endif 969 #ifdef DLT_JUNIPER_ATM2 970 case DLT_JUNIPER_ATM2: 971 TCHECK2(p[0],4); 972 /* ATM cell relay control word present ? */ 973 if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) { 974 control_word = EXTRACT_32BITS(p); 975 /* some control word heuristics */ 976 switch(control_word) { 977 case 0: /* zero control word */ 978 case 0x08000000: /* < JUNOS 7.4 control-word */ 979 case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/ 980 l2info->header_len += 4; 981 break; 982 default: 983 break; 984 } 985 986 if (eflag) 987 printf("control-word 0x%08x ", control_word); 988 } 989 break; 990 #endif 991 #ifdef DLT_JUNIPER_ATM1 992 case DLT_JUNIPER_ATM1: 993 break; 994 #endif 995 #ifdef DLT_JUNIPER_PPP 996 case DLT_JUNIPER_PPP: 997 break; 998 #endif 999 #ifdef DLT_JUNIPER_CHDLC 1000 case DLT_JUNIPER_CHDLC: 1001 break; 1002 #endif 1003 #ifdef DLT_JUNIPER_ETHER 1004 case DLT_JUNIPER_ETHER: 1005 break; 1006 #endif 1007 #ifdef DLT_JUNIPER_FRELAY 1008 case DLT_JUNIPER_FRELAY: 1009 break; 1010 #endif 1011 1012 default: 1013 printf("Unknown Juniper DLT_ type %u: ", l2info->pictype); 1014 break; 1015 } 1016 1017 if (eflag > 1) 1018 printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto); 1019 1020 return 1; /* everything went ok so far. continue parsing */ 1021 trunc: 1022 printf("[|juniper_hdr], length %u",h->len); 1023 return 0; 1024 } 1025 1026 1027 /* 1028 * Local Variables: 1029 * c-style: whitesmith 1030 * c-basic-offset: 4 1031 * End: 1032 */ 1033