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