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