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