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