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 17 static const char rcsid[] _U_ = 18 "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.8.2.19 2005/08/23 10:29:42 hannes 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 u_int32_t control_word; 674 675 struct juniper_l2info_t l2info; 676 677 l2info.pictype = DLT_JUNIPER_ATM2; 678 if(juniper_parse_header(p, h, &l2info) == 0) 679 return l2info.header_len; 680 681 p+=l2info.header_len; 682 683 if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */ 684 control_word = EXTRACT_32BITS(p); 685 if(control_word == 0 || control_word == 0x08000000) { 686 l2info.header_len += 4; 687 l2info.length -= 4; 688 p += 4; 689 } 690 oam_print(p,l2info.length,ATM_OAM_NOHEC); 691 return l2info.header_len; 692 } 693 694 if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */ 695 EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */ 696 697 if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL, 698 &extracted_ethertype) != 0) 699 return l2info.header_len; 700 } 701 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; 706 } 707 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; 712 } 713 714 if(juniper_ppp_heuristic_guess(p, l2info.length) != 0) /* PPPoA vcmux encaps ? */ 715 return l2info.header_len; 716 717 if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */ 718 return l2info.header_len; 719 720 return l2info.header_len; 721 } 722 #endif 723 724 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 */ 727 int 728 juniper_ppp_heuristic_guess(register const u_char *p, u_int length) { 729 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; 748 749 default: 750 return 0; /* did not find a ppp header */ 751 break; 752 } 753 return 1; /* we printed a ppp packet */ 754 } 755 756 int 757 ip_heuristic_guess(register const u_char *p, u_int length) { 758 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; 796 } 797 return 1; /* we printed an v4/v6 packet */ 798 } 799 800 static int 801 juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) { 802 803 struct juniper_cookie_table_t *lp = juniper_cookie_table; 804 u_int idx, offset; 805 806 l2info->header_len = 0; 807 l2info->cookie_len = 0; 808 l2info->proto = 0; 809 810 811 l2info->length = h->len; 812 l2info->caplen = h->caplen; 813 l2info->direction = p[3]&JUNIPER_BPF_PKT_IN; 814 815 TCHECK2(p[0],4); 816 if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */ 817 printf("no magic-number found!"); 818 return 0; 819 } 820 821 if (eflag) /* print direction */ 822 printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction)); 823 824 /* extensions present ? - calculate how much bytes to skip */ 825 if ((p[3] & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) { 826 offset = 6 + EXTRACT_16BITS(p+4); 827 if (eflag>1) 828 printf("ext-len %u, ",EXTRACT_16BITS(p+4)); 829 } else 830 offset = 4; 831 832 if ((p[3] & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) { 833 if (eflag) 834 printf("no-L2-hdr, "); 835 836 /* there is no link-layer present - 837 * perform the v4/v6 heuristics 838 * to figure out what it is 839 */ 840 TCHECK2(p[offset+4],1); 841 if(ip_heuristic_guess(p+offset+4,l2info->length-(offset+4)) == 0) 842 printf("no IP-hdr found!"); 843 844 l2info->header_len=offset+4; 845 return 0; /* stop parsing the output further */ 846 847 } 848 l2info->header_len = offset; 849 p+=l2info->header_len; 850 l2info->length -= l2info->header_len; 851 l2info->caplen -= l2info->header_len; 852 853 /* search through the cookie table and copy values matching for our PIC type */ 854 while (lp->s != NULL) { 855 if (lp->pictype == l2info->pictype) { 856 857 l2info->cookie_len += lp->cookie_len; 858 859 switch (p[0]) { 860 case LS_COOKIE_ID: 861 l2info->cookie_type = LS_COOKIE_ID; 862 l2info->cookie_len += 2; 863 break; 864 case AS_COOKIE_ID: 865 l2info->cookie_type = AS_COOKIE_ID; 866 l2info->cookie_len = 8; 867 break; 868 869 default: 870 l2info->bundle = l2info->cookie[0]; 871 break; 872 } 873 874 875 #ifdef DLT_JUNIPER_MFR 876 /* MFR child links don't carry cookies */ 877 if (l2info->pictype == DLT_JUNIPER_MFR && 878 (p[0] & MFR_BE_MASK) == MFR_BE_MASK) { 879 l2info->cookie_len = 0; 880 } 881 #endif 882 883 l2info->header_len += l2info->cookie_len; 884 l2info->length -= l2info->cookie_len; 885 l2info->caplen -= l2info->cookie_len; 886 887 if (eflag) 888 printf("%s-PIC, cookie-len %u", 889 lp->s, 890 l2info->cookie_len); 891 892 if (l2info->cookie_len > 0) { 893 TCHECK2(p[0],l2info->cookie_len); 894 if (eflag) 895 printf(", cookie 0x"); 896 for (idx = 0; idx < l2info->cookie_len; idx++) { 897 l2info->cookie[idx] = p[idx]; /* copy cookie data */ 898 if (eflag) printf("%02x",p[idx]); 899 } 900 } 901 902 if (eflag) printf(": "); /* print demarc b/w L2/L3*/ 903 904 905 l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len); 906 break; 907 } 908 ++lp; 909 } 910 p+=l2info->cookie_len; 911 912 /* DLT_ specific parsing */ 913 switch(l2info->pictype) { 914 #ifdef DLT_JUNIPER_MLPPP 915 case DLT_JUNIPER_MLPPP: 916 switch (l2info->cookie_type) { 917 case LS_COOKIE_ID: 918 l2info->bundle = l2info->cookie[1]; 919 break; 920 case AS_COOKIE_ID: 921 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; 922 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; 923 break; 924 default: 925 l2info->bundle = l2info->cookie[0]; 926 break; 927 } 928 break; 929 #endif 930 #ifdef DLT_JUNIPER_MLFR 931 case DLT_JUNIPER_MLFR: 932 switch (l2info->cookie_type) { 933 case LS_COOKIE_ID: 934 l2info->bundle = l2info->cookie[1]; 935 l2info->proto = EXTRACT_16BITS(p); 936 l2info->header_len += 2; 937 l2info->length -= 2; 938 l2info->caplen -= 2; 939 break; 940 case AS_COOKIE_ID: 941 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; 942 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; 943 break; 944 default: 945 l2info->bundle = l2info->cookie[0]; 946 l2info->header_len += 2; 947 l2info->length -= 2; 948 l2info->caplen -= 2; 949 break; 950 } 951 break; 952 #endif 953 #ifdef DLT_JUNIPER_MFR 954 case DLT_JUNIPER_MFR: 955 switch (l2info->cookie_type) { 956 case LS_COOKIE_ID: 957 l2info->bundle = l2info->cookie[1]; 958 l2info->proto = EXTRACT_16BITS(p); 959 l2info->header_len += 2; 960 l2info->length -= 2; 961 l2info->caplen -= 2; 962 break; 963 case AS_COOKIE_ID: 964 l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff; 965 l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK; 966 break; 967 default: 968 l2info->bundle = l2info->cookie[0]; 969 break; 970 } 971 break; 972 #endif 973 #ifdef DLT_JUNIPER_ATM2 974 case DLT_JUNIPER_ATM2: 975 TCHECK2(p[0],4); 976 /* ATM cell relay control word present ? */ 977 if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK && *p & 0x08) { 978 l2info->header_len += 4; 979 if (eflag) 980 printf("control-word 0x%08x ",EXTRACT_32BITS(p)); 981 } 982 break; 983 #endif 984 #ifdef DLT_JUNIPER_ATM1 985 case DLT_JUNIPER_ATM1: 986 break; 987 #endif 988 default: 989 printf("Unknown Juniper DLT_ type %u: ", l2info->pictype); 990 break; 991 } 992 993 if (eflag > 1) 994 printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto); 995 996 return 1; /* everything went ok so far. continue parsing */ 997 trunc: 998 printf("[|juniper_hdr], length %u",h->len); 999 return 0; 1000 } 1001 1002 1003 /* 1004 * Local Variables: 1005 * c-style: whitesmith 1006 * c-basic-offset: 4 1007 * End: 1008 */ 1009