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