1 /* $NetBSD: pcap-dag.c,v 1.7 2023/08/17 15:18:12 christos Exp $ */ 2 3 /* 4 * pcap-dag.c: Packet capture interface for Endace DAG cards. 5 * 6 * Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com) 7 * Modifications: Jesper Peterson 8 * Koryn Grant 9 * Stephen Donnelly <stephen.donnelly@endace.com> 10 */ 11 12 #include <sys/cdefs.h> 13 __RCSID("$NetBSD: pcap-dag.c,v 1.7 2023/08/17 15:18:12 christos Exp $"); 14 15 #ifdef HAVE_CONFIG_H 16 #include <config.h> 17 #endif 18 19 #include <sys/param.h> /* optionally get BSD define */ 20 21 #include <stdlib.h> 22 #include <string.h> 23 #include <errno.h> 24 25 #include "pcap-int.h" 26 27 #include <netinet/in.h> 28 #include <sys/mman.h> 29 #include <sys/socket.h> 30 #include <sys/types.h> 31 #include <unistd.h> 32 33 struct mbuf; /* Squelch compiler warnings on some platforms for */ 34 struct rtentry; /* declarations in <net/if.h> */ 35 #include <net/if.h> 36 37 #include "dagnew.h" 38 #include "dagapi.h" 39 #include "dagpci.h" 40 #include "dag_config_api.h" 41 42 #include "pcap-dag.h" 43 44 /* 45 * DAG devices have names beginning with "dag", followed by a number 46 * from 0 to DAG_MAX_BOARDS, then optionally a colon and a stream number 47 * from 0 to DAG_STREAM_MAX. 48 */ 49 #ifndef DAG_MAX_BOARDS 50 #define DAG_MAX_BOARDS 32 51 #endif 52 53 54 #ifndef ERF_TYPE_AAL5 55 #define ERF_TYPE_AAL5 4 56 #endif 57 58 #ifndef ERF_TYPE_MC_HDLC 59 #define ERF_TYPE_MC_HDLC 5 60 #endif 61 62 #ifndef ERF_TYPE_MC_RAW 63 #define ERF_TYPE_MC_RAW 6 64 #endif 65 66 #ifndef ERF_TYPE_MC_ATM 67 #define ERF_TYPE_MC_ATM 7 68 #endif 69 70 #ifndef ERF_TYPE_MC_RAW_CHANNEL 71 #define ERF_TYPE_MC_RAW_CHANNEL 8 72 #endif 73 74 #ifndef ERF_TYPE_MC_AAL5 75 #define ERF_TYPE_MC_AAL5 9 76 #endif 77 78 #ifndef ERF_TYPE_COLOR_HDLC_POS 79 #define ERF_TYPE_COLOR_HDLC_POS 10 80 #endif 81 82 #ifndef ERF_TYPE_COLOR_ETH 83 #define ERF_TYPE_COLOR_ETH 11 84 #endif 85 86 #ifndef ERF_TYPE_MC_AAL2 87 #define ERF_TYPE_MC_AAL2 12 88 #endif 89 90 #ifndef ERF_TYPE_IP_COUNTER 91 #define ERF_TYPE_IP_COUNTER 13 92 #endif 93 94 #ifndef ERF_TYPE_TCP_FLOW_COUNTER 95 #define ERF_TYPE_TCP_FLOW_COUNTER 14 96 #endif 97 98 #ifndef ERF_TYPE_DSM_COLOR_HDLC_POS 99 #define ERF_TYPE_DSM_COLOR_HDLC_POS 15 100 #endif 101 102 #ifndef ERF_TYPE_DSM_COLOR_ETH 103 #define ERF_TYPE_DSM_COLOR_ETH 16 104 #endif 105 106 #ifndef ERF_TYPE_COLOR_MC_HDLC_POS 107 #define ERF_TYPE_COLOR_MC_HDLC_POS 17 108 #endif 109 110 #ifndef ERF_TYPE_AAL2 111 #define ERF_TYPE_AAL2 18 112 #endif 113 114 #ifndef ERF_TYPE_COLOR_HASH_POS 115 #define ERF_TYPE_COLOR_HASH_POS 19 116 #endif 117 118 #ifndef ERF_TYPE_COLOR_HASH_ETH 119 #define ERF_TYPE_COLOR_HASH_ETH 20 120 #endif 121 122 #ifndef ERF_TYPE_INFINIBAND 123 #define ERF_TYPE_INFINIBAND 21 124 #endif 125 126 #ifndef ERF_TYPE_IPV4 127 #define ERF_TYPE_IPV4 22 128 #endif 129 130 #ifndef ERF_TYPE_IPV6 131 #define ERF_TYPE_IPV6 23 132 #endif 133 134 #ifndef ERF_TYPE_RAW_LINK 135 #define ERF_TYPE_RAW_LINK 24 136 #endif 137 138 #ifndef ERF_TYPE_INFINIBAND_LINK 139 #define ERF_TYPE_INFINIBAND_LINK 25 140 #endif 141 142 #ifndef ERF_TYPE_META 143 #define ERF_TYPE_META 27 144 #endif 145 146 #ifndef ERF_TYPE_PAD 147 #define ERF_TYPE_PAD 48 148 #endif 149 150 #define ATM_CELL_SIZE 52 151 #define ATM_HDR_SIZE 4 152 153 /* 154 * A header containing additional MTP information. 155 */ 156 #define MTP2_SENT_OFFSET 0 /* 1 byte */ 157 #define MTP2_ANNEX_A_USED_OFFSET 1 /* 1 byte */ 158 #define MTP2_LINK_NUMBER_OFFSET 2 /* 2 bytes */ 159 #define MTP2_HDR_LEN 4 /* length of the header */ 160 161 #define MTP2_ANNEX_A_NOT_USED 0 162 #define MTP2_ANNEX_A_USED 1 163 #define MTP2_ANNEX_A_USED_UNKNOWN 2 164 165 /* SunATM pseudo header */ 166 struct sunatm_hdr { 167 unsigned char flags; /* destination and traffic type */ 168 unsigned char vpi; /* VPI */ 169 unsigned short vci; /* VCI */ 170 }; 171 172 /* 173 * Private data for capturing on DAG devices. 174 */ 175 struct pcap_dag { 176 struct pcap_stat stat; 177 u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */ 178 u_char *dag_mem_top; /* DAG card current memory top pointer */ 179 int dag_fcs_bits; /* Number of checksum bits from link layer */ 180 int dag_flags; /* Flags */ 181 int dag_stream; /* DAG stream number */ 182 int dag_timeout; /* timeout specified to pcap_open_live. 183 * Same as in linux above, introduce 184 * generally? */ 185 dag_card_ref_t dag_ref; /* DAG Configuration/Status API card reference */ 186 dag_component_t dag_root; /* DAG CSAPI Root component */ 187 attr_uuid_t drop_attr; /* DAG Stream Drop Attribute handle, if available */ 188 struct timeval required_select_timeout; 189 /* Timeout caller must use in event loops */ 190 }; 191 192 typedef struct pcap_dag_node { 193 struct pcap_dag_node *next; 194 pcap_t *p; 195 pid_t pid; 196 } pcap_dag_node_t; 197 198 static pcap_dag_node_t *pcap_dags = NULL; 199 static int atexit_handler_installed = 0; 200 static const unsigned short endian_test_word = 0x0100; 201 202 #define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word)) 203 204 #define MAX_DAG_PACKET 65536 205 206 static unsigned char TempPkt[MAX_DAG_PACKET]; 207 208 #ifndef HAVE_DAG_LARGE_STREAMS_API 209 #define dag_attach_stream64(a, b, c, d) dag_attach_stream(a, b, c, d) 210 #define dag_get_stream_poll64(a, b, c, d, e) dag_get_stream_poll(a, b, c, d, e) 211 #define dag_set_stream_poll64(a, b, c, d, e) dag_set_stream_poll(a, b, c, d, e) 212 #define dag_size_t uint32_t 213 #endif 214 215 static int dag_stats(pcap_t *p, struct pcap_stat *ps); 216 static int dag_set_datalink(pcap_t *p, int dlt); 217 static int dag_get_datalink(pcap_t *p); 218 static int dag_setnonblock(pcap_t *p, int nonblock); 219 220 static void 221 delete_pcap_dag(const pcap_t *p) 222 { 223 pcap_dag_node_t *curr = NULL, *prev = NULL; 224 225 for (prev = NULL, curr = pcap_dags; curr != NULL && curr->p != p; prev = curr, curr = curr->next) { 226 /* empty */ 227 } 228 229 if (curr != NULL && curr->p == p) { 230 if (prev != NULL) { 231 prev->next = curr->next; 232 } else { 233 pcap_dags = curr->next; 234 } 235 } 236 } 237 238 /* 239 * Performs a graceful shutdown of the DAG card, frees dynamic memory held 240 * in the pcap_t structure, and closes the file descriptor for the DAG card. 241 */ 242 243 static void 244 dag_platform_cleanup(pcap_t *p) 245 { 246 struct pcap_dag *pd = p->priv; 247 248 if(dag_stop_stream(p->fd, pd->dag_stream) < 0) 249 fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno)); 250 251 if(dag_detach_stream(p->fd, pd->dag_stream) < 0) 252 fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno)); 253 254 if(pd->dag_ref != NULL) { 255 dag_config_dispose(pd->dag_ref); 256 /* 257 * Note: we don't need to call close(p->fd) or 258 * dag_close(p->fd), as dag_config_dispose(pd->dag_ref) 259 * does this. 260 * 261 * Set p->fd to -1 to make sure that's not done. 262 */ 263 p->fd = -1; 264 pd->dag_ref = NULL; 265 } 266 delete_pcap_dag(p); 267 pcap_cleanup_live_common(p); 268 } 269 270 static void 271 atexit_handler(void) 272 { 273 while (pcap_dags != NULL) { 274 if (pcap_dags->pid == getpid()) { 275 if (pcap_dags->p != NULL) 276 dag_platform_cleanup(pcap_dags->p); 277 } else { 278 delete_pcap_dag(pcap_dags->p); 279 } 280 } 281 } 282 283 static int 284 new_pcap_dag(pcap_t *p) 285 { 286 pcap_dag_node_t *node = NULL; 287 288 if ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) { 289 return -1; 290 } 291 292 if (!atexit_handler_installed) { 293 atexit(atexit_handler); 294 atexit_handler_installed = 1; 295 } 296 297 node->next = pcap_dags; 298 node->p = p; 299 node->pid = getpid(); 300 301 pcap_dags = node; 302 303 return 0; 304 } 305 306 static unsigned int 307 dag_erf_ext_header_count(const uint8_t *erf, size_t len) 308 { 309 uint32_t hdr_num = 0; 310 uint8_t hdr_type; 311 312 /* basic sanity checks */ 313 if ( erf == NULL ) 314 return 0; 315 if ( len < 16 ) 316 return 0; 317 318 /* check if we have any extension headers */ 319 if ( (erf[8] & 0x80) == 0x00 ) 320 return 0; 321 322 /* loop over the extension headers */ 323 do { 324 325 /* sanity check we have enough bytes */ 326 if ( len < (24 + (hdr_num * 8)) ) 327 return hdr_num; 328 329 /* get the header type */ 330 hdr_type = erf[(16 + (hdr_num * 8))]; 331 hdr_num++; 332 333 } while ( hdr_type & 0x80 ); 334 335 return hdr_num; 336 } 337 338 /* 339 * Read at most max_packets from the capture stream and call the callback 340 * for each of them. Returns the number of packets handled, -1 if an 341 * error occurred, or -2 if we were told to break out of the loop. 342 */ 343 static int 344 dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 345 { 346 struct pcap_dag *pd = p->priv; 347 unsigned int processed = 0; 348 unsigned int nonblocking = pd->dag_flags & DAGF_NONBLOCK; 349 unsigned int num_ext_hdr = 0; 350 unsigned int ticks_per_second; 351 352 /* Get the next bufferful of packets (if necessary). */ 353 while (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size) { 354 355 /* 356 * Has "pcap_breakloop()" been called? 357 */ 358 if (p->break_loop) { 359 /* 360 * Yes - clear the flag that indicates that 361 * it has, and return -2 to indicate that 362 * we were told to break out of the loop. 363 */ 364 p->break_loop = 0; 365 return -2; 366 } 367 368 /* dag_advance_stream() will block (unless nonblock is called) 369 * until 64kB of data has accumulated. 370 * If to_ms is set, it will timeout before 64kB has accumulated. 371 * We wait for 64kB because processing a few packets at a time 372 * can cause problems at high packet rates (>200kpps) due 373 * to inefficiencies. 374 * This does mean if to_ms is not specified the capture may 'hang' 375 * for long periods if the data rate is extremely slow (<64kB/sec) 376 * If non-block is specified it will return immediately. The user 377 * is then responsible for efficiency. 378 */ 379 if ( NULL == (pd->dag_mem_top = dag_advance_stream(p->fd, pd->dag_stream, &(pd->dag_mem_bottom))) ) { 380 return -1; 381 } 382 383 if (nonblocking && (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size)) 384 { 385 /* Pcap is configured to process only available packets, and there aren't any, return immediately. */ 386 return 0; 387 } 388 389 if(!nonblocking && 390 pd->dag_timeout && 391 (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size)) 392 { 393 /* Blocking mode, but timeout set and no data has arrived, return anyway.*/ 394 return 0; 395 } 396 397 } 398 399 /* 400 * Process the packets. 401 * 402 * This assumes that a single buffer of packets will have 403 * <= INT_MAX packets, so the packet count doesn't overflow. 404 */ 405 while (pd->dag_mem_top - pd->dag_mem_bottom >= dag_record_size) { 406 407 unsigned short packet_len = 0; 408 int caplen = 0; 409 struct pcap_pkthdr pcap_header; 410 411 dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom); 412 413 u_char *dp = ((u_char *)header); /* + dag_record_size; */ 414 unsigned short rlen; 415 416 /* 417 * Has "pcap_breakloop()" been called? 418 */ 419 if (p->break_loop) { 420 /* 421 * Yes - clear the flag that indicates that 422 * it has, and return -2 to indicate that 423 * we were told to break out of the loop. 424 */ 425 p->break_loop = 0; 426 return -2; 427 } 428 429 rlen = ntohs(header->rlen); 430 if (rlen < dag_record_size) 431 { 432 pcap_strlcpy(p->errbuf, "dag_read: record too small", 433 PCAP_ERRBUF_SIZE); 434 return -1; 435 } 436 pd->dag_mem_bottom += rlen; 437 438 /* Count lost packets. */ 439 switch((header->type & 0x7f)) { 440 /* in these types the color value overwrites the lctr */ 441 case ERF_TYPE_COLOR_HDLC_POS: 442 case ERF_TYPE_COLOR_ETH: 443 case ERF_TYPE_DSM_COLOR_HDLC_POS: 444 case ERF_TYPE_DSM_COLOR_ETH: 445 case ERF_TYPE_COLOR_MC_HDLC_POS: 446 case ERF_TYPE_COLOR_HASH_ETH: 447 case ERF_TYPE_COLOR_HASH_POS: 448 break; 449 450 default: 451 if ( (pd->drop_attr == kNullAttributeUuid) && (header->lctr) ) { 452 pd->stat.ps_drop += ntohs(header->lctr); 453 } 454 } 455 456 if ((header->type & 0x7f) == ERF_TYPE_PAD) { 457 continue; 458 } 459 460 num_ext_hdr = dag_erf_ext_header_count(dp, rlen); 461 462 /* ERF encapsulation */ 463 /* The Extensible Record Format is not dropped for this kind of encapsulation, 464 * and will be handled as a pseudo header by the decoding application. 465 * The information carried in the ERF header and in the optional subheader (if present) 466 * could be merged with the libpcap information, to offer a better decoding. 467 * The packet length is 468 * o the length of the packet on the link (header->wlen), 469 * o plus the length of the ERF header (dag_record_size), as the length of the 470 * pseudo header will be adjusted during the decoding, 471 * o plus the length of the optional subheader (if present). 472 * 473 * The capture length is header.rlen and the byte stuffing for alignment will be dropped 474 * if the capture length is greater than the packet length. 475 */ 476 if (p->linktype == DLT_ERF) { 477 packet_len = ntohs(header->wlen) + dag_record_size; 478 caplen = rlen; 479 switch ((header->type & 0x7f)) { 480 case ERF_TYPE_MC_AAL5: 481 case ERF_TYPE_MC_ATM: 482 case ERF_TYPE_MC_HDLC: 483 case ERF_TYPE_MC_RAW_CHANNEL: 484 case ERF_TYPE_MC_RAW: 485 case ERF_TYPE_MC_AAL2: 486 case ERF_TYPE_COLOR_MC_HDLC_POS: 487 packet_len += 4; /* MC header */ 488 break; 489 490 case ERF_TYPE_COLOR_HASH_ETH: 491 case ERF_TYPE_DSM_COLOR_ETH: 492 case ERF_TYPE_COLOR_ETH: 493 case ERF_TYPE_ETH: 494 packet_len += 2; /* ETH header */ 495 break; 496 } /* switch type */ 497 498 /* Include ERF extension headers */ 499 packet_len += (8 * num_ext_hdr); 500 501 if (caplen > packet_len) { 502 caplen = packet_len; 503 } 504 } else { 505 /* Other kind of encapsulation according to the header Type */ 506 507 /* Skip over generic ERF header */ 508 dp += dag_record_size; 509 /* Skip over extension headers */ 510 dp += 8 * num_ext_hdr; 511 512 switch((header->type & 0x7f)) { 513 case ERF_TYPE_ATM: 514 case ERF_TYPE_AAL5: 515 if ((header->type & 0x7f) == ERF_TYPE_AAL5) { 516 packet_len = ntohs(header->wlen); 517 caplen = rlen - dag_record_size; 518 } 519 case ERF_TYPE_MC_ATM: 520 if ((header->type & 0x7f) == ERF_TYPE_MC_ATM) { 521 caplen = packet_len = ATM_CELL_SIZE; 522 dp+=4; 523 } 524 case ERF_TYPE_MC_AAL5: 525 if ((header->type & 0x7f) == ERF_TYPE_MC_AAL5) { 526 packet_len = ntohs(header->wlen); 527 caplen = rlen - dag_record_size - 4; 528 dp+=4; 529 } 530 /* Skip over extension headers */ 531 caplen -= (8 * num_ext_hdr); 532 533 if ((header->type & 0x7f) == ERF_TYPE_ATM) { 534 caplen = packet_len = ATM_CELL_SIZE; 535 } 536 if (p->linktype == DLT_SUNATM) { 537 struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp; 538 unsigned long rawatm; 539 540 rawatm = ntohl(*((unsigned long *)dp)); 541 sunatm->vci = htons((rawatm >> 4) & 0xffff); 542 sunatm->vpi = (rawatm >> 20) & 0x00ff; 543 sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) | 544 ((sunatm->vpi == 0 && sunatm->vci == htons(5)) ? 6 : 545 ((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 : 546 ((dp[ATM_HDR_SIZE] == 0xaa && 547 dp[ATM_HDR_SIZE+1] == 0xaa && 548 dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1))); 549 550 } else if (p->linktype == DLT_ATM_RFC1483) { 551 packet_len -= ATM_HDR_SIZE; 552 caplen -= ATM_HDR_SIZE; 553 dp += ATM_HDR_SIZE; 554 } else 555 continue; 556 break; 557 558 case ERF_TYPE_COLOR_HASH_ETH: 559 case ERF_TYPE_DSM_COLOR_ETH: 560 case ERF_TYPE_COLOR_ETH: 561 case ERF_TYPE_ETH: 562 if ((p->linktype != DLT_EN10MB) && 563 (p->linktype != DLT_DOCSIS)) 564 continue; 565 packet_len = ntohs(header->wlen); 566 packet_len -= (pd->dag_fcs_bits >> 3); 567 caplen = rlen - dag_record_size - 2; 568 /* Skip over extension headers */ 569 caplen -= (8 * num_ext_hdr); 570 if (caplen > packet_len) { 571 caplen = packet_len; 572 } 573 dp += 2; 574 break; 575 576 case ERF_TYPE_COLOR_HASH_POS: 577 case ERF_TYPE_DSM_COLOR_HDLC_POS: 578 case ERF_TYPE_COLOR_HDLC_POS: 579 case ERF_TYPE_HDLC_POS: 580 if ((p->linktype != DLT_CHDLC) && 581 (p->linktype != DLT_PPP_SERIAL) && 582 (p->linktype != DLT_FRELAY)) 583 continue; 584 packet_len = ntohs(header->wlen); 585 packet_len -= (pd->dag_fcs_bits >> 3); 586 caplen = rlen - dag_record_size; 587 /* Skip over extension headers */ 588 caplen -= (8 * num_ext_hdr); 589 if (caplen > packet_len) { 590 caplen = packet_len; 591 } 592 break; 593 594 case ERF_TYPE_COLOR_MC_HDLC_POS: 595 case ERF_TYPE_MC_HDLC: 596 if ((p->linktype != DLT_CHDLC) && 597 (p->linktype != DLT_PPP_SERIAL) && 598 (p->linktype != DLT_FRELAY) && 599 (p->linktype != DLT_MTP2) && 600 (p->linktype != DLT_MTP2_WITH_PHDR) && 601 (p->linktype != DLT_LAPD)) 602 continue; 603 packet_len = ntohs(header->wlen); 604 packet_len -= (pd->dag_fcs_bits >> 3); 605 caplen = rlen - dag_record_size - 4; 606 /* Skip over extension headers */ 607 caplen -= (8 * num_ext_hdr); 608 if (caplen > packet_len) { 609 caplen = packet_len; 610 } 611 /* jump the MC_HDLC_HEADER */ 612 dp += 4; 613 #ifdef DLT_MTP2_WITH_PHDR 614 if (p->linktype == DLT_MTP2_WITH_PHDR) { 615 /* Add the MTP2 Pseudo Header */ 616 caplen += MTP2_HDR_LEN; 617 packet_len += MTP2_HDR_LEN; 618 619 TempPkt[MTP2_SENT_OFFSET] = 0; 620 TempPkt[MTP2_ANNEX_A_USED_OFFSET] = MTP2_ANNEX_A_USED_UNKNOWN; 621 *(TempPkt+MTP2_LINK_NUMBER_OFFSET) = ((header->rec.mc_hdlc.mc_header>>16)&0x01); 622 *(TempPkt+MTP2_LINK_NUMBER_OFFSET+1) = ((header->rec.mc_hdlc.mc_header>>24)&0xff); 623 memcpy(TempPkt+MTP2_HDR_LEN, dp, caplen); 624 dp = TempPkt; 625 } 626 #endif 627 break; 628 629 case ERF_TYPE_IPV4: 630 if ((p->linktype != DLT_RAW) && 631 (p->linktype != DLT_IPV4)) 632 continue; 633 packet_len = ntohs(header->wlen); 634 caplen = rlen - dag_record_size; 635 /* Skip over extension headers */ 636 caplen -= (8 * num_ext_hdr); 637 if (caplen > packet_len) { 638 caplen = packet_len; 639 } 640 break; 641 642 case ERF_TYPE_IPV6: 643 if ((p->linktype != DLT_RAW) && 644 (p->linktype != DLT_IPV6)) 645 continue; 646 packet_len = ntohs(header->wlen); 647 caplen = rlen - dag_record_size; 648 /* Skip over extension headers */ 649 caplen -= (8 * num_ext_hdr); 650 if (caplen > packet_len) { 651 caplen = packet_len; 652 } 653 break; 654 655 /* These types have no matching 'native' DLT, but can be used with DLT_ERF above */ 656 case ERF_TYPE_MC_RAW: 657 case ERF_TYPE_MC_RAW_CHANNEL: 658 case ERF_TYPE_IP_COUNTER: 659 case ERF_TYPE_TCP_FLOW_COUNTER: 660 case ERF_TYPE_INFINIBAND: 661 case ERF_TYPE_RAW_LINK: 662 case ERF_TYPE_INFINIBAND_LINK: 663 default: 664 /* Unhandled ERF type. 665 * Ignore rather than generating error 666 */ 667 continue; 668 } /* switch type */ 669 670 } /* ERF encapsulation */ 671 672 if (caplen > p->snapshot) 673 caplen = p->snapshot; 674 675 /* Run the packet filter if there is one. */ 676 if ((p->fcode.bf_insns == NULL) || pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen)) { 677 678 /* convert between timestamp formats */ 679 register unsigned long long ts; 680 681 if (IS_BIGENDIAN()) { 682 ts = SWAPLL(header->ts); 683 } else { 684 ts = header->ts; 685 } 686 687 switch (p->opt.tstamp_precision) { 688 case PCAP_TSTAMP_PRECISION_NANO: 689 ticks_per_second = 1000000000; 690 break; 691 case PCAP_TSTAMP_PRECISION_MICRO: 692 default: 693 ticks_per_second = 1000000; 694 break; 695 696 } 697 pcap_header.ts.tv_sec = ts >> 32; 698 ts = (ts & 0xffffffffULL) * ticks_per_second; 699 ts += 0x80000000; /* rounding */ 700 pcap_header.ts.tv_usec = ts >> 32; 701 if (pcap_header.ts.tv_usec >= ticks_per_second) { 702 pcap_header.ts.tv_usec -= ticks_per_second; 703 pcap_header.ts.tv_sec++; 704 } 705 706 /* Fill in our own header data */ 707 pcap_header.caplen = caplen; 708 pcap_header.len = packet_len; 709 710 /* Count the packet. */ 711 pd->stat.ps_recv++; 712 713 /* Call the user supplied callback function */ 714 callback(user, &pcap_header, dp); 715 716 /* Only count packets that pass the filter, for consistency with standard Linux behaviour. */ 717 processed++; 718 if (processed == cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) 719 { 720 /* Reached the user-specified limit. */ 721 return cnt; 722 } 723 } 724 } 725 726 return processed; 727 } 728 729 static int 730 dag_inject(pcap_t *p, const void *buf _U_, int size _U_) 731 { 732 pcap_strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards", 733 PCAP_ERRBUF_SIZE); 734 return (-1); 735 } 736 737 /* 738 * Get a handle for a live capture from the given DAG device. Passing a NULL 739 * device will result in a failure. The promisc flag is ignored because DAG 740 * cards are always promiscuous. The to_ms parameter is used in setting the 741 * API polling parameters. 742 * 743 * snaplen is now also ignored, until we get per-stream slen support. Set 744 * slen with appropriate DAG tool BEFORE pcap_activate(). 745 * 746 * See also pcap(3). 747 */ 748 static int dag_activate(pcap_t* p) 749 { 750 struct pcap_dag *pd = p->priv; 751 char *s; 752 int n; 753 daginf_t* daginf; 754 char * newDev = NULL; 755 char * device = p->opt.device; 756 int ret; 757 dag_size_t mindata; 758 struct timeval maxwait; 759 struct timeval poll; 760 761 if (device == NULL) { 762 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL"); 763 return PCAP_ERROR; 764 } 765 766 /* Initialize some components of the pcap structure. */ 767 newDev = (char *)malloc(strlen(device) + 16); 768 if (newDev == NULL) { 769 ret = PCAP_ERROR; 770 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 771 errno, "Can't allocate string for device name"); 772 goto fail; 773 } 774 775 /* Parse input name to get dag device and stream number if provided */ 776 if (dag_parse_name(device, newDev, strlen(device) + 16, &pd->dag_stream) < 0) { 777 /* 778 * XXX - it'd be nice if this indicated what was wrong 779 * with the name. Does this reliably set errno? 780 * Should this return PCAP_ERROR_NO_SUCH_DEVICE in some 781 * cases? 782 */ 783 ret = PCAP_ERROR; 784 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 785 errno, "dag_parse_name"); 786 goto fail; 787 } 788 device = newDev; 789 790 if (pd->dag_stream%2) { 791 ret = PCAP_ERROR; 792 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture"); 793 goto fail; 794 } 795 796 /* setup device parameters */ 797 if((pd->dag_ref = dag_config_init((char *)device)) == NULL) { 798 /* 799 * XXX - does this reliably set errno? 800 */ 801 if (errno == ENOENT) { 802 /* 803 * There's nothing more to say, so clear 804 * the error message. 805 */ 806 ret = PCAP_ERROR_NO_SUCH_DEVICE; 807 p->errbuf[0] = '\0'; 808 } else if (errno == EPERM || errno == EACCES) { 809 ret = PCAP_ERROR_PERM_DENIED; 810 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 811 "Attempt to open %s failed with %s - additional privileges may be required", 812 device, (errno == EPERM) ? "EPERM" : "EACCES"); 813 } else { 814 ret = PCAP_ERROR; 815 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 816 errno, "dag_config_init %s", device); 817 } 818 goto fail; 819 } 820 821 if((p->fd = dag_config_get_card_fd(pd->dag_ref)) < 0) { 822 /* 823 * XXX - does this reliably set errno? 824 */ 825 ret = PCAP_ERROR; 826 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 827 errno, "dag_config_get_card_fd %s", device); 828 goto failclose; 829 } 830 831 /* Open requested stream. Can fail if already locked or on error */ 832 if (dag_attach_stream64(p->fd, pd->dag_stream, 0, 0) < 0) { 833 ret = PCAP_ERROR; 834 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 835 errno, "dag_attach_stream"); 836 goto failclose; 837 } 838 839 /* Try to find Stream Drop attribute */ 840 pd->drop_attr = kNullAttributeUuid; 841 pd->dag_root = dag_config_get_root_component(pd->dag_ref); 842 if ( dag_component_get_subcomponent(pd->dag_root, kComponentStreamFeatures, 0) ) 843 { 844 pd->drop_attr = dag_config_get_indexed_attribute_uuid(pd->dag_ref, kUint32AttributeStreamDropCount, pd->dag_stream/2); 845 } 846 847 /* Set up default poll parameters for stream 848 * Can be overridden by pcap_set_nonblock() 849 */ 850 if (dag_get_stream_poll64(p->fd, pd->dag_stream, 851 &mindata, &maxwait, &poll) < 0) { 852 ret = PCAP_ERROR; 853 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 854 errno, "dag_get_stream_poll"); 855 goto faildetach; 856 } 857 858 /* Use the poll time as the required select timeout for callers 859 * who are using select()/etc. in an event loop waiting for 860 * packets to arrive. 861 */ 862 pd->required_select_timeout = poll; 863 p->required_select_timeout = &pd->required_select_timeout; 864 865 /* 866 * Turn a negative snapshot value (invalid), a snapshot value of 867 * 0 (unspecified), or a value bigger than the normal maximum 868 * value, into the maximum allowed value. 869 * 870 * If some application really *needs* a bigger snapshot 871 * length, we should just increase MAXIMUM_SNAPLEN. 872 */ 873 if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN) 874 p->snapshot = MAXIMUM_SNAPLEN; 875 876 if (p->opt.immediate) { 877 /* Call callback immediately. 878 * XXX - is this the right way to p this? 879 */ 880 mindata = 0; 881 } else { 882 /* Amount of data to collect in Bytes before calling callbacks. 883 * Important for efficiency, but can introduce latency 884 * at low packet rates if to_ms not set! 885 */ 886 mindata = 65536; 887 } 888 889 /* Obey opt.timeout (was to_ms) if supplied. This is a good idea! 890 * Recommend 10-100ms. Calls will time out even if no data arrived. 891 */ 892 maxwait.tv_sec = p->opt.timeout/1000; 893 maxwait.tv_usec = (p->opt.timeout%1000) * 1000; 894 895 if (dag_set_stream_poll64(p->fd, pd->dag_stream, 896 mindata, &maxwait, &poll) < 0) { 897 ret = PCAP_ERROR; 898 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 899 errno, "dag_set_stream_poll"); 900 goto faildetach; 901 } 902 903 /* XXX Not calling dag_configure() to set slen; this is unsafe in 904 * multi-stream environments as the gpp config is global. 905 * Once the firmware provides 'per-stream slen' this can be supported 906 * again via the Config API without side-effects */ 907 #if 0 908 /* set the card snap length to the specified snaplen parameter */ 909 /* This is a really bad idea, as different cards have different 910 * valid slen ranges. Should fix in Config API. */ 911 if (p->snapshot == 0 || p->snapshot > MAX_DAG_SNAPLEN) { 912 p->snapshot = MAX_DAG_SNAPLEN; 913 } else if (snaplen < MIN_DAG_SNAPLEN) { 914 p->snapshot = MIN_DAG_SNAPLEN; 915 } 916 /* snap len has to be a multiple of 4 */ 917 #endif 918 919 if(dag_start_stream(p->fd, pd->dag_stream) < 0) { 920 ret = PCAP_ERROR; 921 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 922 errno, "dag_start_stream %s", device); 923 goto faildetach; 924 } 925 926 /* 927 * Important! You have to ensure bottom is properly 928 * initialized to zero on startup, it won't give you 929 * a compiler warning if you make this mistake! 930 */ 931 pd->dag_mem_bottom = 0; 932 pd->dag_mem_top = 0; 933 934 /* 935 * Find out how many FCS bits we should strip. 936 * First, query the card to see if it strips the FCS. 937 */ 938 daginf = dag_info(p->fd); 939 if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code)) { 940 /* DAG 4.2S and 4.23S already strip the FCS. Stripping the final word again truncates the packet. */ 941 pd->dag_fcs_bits = 0; 942 943 /* Note that no FCS will be supplied. */ 944 p->linktype_ext = LT_FCS_DATALINK_EXT(0); 945 } else { 946 /* 947 * Start out assuming it's 32 bits. 948 */ 949 pd->dag_fcs_bits = 32; 950 951 /* Allow an environment variable to override. */ 952 if ((s = getenv("ERF_FCS_BITS")) != NULL) { 953 if ((n = atoi(s)) == 0 || n == 16 || n == 32) { 954 pd->dag_fcs_bits = n; 955 } else { 956 ret = PCAP_ERROR; 957 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 958 "pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n); 959 goto failstop; 960 } 961 } 962 963 /* 964 * Did the user request that they not be stripped? 965 */ 966 if ((s = getenv("ERF_DONT_STRIP_FCS")) != NULL) { 967 /* Yes. Note the number of 16-bit words that will be 968 supplied. */ 969 p->linktype_ext = LT_FCS_DATALINK_EXT(pd->dag_fcs_bits/16); 970 971 /* And don't strip them. */ 972 pd->dag_fcs_bits = 0; 973 } 974 } 975 976 pd->dag_timeout = p->opt.timeout; 977 978 p->linktype = -1; 979 if (dag_get_datalink(p) < 0) { 980 ret = PCAP_ERROR; 981 goto failstop; 982 } 983 984 p->bufsize = 0; 985 986 if (new_pcap_dag(p) < 0) { 987 ret = PCAP_ERROR; 988 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 989 errno, "new_pcap_dag %s", device); 990 goto failstop; 991 } 992 993 /* 994 * "select()" and "poll()" don't work on DAG device descriptors. 995 */ 996 p->selectable_fd = -1; 997 998 if (newDev != NULL) { 999 free((char *)newDev); 1000 } 1001 1002 p->read_op = dag_read; 1003 p->inject_op = dag_inject; 1004 p->setfilter_op = install_bpf_program; 1005 p->setdirection_op = NULL; /* Not implemented.*/ 1006 p->set_datalink_op = dag_set_datalink; 1007 p->getnonblock_op = pcap_getnonblock_fd; 1008 p->setnonblock_op = dag_setnonblock; 1009 p->stats_op = dag_stats; 1010 p->cleanup_op = dag_platform_cleanup; 1011 pd->stat.ps_drop = 0; 1012 pd->stat.ps_recv = 0; 1013 pd->stat.ps_ifdrop = 0; 1014 return 0; 1015 1016 failstop: 1017 if (dag_stop_stream(p->fd, pd->dag_stream) < 0) { 1018 fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno)); 1019 } 1020 1021 faildetach: 1022 if (dag_detach_stream(p->fd, pd->dag_stream) < 0) 1023 fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno)); 1024 1025 failclose: 1026 dag_config_dispose(pd->dag_ref); 1027 /* 1028 * Note: we don't need to call close(p->fd) or dag_close(p->fd), 1029 * as dag_config_dispose(pd->dag_ref) does this. 1030 * 1031 * Set p->fd to -1 to make sure that's not done. 1032 */ 1033 p->fd = -1; 1034 pd->dag_ref = NULL; 1035 delete_pcap_dag(p); 1036 1037 fail: 1038 pcap_cleanup_live_common(p); 1039 if (newDev != NULL) { 1040 free((char *)newDev); 1041 } 1042 1043 return ret; 1044 } 1045 1046 pcap_t *dag_create(const char *device, char *ebuf, int *is_ours) 1047 { 1048 const char *cp; 1049 char *cpend; 1050 long devnum; 1051 pcap_t *p; 1052 long stream = 0; 1053 1054 /* Does this look like a DAG device? */ 1055 cp = strrchr(device, '/'); 1056 if (cp == NULL) 1057 cp = device; 1058 /* Does it begin with "dag"? */ 1059 if (strncmp(cp, "dag", 3) != 0) { 1060 /* Nope, doesn't begin with "dag" */ 1061 *is_ours = 0; 1062 return NULL; 1063 } 1064 /* Yes - is "dag" followed by a number from 0 to DAG_MAX_BOARDS-1 */ 1065 cp += 3; 1066 devnum = strtol(cp, &cpend, 10); 1067 if (*cpend == ':') { 1068 /* Followed by a stream number. */ 1069 stream = strtol(++cpend, &cpend, 10); 1070 } 1071 1072 if (cpend == cp || *cpend != '\0') { 1073 /* Not followed by a number. */ 1074 *is_ours = 0; 1075 return NULL; 1076 } 1077 1078 if (devnum < 0 || devnum >= DAG_MAX_BOARDS) { 1079 /* Followed by a non-valid number. */ 1080 *is_ours = 0; 1081 return NULL; 1082 } 1083 1084 if (stream <0 || stream >= DAG_STREAM_MAX) { 1085 /* Followed by a non-valid stream number. */ 1086 *is_ours = 0; 1087 return NULL; 1088 } 1089 1090 /* OK, it's probably ours. */ 1091 *is_ours = 1; 1092 1093 p = PCAP_CREATE_COMMON(ebuf, struct pcap_dag); 1094 if (p == NULL) 1095 return NULL; 1096 1097 p->activate_op = dag_activate; 1098 1099 /* 1100 * We claim that we support microsecond and nanosecond time 1101 * stamps. 1102 * 1103 * XXX Our native precision is 2^-32s, but libpcap doesn't support 1104 * power of two precisions yet. We can convert to either MICRO or NANO. 1105 */ 1106 p->tstamp_precision_list = malloc(2 * sizeof(u_int)); 1107 if (p->tstamp_precision_list == NULL) { 1108 pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE, 1109 errno, "malloc"); 1110 pcap_close(p); 1111 return NULL; 1112 } 1113 p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO; 1114 p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO; 1115 p->tstamp_precision_count = 2; 1116 return p; 1117 } 1118 1119 static int 1120 dag_stats(pcap_t *p, struct pcap_stat *ps) { 1121 struct pcap_dag *pd = p->priv; 1122 uint32_t stream_drop; 1123 dag_err_t dag_error; 1124 1125 /* 1126 * Packet records received (ps_recv) are counted in dag_read(). 1127 * Packet records dropped (ps_drop) are read from Stream Drop attribute if present, 1128 * otherwise integrate the ERF Header lctr counts (if available) in dag_read(). 1129 * We are reporting that no records are dropped by the card/driver (ps_ifdrop). 1130 */ 1131 1132 if(pd->drop_attr != kNullAttributeUuid) { 1133 /* Note this counter is cleared at start of capture and will wrap at UINT_MAX. 1134 * The application is responsible for polling ps_drop frequently enough 1135 * to detect each wrap and integrate total drop with a wider counter */ 1136 if ((dag_error = dag_config_get_uint32_attribute_ex(pd->dag_ref, pd->drop_attr, &stream_drop)) == kDagErrNone) { 1137 pd->stat.ps_drop = stream_drop; 1138 } else { 1139 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "reading stream drop attribute: %s", 1140 dag_config_strerror(dag_error)); 1141 return -1; 1142 } 1143 } 1144 1145 *ps = pd->stat; 1146 1147 return 0; 1148 } 1149 1150 /* 1151 * Add all DAG devices. 1152 */ 1153 int 1154 dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf) 1155 { 1156 char name[12]; /* XXX - pick a size */ 1157 int c; 1158 char dagname[DAGNAME_BUFSIZE]; 1159 int dagstream; 1160 int dagfd; 1161 dag_card_inf_t *inf; 1162 char *description; 1163 int stream, rxstreams; 1164 1165 /* Try all the DAGs 0-DAG_MAX_BOARDS */ 1166 for (c = 0; c < DAG_MAX_BOARDS; c++) { 1167 snprintf(name, 12, "dag%d", c); 1168 if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream)) 1169 { 1170 (void) snprintf(errbuf, PCAP_ERRBUF_SIZE, 1171 "dag: device name %s can't be parsed", name); 1172 return (-1); 1173 } 1174 if ( (dagfd = dag_open(dagname)) >= 0 ) { 1175 description = NULL; 1176 if ((inf = dag_pciinfo(dagfd))) 1177 description = dag_device_name(inf->device_code, 1); 1178 /* 1179 * XXX - is there a way to determine whether 1180 * the card is plugged into a network or not? 1181 * If so, we should check that and set 1182 * PCAP_IF_CONNECTION_STATUS_CONNECTED or 1183 * PCAP_IF_CONNECTION_STATUS_DISCONNECTED. 1184 * 1185 * Also, are there notions of "up" and "running"? 1186 */ 1187 if (add_dev(devlistp, name, 0, description, errbuf) == NULL) { 1188 /* 1189 * Failure. 1190 */ 1191 return (-1); 1192 } 1193 rxstreams = dag_rx_get_stream_count(dagfd); 1194 for(stream=0;stream<DAG_STREAM_MAX;stream+=2) { 1195 if (0 == dag_attach_stream64(dagfd, stream, 0, 0)) { 1196 dag_detach_stream(dagfd, stream); 1197 1198 snprintf(name, 10, "dag%d:%d", c, stream); 1199 if (add_dev(devlistp, name, 0, description, errbuf) == NULL) { 1200 /* 1201 * Failure. 1202 */ 1203 return (-1); 1204 } 1205 1206 rxstreams--; 1207 if(rxstreams <= 0) { 1208 break; 1209 } 1210 } 1211 } 1212 dag_close(dagfd); 1213 } 1214 1215 } 1216 return (0); 1217 } 1218 1219 static int 1220 dag_set_datalink(pcap_t *p, int dlt) 1221 { 1222 p->linktype = dlt; 1223 1224 return (0); 1225 } 1226 1227 static int 1228 dag_setnonblock(pcap_t *p, int nonblock) 1229 { 1230 struct pcap_dag *pd = p->priv; 1231 dag_size_t mindata; 1232 struct timeval maxwait; 1233 struct timeval poll; 1234 1235 /* 1236 * Set non-blocking mode on the FD. 1237 * XXX - is that necessary? If not, don't bother calling it, 1238 * and have a "dag_getnonblock()" function that looks at 1239 * "pd->dag_flags". 1240 */ 1241 if (pcap_setnonblock_fd(p, nonblock) < 0) 1242 return (-1); 1243 1244 if (dag_get_stream_poll64(p->fd, pd->dag_stream, 1245 &mindata, &maxwait, &poll) < 0) { 1246 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1247 errno, "dag_get_stream_poll"); 1248 return -1; 1249 } 1250 1251 /* Amount of data to collect in Bytes before calling callbacks. 1252 * Important for efficiency, but can introduce latency 1253 * at low packet rates if to_ms not set! 1254 */ 1255 if(nonblock) 1256 mindata = 0; 1257 else 1258 mindata = 65536; 1259 1260 if (dag_set_stream_poll64(p->fd, pd->dag_stream, 1261 mindata, &maxwait, &poll) < 0) { 1262 pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE, 1263 errno, "dag_set_stream_poll"); 1264 return -1; 1265 } 1266 1267 if (nonblock) { 1268 pd->dag_flags |= DAGF_NONBLOCK; 1269 } else { 1270 pd->dag_flags &= ~DAGF_NONBLOCK; 1271 } 1272 return (0); 1273 } 1274 1275 static int 1276 dag_get_datalink(pcap_t *p) 1277 { 1278 struct pcap_dag *pd = p->priv; 1279 int index=0, dlt_index=0; 1280 uint8_t types[255]; 1281 1282 memset(types, 0, 255); 1283 1284 if (p->dlt_list == NULL && (p->dlt_list = malloc(255*sizeof(*(p->dlt_list)))) == NULL) { 1285 pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 1286 errno, "malloc"); 1287 return (-1); 1288 } 1289 1290 p->linktype = 0; 1291 1292 #ifdef HAVE_DAG_GET_STREAM_ERF_TYPES 1293 /* Get list of possible ERF types for this card */ 1294 if (dag_get_stream_erf_types(p->fd, pd->dag_stream, types, 255) < 0) { 1295 pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 1296 errno, "dag_get_stream_erf_types"); 1297 return (-1); 1298 } 1299 1300 while (types[index]) { 1301 1302 #elif defined HAVE_DAG_GET_ERF_TYPES 1303 /* Get list of possible ERF types for this card */ 1304 if (dag_get_erf_types(p->fd, types, 255) < 0) { 1305 pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf), 1306 errno, "dag_get_erf_types"); 1307 return (-1); 1308 } 1309 1310 while (types[index]) { 1311 #else 1312 /* Check the type through a dagapi call. */ 1313 types[index] = dag_linktype(p->fd); 1314 1315 { 1316 #endif 1317 switch((types[index] & 0x7f)) { 1318 1319 case ERF_TYPE_HDLC_POS: 1320 case ERF_TYPE_COLOR_HDLC_POS: 1321 case ERF_TYPE_DSM_COLOR_HDLC_POS: 1322 case ERF_TYPE_COLOR_HASH_POS: 1323 1324 if (p->dlt_list != NULL) { 1325 p->dlt_list[dlt_index++] = DLT_CHDLC; 1326 p->dlt_list[dlt_index++] = DLT_PPP_SERIAL; 1327 p->dlt_list[dlt_index++] = DLT_FRELAY; 1328 } 1329 if(!p->linktype) 1330 p->linktype = DLT_CHDLC; 1331 break; 1332 1333 case ERF_TYPE_ETH: 1334 case ERF_TYPE_COLOR_ETH: 1335 case ERF_TYPE_DSM_COLOR_ETH: 1336 case ERF_TYPE_COLOR_HASH_ETH: 1337 /* 1338 * This is (presumably) a real Ethernet capture; give it a 1339 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 1340 * that an application can let you choose it, in case you're 1341 * capturing DOCSIS traffic that a Cisco Cable Modem 1342 * Termination System is putting out onto an Ethernet (it 1343 * doesn't put an Ethernet header onto the wire, it puts raw 1344 * DOCSIS frames out on the wire inside the low-level 1345 * Ethernet framing). 1346 */ 1347 if (p->dlt_list != NULL) { 1348 p->dlt_list[dlt_index++] = DLT_EN10MB; 1349 p->dlt_list[dlt_index++] = DLT_DOCSIS; 1350 } 1351 if(!p->linktype) 1352 p->linktype = DLT_EN10MB; 1353 break; 1354 1355 case ERF_TYPE_ATM: 1356 case ERF_TYPE_AAL5: 1357 case ERF_TYPE_MC_ATM: 1358 case ERF_TYPE_MC_AAL5: 1359 if (p->dlt_list != NULL) { 1360 p->dlt_list[dlt_index++] = DLT_ATM_RFC1483; 1361 p->dlt_list[dlt_index++] = DLT_SUNATM; 1362 } 1363 if(!p->linktype) 1364 p->linktype = DLT_ATM_RFC1483; 1365 break; 1366 1367 case ERF_TYPE_COLOR_MC_HDLC_POS: 1368 case ERF_TYPE_MC_HDLC: 1369 if (p->dlt_list != NULL) { 1370 p->dlt_list[dlt_index++] = DLT_CHDLC; 1371 p->dlt_list[dlt_index++] = DLT_PPP_SERIAL; 1372 p->dlt_list[dlt_index++] = DLT_FRELAY; 1373 p->dlt_list[dlt_index++] = DLT_MTP2; 1374 p->dlt_list[dlt_index++] = DLT_MTP2_WITH_PHDR; 1375 p->dlt_list[dlt_index++] = DLT_LAPD; 1376 } 1377 if(!p->linktype) 1378 p->linktype = DLT_CHDLC; 1379 break; 1380 1381 case ERF_TYPE_IPV4: 1382 if (p->dlt_list != NULL) { 1383 p->dlt_list[dlt_index++] = DLT_RAW; 1384 p->dlt_list[dlt_index++] = DLT_IPV4; 1385 } 1386 if(!p->linktype) 1387 p->linktype = DLT_RAW; 1388 break; 1389 1390 case ERF_TYPE_IPV6: 1391 if (p->dlt_list != NULL) { 1392 p->dlt_list[dlt_index++] = DLT_RAW; 1393 p->dlt_list[dlt_index++] = DLT_IPV6; 1394 } 1395 if(!p->linktype) 1396 p->linktype = DLT_RAW; 1397 break; 1398 1399 case ERF_TYPE_LEGACY: 1400 case ERF_TYPE_MC_RAW: 1401 case ERF_TYPE_MC_RAW_CHANNEL: 1402 case ERF_TYPE_IP_COUNTER: 1403 case ERF_TYPE_TCP_FLOW_COUNTER: 1404 case ERF_TYPE_INFINIBAND: 1405 case ERF_TYPE_RAW_LINK: 1406 case ERF_TYPE_INFINIBAND_LINK: 1407 case ERF_TYPE_META: 1408 default: 1409 /* Libpcap cannot deal with these types yet */ 1410 /* Add no 'native' DLTs, but still covered by DLT_ERF */ 1411 break; 1412 1413 } /* switch */ 1414 index++; 1415 } 1416 1417 p->dlt_list[dlt_index++] = DLT_ERF; 1418 1419 p->dlt_count = dlt_index; 1420 1421 if(!p->linktype) 1422 p->linktype = DLT_ERF; 1423 1424 return p->linktype; 1425 } 1426 1427 #ifdef DAG_ONLY 1428 /* 1429 * This libpcap build supports only DAG cards, not regular network 1430 * interfaces. 1431 */ 1432 1433 /* 1434 * There are no regular interfaces, just DAG interfaces. 1435 */ 1436 int 1437 pcap_platform_finddevs(pcap_if_list_t *devlistp _U_, char *errbuf) 1438 { 1439 return (0); 1440 } 1441 1442 /* 1443 * Attempts to open a regular interface fail. 1444 */ 1445 pcap_t * 1446 pcap_create_interface(const char *device, char *errbuf) 1447 { 1448 snprintf(errbuf, PCAP_ERRBUF_SIZE, 1449 "This version of libpcap only supports DAG cards"); 1450 return NULL; 1451 } 1452 1453 /* 1454 * Libpcap version string. 1455 */ 1456 const char * 1457 pcap_lib_version(void) 1458 { 1459 return (PCAP_VERSION_STRING " (DAG-only)"); 1460 } 1461 #endif 1462