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