1/* 2 * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy) 3 * Copyright (c) 2005 - 2008 CACE Technologies, Davis (California) 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the Politecnico di Torino, CACE Technologies 16 * nor the names of its contributors may be used to endorse or promote 17 * products derived from this software without specific prior written 18 * permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34#include <pcap-int.h> 35#include <Packet32.h> 36#ifdef __MINGW32__ 37#ifdef __MINGW64__ 38#include <ntddndis.h> 39#else /*__MINGW64__*/ 40#include <ddk/ntddndis.h> 41#include <ddk/ndis.h> 42#endif /*__MINGW64__*/ 43#else /*__MINGW32__*/ 44#include <ntddndis.h> 45#endif /*__MINGW32__*/ 46#ifdef HAVE_DAG_API 47#include <dagnew.h> 48#include <dagapi.h> 49#endif /* HAVE_DAG_API */ 50#ifdef __MINGW32__ 51int* _errno(); 52#define errno (*_errno()) 53#endif /* __MINGW32__ */ 54 55static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *); 56static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *); 57static int pcap_getnonblock_win32(pcap_t *, char *); 58static int pcap_setnonblock_win32(pcap_t *, int, char *); 59 60/*dimension of the buffer in the pcap_t structure*/ 61#define WIN32_DEFAULT_USER_BUFFER_SIZE 256000 62 63/*dimension of the buffer in the kernel driver NPF */ 64#define WIN32_DEFAULT_KERNEL_BUFFER_SIZE 1000000 65 66/* Equivalent to ntohs(), but a lot faster under Windows */ 67#define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8) 68 69/* 70 * Private data for capturing on WinPcap devices. 71 */ 72struct pcap_win { 73 int nonblock; 74 75 int filtering_in_kernel; /* using kernel filter */ 76 77#ifdef HAVE_DAG_API 78 int dag_fcs_bits; /* Number of checksum bits from link layer */ 79#endif 80}; 81 82/* 83 * Header that the WinPcap driver associates to the packets. 84 * Once was in bpf.h 85 */ 86struct bpf_hdr { 87 struct timeval bh_tstamp; /* time stamp */ 88 bpf_u_int32 bh_caplen; /* length of captured portion */ 89 bpf_u_int32 bh_datalen; /* original length of packet */ 90 u_short bh_hdrlen; /* length of bpf header (this struct 91 plus alignment padding) */ 92}; 93 94CRITICAL_SECTION g_PcapCompileCriticalSection; 95 96BOOL WINAPI DllMain( 97 HANDLE hinstDLL, 98 DWORD dwReason, 99 LPVOID lpvReserved 100) 101{ 102 if (dwReason == DLL_PROCESS_ATTACH) 103 { 104 InitializeCriticalSection(&g_PcapCompileCriticalSection); 105 } 106 107 return TRUE; 108} 109 110/* Start winsock */ 111int 112wsockinit() 113{ 114 WORD wVersionRequested; 115 WSADATA wsaData; 116 static int err = -1; 117 static int done = 0; 118 119 if (done) 120 return err; 121 122 wVersionRequested = MAKEWORD( 1, 1); 123 err = WSAStartup( wVersionRequested, &wsaData ); 124 atexit ((void(*)(void))WSACleanup); 125 InitializeCriticalSection(&g_PcapCompileCriticalSection); 126 done = 1; 127 128 if ( err != 0 ) 129 err = -1; 130 return err; 131} 132 133int pcap_wsockinit() 134{ 135 return wsockinit(); 136} 137 138static int 139pcap_stats_win32(pcap_t *p, struct pcap_stat *ps) 140{ 141 142 if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){ 143 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror()); 144 return -1; 145 } 146 147 return 0; 148} 149 150/* Set the dimension of the kernel-level capture buffer */ 151static int 152pcap_setbuff_win32(pcap_t *p, int dim) 153{ 154 if(PacketSetBuff(p->adapter,dim)==FALSE) 155 { 156 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer"); 157 return -1; 158 } 159 return 0; 160} 161 162/* Set the driver working mode */ 163static int 164pcap_setmode_win32(pcap_t *p, int mode) 165{ 166 if(PacketSetMode(p->adapter,mode)==FALSE) 167 { 168 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized"); 169 return -1; 170 } 171 172 return 0; 173} 174 175/*set the minimum amount of data that will release a read call*/ 176static int 177pcap_setmintocopy_win32(pcap_t *p, int size) 178{ 179 if(PacketSetMinToCopy(p->adapter, size)==FALSE) 180 { 181 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size"); 182 return -1; 183 } 184 return 0; 185} 186 187/*return the Adapter for a pcap_t*/ 188static Adapter * 189pcap_getadapter_win32(pcap_t *p) 190{ 191 return p->adapter; 192} 193 194static int 195pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 196{ 197 int cc; 198 int n = 0; 199 register u_char *bp, *ep; 200 u_char *datap; 201 struct pcap_win *pw = p->priv; 202 203 cc = p->cc; 204 if (p->cc == 0) { 205 /* 206 * Has "pcap_breakloop()" been called? 207 */ 208 if (p->break_loop) { 209 /* 210 * Yes - clear the flag that indicates that it 211 * has, and return PCAP_ERROR_BREAK to indicate 212 * that we were told to break out of the loop. 213 */ 214 p->break_loop = 0; 215 return (PCAP_ERROR_BREAK); 216 } 217 218 /* capture the packets */ 219 if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){ 220 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed"); 221 return (PCAP_ERROR); 222 } 223 224 cc = p->Packet->ulBytesReceived; 225 226 bp = p->Packet->Buffer; 227 } 228 else 229 bp = p->bp; 230 231 /* 232 * Loop through each packet. 233 */ 234#define bhp ((struct bpf_hdr *)bp) 235 ep = bp + cc; 236 while (1) { 237 register int caplen, hdrlen; 238 239 /* 240 * Has "pcap_breakloop()" been called? 241 * If so, return immediately - if we haven't read any 242 * packets, clear the flag and return PCAP_ERROR_BREAK 243 * to indicate that we were told to break out of the loop, 244 * otherwise leave the flag set, so that the *next* call 245 * will break out of the loop without having read any 246 * packets, and return the number of packets we've 247 * processed so far. 248 */ 249 if (p->break_loop) { 250 if (n == 0) { 251 p->break_loop = 0; 252 return (PCAP_ERROR_BREAK); 253 } else { 254 p->bp = bp; 255 p->cc = ep - bp; 256 return (n); 257 } 258 } 259 if (bp >= ep) 260 break; 261 262 caplen = bhp->bh_caplen; 263 hdrlen = bhp->bh_hdrlen; 264 datap = bp + hdrlen; 265 266 /* 267 * Short-circuit evaluation: if using BPF filter 268 * in kernel, no need to do it now - we already know 269 * the packet passed the filter. 270 * 271 * XXX - bpf_filter() should always return TRUE if 272 * handed a null pointer for the program, but it might 273 * just try to "run" the filter, so we check here. 274 */ 275 if (pw->filtering_in_kernel || 276 p->fcode.bf_insns == NULL || 277 bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) { 278 /* 279 * XXX A bpf_hdr matches a pcap_pkthdr. 280 */ 281 (*callback)(user, (struct pcap_pkthdr*)bp, datap); 282 bp += Packet_WORDALIGN(caplen + hdrlen); 283 if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) { 284 p->bp = bp; 285 p->cc = ep - bp; 286 return (n); 287 } 288 } else { 289 /* 290 * Skip this packet. 291 */ 292 bp += Packet_WORDALIGN(caplen + hdrlen); 293 } 294 } 295#undef bhp 296 p->cc = 0; 297 return (n); 298} 299 300#ifdef HAVE_DAG_API 301static int 302pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 303{ 304 struct pcap_win *pw = p->priv; 305 u_char *dp = NULL; 306 int packet_len = 0, caplen = 0; 307 struct pcap_pkthdr pcap_header; 308 u_char *endofbuf; 309 int n = 0; 310 dag_record_t *header; 311 unsigned erf_record_len; 312 ULONGLONG ts; 313 int cc; 314 unsigned swt; 315 unsigned dfp = p->adapter->DagFastProcess; 316 317 cc = p->cc; 318 if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */ 319 { 320 /* Get new packets from the network */ 321 if(PacketReceivePacket(p->adapter, p->Packet, TRUE)==FALSE){ 322 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed"); 323 return (-1); 324 } 325 326 cc = p->Packet->ulBytesReceived; 327 if(cc == 0) 328 /* The timeout has expired but we no packets arrived */ 329 return 0; 330 header = (dag_record_t*)p->adapter->DagBuffer; 331 } 332 else 333 header = (dag_record_t*)p->bp; 334 335 endofbuf = (char*)header + cc; 336 337 /* 338 * Cycle through the packets 339 */ 340 do 341 { 342 erf_record_len = SWAPS(header->rlen); 343 if((char*)header + erf_record_len > endofbuf) 344 break; 345 346 /* Increase the number of captured packets */ 347 pw->stat.ps_recv++; 348 349 /* Find the beginning of the packet */ 350 dp = ((u_char *)header) + dag_record_size; 351 352 /* Determine actual packet len */ 353 switch(header->type) 354 { 355 case TYPE_ATM: 356 packet_len = ATM_SNAPLEN; 357 caplen = ATM_SNAPLEN; 358 dp += 4; 359 360 break; 361 362 case TYPE_ETH: 363 swt = SWAPS(header->wlen); 364 packet_len = swt - (pw->dag_fcs_bits); 365 caplen = erf_record_len - dag_record_size - 2; 366 if (caplen > packet_len) 367 { 368 caplen = packet_len; 369 } 370 dp += 2; 371 372 break; 373 374 case TYPE_HDLC_POS: 375 swt = SWAPS(header->wlen); 376 packet_len = swt - (pw->dag_fcs_bits); 377 caplen = erf_record_len - dag_record_size; 378 if (caplen > packet_len) 379 { 380 caplen = packet_len; 381 } 382 383 break; 384 } 385 386 if(caplen > p->snapshot) 387 caplen = p->snapshot; 388 389 /* 390 * Has "pcap_breakloop()" been called? 391 * If so, return immediately - if we haven't read any 392 * packets, clear the flag and return -2 to indicate 393 * that we were told to break out of the loop, otherwise 394 * leave the flag set, so that the *next* call will break 395 * out of the loop without having read any packets, and 396 * return the number of packets we've processed so far. 397 */ 398 if (p->break_loop) 399 { 400 if (n == 0) 401 { 402 p->break_loop = 0; 403 return (-2); 404 } 405 else 406 { 407 p->bp = (char*)header; 408 p->cc = endofbuf - (char*)header; 409 return (n); 410 } 411 } 412 413 if(!dfp) 414 { 415 /* convert between timestamp formats */ 416 ts = header->ts; 417 pcap_header.ts.tv_sec = (int)(ts >> 32); 418 ts = (ts & 0xffffffffi64) * 1000000; 419 ts += 0x80000000; /* rounding */ 420 pcap_header.ts.tv_usec = (int)(ts >> 32); 421 if (pcap_header.ts.tv_usec >= 1000000) { 422 pcap_header.ts.tv_usec -= 1000000; 423 pcap_header.ts.tv_sec++; 424 } 425 } 426 427 /* No underlaying filtering system. We need to filter on our own */ 428 if (p->fcode.bf_insns) 429 { 430 if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0) 431 { 432 /* Move to next packet */ 433 header = (dag_record_t*)((char*)header + erf_record_len); 434 continue; 435 } 436 } 437 438 /* Fill the header for the user suppplied callback function */ 439 pcap_header.caplen = caplen; 440 pcap_header.len = packet_len; 441 442 /* Call the callback function */ 443 (*callback)(user, &pcap_header, dp); 444 445 /* Move to next packet */ 446 header = (dag_record_t*)((char*)header + erf_record_len); 447 448 /* Stop if the number of packets requested by user has been reached*/ 449 if (++n >= cnt && !PACKET_COUNT_IS_UNLIMITED(cnt)) 450 { 451 p->bp = (char*)header; 452 p->cc = endofbuf - (char*)header; 453 return (n); 454 } 455 } 456 while((u_char*)header < endofbuf); 457 458 return 1; 459} 460#endif /* HAVE_DAG_API */ 461 462/* Send a packet to the network */ 463static int 464pcap_inject_win32(pcap_t *p, const void *buf, size_t size){ 465 LPPACKET PacketToSend; 466 467 PacketToSend=PacketAllocatePacket(); 468 469 if (PacketToSend == NULL) 470 { 471 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketAllocatePacket failed"); 472 return -1; 473 } 474 475 PacketInitPacket(PacketToSend,(PVOID)buf,size); 476 if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){ 477 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send error: PacketSendPacket failed"); 478 PacketFreePacket(PacketToSend); 479 return -1; 480 } 481 482 PacketFreePacket(PacketToSend); 483 484 /* 485 * We assume it all got sent if "PacketSendPacket()" succeeded. 486 * "pcap_inject()" is expected to return the number of bytes 487 * sent. 488 */ 489 return size; 490} 491 492static void 493pcap_cleanup_win32(pcap_t *p) 494{ 495 if (p->adapter != NULL) { 496 PacketCloseAdapter(p->adapter); 497 p->adapter = NULL; 498 } 499 if (p->Packet) { 500 PacketFreePacket(p->Packet); 501 p->Packet = NULL; 502 } 503 pcap_cleanup_live_common(p); 504} 505 506static int 507pcap_activate_win32(pcap_t *p) 508{ 509 struct pcap_win *pw = p->priv; 510 NetType type; 511 512 if (p->opt.rfmon) { 513 /* 514 * No monitor mode on Windows. It could be done on 515 * Vista with drivers that support the native 802.11 516 * mechanism and monitor mode. 517 */ 518 return (PCAP_ERROR_RFMON_NOTSUP); 519 } 520 521 /* Init WinSock */ 522 wsockinit(); 523 524 p->adapter = PacketOpenAdapter(p->opt.source); 525 526 if (p->adapter == NULL) 527 { 528 /* Adapter detected but we are not able to open it. Return failure. */ 529 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror()); 530 return PCAP_ERROR; 531 } 532 533 /*get network type*/ 534 if(PacketGetNetType (p->adapter,&type) == FALSE) 535 { 536 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror()); 537 goto bad; 538 } 539 540 /*Set the linktype*/ 541 switch (type.LinkType) 542 { 543 case NdisMediumWan: 544 p->linktype = DLT_EN10MB; 545 break; 546 547 case NdisMedium802_3: 548 p->linktype = DLT_EN10MB; 549 /* 550 * This is (presumably) a real Ethernet capture; give it a 551 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 552 * that an application can let you choose it, in case you're 553 * capturing DOCSIS traffic that a Cisco Cable Modem 554 * Termination System is putting out onto an Ethernet (it 555 * doesn't put an Ethernet header onto the wire, it puts raw 556 * DOCSIS frames out on the wire inside the low-level 557 * Ethernet framing). 558 */ 559 p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 560 /* 561 * If that fails, just leave the list empty. 562 */ 563 if (p->dlt_list != NULL) { 564 p->dlt_list[0] = DLT_EN10MB; 565 p->dlt_list[1] = DLT_DOCSIS; 566 p->dlt_count = 2; 567 } 568 break; 569 570 case NdisMediumFddi: 571 p->linktype = DLT_FDDI; 572 break; 573 574 case NdisMedium802_5: 575 p->linktype = DLT_IEEE802; 576 break; 577 578 case NdisMediumArcnetRaw: 579 p->linktype = DLT_ARCNET; 580 break; 581 582 case NdisMediumArcnet878_2: 583 p->linktype = DLT_ARCNET; 584 break; 585 586 case NdisMediumAtm: 587 p->linktype = DLT_ATM_RFC1483; 588 break; 589 590 case NdisMediumCHDLC: 591 p->linktype = DLT_CHDLC; 592 break; 593 594 case NdisMediumPPPSerial: 595 p->linktype = DLT_PPP_SERIAL; 596 break; 597 598 case NdisMediumNull: 599 p->linktype = DLT_NULL; 600 break; 601 602 case NdisMediumBare80211: 603 p->linktype = DLT_IEEE802_11; 604 break; 605 606 case NdisMediumRadio80211: 607 p->linktype = DLT_IEEE802_11_RADIO; 608 break; 609 610 case NdisMediumPpi: 611 p->linktype = DLT_PPI; 612 break; 613 614 default: 615 p->linktype = DLT_EN10MB; /*an unknown adapter is assumed to be ethernet*/ 616 break; 617 } 618 619 /* Set promiscuous mode */ 620 if (p->opt.promisc) 621 { 622 623 if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS) == FALSE) 624 { 625 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to promiscuous mode"); 626 goto bad; 627 } 628 } 629 else 630 { 631 if (PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL) == FALSE) 632 { 633 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to set hardware filter to non-promiscuous mode"); 634 goto bad; 635 } 636 } 637 638 /* Set the buffer size */ 639 p->bufsize = WIN32_DEFAULT_USER_BUFFER_SIZE; 640 641 /* allocate Packet structure used during the capture */ 642 if((p->Packet = PacketAllocatePacket())==NULL) 643 { 644 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure"); 645 goto bad; 646 } 647 648 if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD)) 649 { 650 /* 651 * Traditional Adapter 652 */ 653 /* 654 * If the buffer size wasn't explicitly set, default to 655 * WIN32_DEFAULT_USER_BUFFER_SIZE. 656 */ 657 if (p->opt.buffer_size == 0) 658 p->opt.buffer_size = WIN32_DEFAULT_KERNEL_BUFFER_SIZE; 659 660 if(PacketSetBuff(p->adapter,p->opt.buffer_size)==FALSE) 661 { 662 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer"); 663 goto bad; 664 } 665 666 p->buffer = (u_char *)malloc(p->bufsize); 667 if (p->buffer == NULL) 668 { 669 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); 670 goto bad; 671 } 672 673 PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize); 674 675 if (p->opt.immediate) 676 { 677 /* tell the driver to copy the buffer as soon as data arrives */ 678 if(PacketSetMinToCopy(p->adapter,0)==FALSE) 679 { 680 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s", pcap_win32strerror()); 681 goto bad; 682 } 683 } 684 else 685 { 686 /* tell the driver to copy the buffer only if it contains at least 16K */ 687 if(PacketSetMinToCopy(p->adapter,16000)==FALSE) 688 { 689 snprintf(p->errbuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s", pcap_win32strerror()); 690 goto bad; 691 } 692 } 693 } 694 else 695#ifdef HAVE_DAG_API 696 { 697 /* 698 * Dag Card 699 */ 700 LONG status; 701 HKEY dagkey; 702 DWORD lptype; 703 DWORD lpcbdata; 704 int postype = 0; 705 char keyname[512]; 706 707 snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s", 708 "SYSTEM\\CurrentControlSet\\Services\\DAG", 709 strstr(_strlwr(p->opt.source), "dag")); 710 do 711 { 712 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey); 713 if(status != ERROR_SUCCESS) 714 break; 715 716 status = RegQueryValueEx(dagkey, 717 "PosType", 718 NULL, 719 &lptype, 720 (char*)&postype, 721 &lpcbdata); 722 723 if(status != ERROR_SUCCESS) 724 { 725 postype = 0; 726 } 727 728 RegCloseKey(dagkey); 729 } 730 while(FALSE); 731 732 733 p->snapshot = PacketSetSnapLen(p->adapter, snaplen); 734 735 /* Set the length of the FCS associated to any packet. This value 736 * will be subtracted to the packet length */ 737 pw->dag_fcs_bits = p->adapter->DagFcsLen; 738 } 739#else 740 goto bad; 741#endif /* HAVE_DAG_API */ 742 743 PacketSetReadTimeout(p->adapter, p->opt.timeout); 744 745#ifdef HAVE_DAG_API 746 if(p->adapter->Flags & INFO_FLAG_DAG_CARD) 747 { 748 /* install dag specific handlers for read and setfilter */ 749 p->read_op = pcap_read_win32_dag; 750 p->setfilter_op = pcap_setfilter_win32_dag; 751 } 752 else 753 { 754#endif /* HAVE_DAG_API */ 755 /* install traditional npf handlers for read and setfilter */ 756 p->read_op = pcap_read_win32_npf; 757 p->setfilter_op = pcap_setfilter_win32_npf; 758#ifdef HAVE_DAG_API 759 } 760#endif /* HAVE_DAG_API */ 761 p->setdirection_op = NULL; /* Not implemented. */ 762 /* XXX - can this be implemented on some versions of Windows? */ 763 p->inject_op = pcap_inject_win32; 764 p->set_datalink_op = NULL; /* can't change data link type */ 765 p->getnonblock_op = pcap_getnonblock_win32; 766 p->setnonblock_op = pcap_setnonblock_win32; 767 p->stats_op = pcap_stats_win32; 768 p->setbuff_op = pcap_setbuff_win32; 769 p->setmode_op = pcap_setmode_win32; 770 p->setmintocopy_op = pcap_setmintocopy_win32; 771 p->getadapter_op = pcap_getadapter_win32; 772 p->cleanup_op = pcap_cleanup_win32; 773 774 return (0); 775bad: 776 pcap_cleanup_win32(p); 777 return (PCAP_ERROR); 778} 779 780pcap_t * 781pcap_create_interface(const char *device, char *ebuf) 782{ 783 pcap_t *p; 784 785 if (strlen(device) == 1) 786 { 787 /* 788 * It's probably a unicode string 789 * Convert to ascii and pass it to pcap_create_common 790 * 791 * This wonderful hack is needed because pcap_lookupdev still returns 792 * unicode strings, and it's used by windump when no device is specified 793 * in the command line 794 */ 795 size_t length; 796 char* deviceAscii; 797 798 length = wcslen((wchar_t*)device); 799 800 deviceAscii = (char*)malloc(length + 1); 801 802 if (deviceAscii == NULL) 803 { 804 snprintf(ebuf, PCAP_ERRBUF_SIZE, "Malloc failed"); 805 return NULL; 806 } 807 808 snprintf(deviceAscii, length + 1, "%ws", (wchar_t*)device); 809 p = pcap_create_common(deviceAscii, ebuf, sizeof (struct pcap_win)); 810 free(deviceAscii); 811 } 812 else 813 { 814 p = pcap_create_common(device, ebuf, sizeof (struct pcap_win)); 815 } 816 817 if (p == NULL) 818 return (NULL); 819 820 p->activate_op = pcap_activate_win32; 821 return (p); 822} 823 824static int 825pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp) 826{ 827 struct pcap_win *pw = p->priv; 828 829 if(PacketSetBpf(p->adapter,fp)==FALSE){ 830 /* 831 * Kernel filter not installed. 832 * 833 * XXX - we don't know whether this failed because: 834 * 835 * the kernel rejected the filter program as invalid, 836 * in which case we should fall back on userland 837 * filtering; 838 * 839 * the kernel rejected the filter program as too big, 840 * in which case we should again fall back on 841 * userland filtering; 842 * 843 * there was some other problem, in which case we 844 * should probably report an error. 845 * 846 * For NPF devices, the Win32 status will be 847 * STATUS_INVALID_DEVICE_REQUEST for invalid 848 * filters, but I don't know what it'd be for 849 * other problems, and for some other devices 850 * it might not be set at all. 851 * 852 * So we just fall back on userland filtering in 853 * all cases. 854 */ 855 856 /* 857 * install_bpf_program() validates the program. 858 * 859 * XXX - what if we already have a filter in the kernel? 860 */ 861 if (install_bpf_program(p, fp) < 0) 862 return (-1); 863 pw->filtering_in_kernel = 0; /* filtering in userland */ 864 return (0); 865 } 866 867 /* 868 * It worked. 869 */ 870 pw->filtering_in_kernel = 1; /* filtering in the kernel */ 871 872 /* 873 * Discard any previously-received packets, as they might have 874 * passed whatever filter was formerly in effect, but might 875 * not pass this filter (BIOCSETF discards packets buffered 876 * in the kernel, so you can lose packets in any case). 877 */ 878 p->cc = 0; 879 return (0); 880} 881 882/* 883 * We filter at user level, since the kernel driver does't process the packets 884 */ 885static int 886pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) { 887 888 if(!fp) 889 { 890 strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf)); 891 return -1; 892 } 893 894 /* Install a user level filter */ 895 if (install_bpf_program(p, fp) < 0) 896 { 897 snprintf(p->errbuf, sizeof(p->errbuf), 898 "setfilter, unable to install the filter: %s", pcap_strerror(errno)); 899 return -1; 900 } 901 902 return (0); 903} 904 905static int 906pcap_getnonblock_win32(pcap_t *p, char *errbuf) 907{ 908 struct pcap_win *pw = p->priv; 909 910 /* 911 * XXX - if there were a PacketGetReadTimeout() call, we 912 * would use it, and return 1 if the timeout is -1 913 * and 0 otherwise. 914 */ 915 return (pw->nonblock); 916} 917 918static int 919pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf) 920{ 921 struct pcap_win *pw = p->priv; 922 int newtimeout; 923 924 if (nonblock) { 925 /* 926 * Set the read timeout to -1 for non-blocking mode. 927 */ 928 newtimeout = -1; 929 } else { 930 /* 931 * Restore the timeout set when the device was opened. 932 * (Note that this may be -1, in which case we're not 933 * really leaving non-blocking mode.) 934 */ 935 newtimeout = p->opt.timeout; 936 } 937 if (!PacketSetReadTimeout(p->adapter, newtimeout)) { 938 snprintf(errbuf, PCAP_ERRBUF_SIZE, 939 "PacketSetReadTimeout: %s", pcap_win32strerror()); 940 return (-1); 941 } 942 pw->nonblock = (newtimeout == -1); 943 return (0); 944} 945 946/*platform-dependent routine to add devices other than NDIS interfaces*/ 947int 948pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf) 949{ 950 return (0); 951} 952