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