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