00001 /* 00002 * Copyright (c) 1999 - 2003 00003 * NetGroup, Politecnico di Torino (Italy) 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 00010 * 1. Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * 2. Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in the 00014 * documentation and/or other materials provided with the distribution. 00015 * 3. Neither the name of the Politecnico di Torino nor the names of its 00016 * contributors may be used to endorse or promote products derived from 00017 * this software without specific prior written permission. 00018 * 00019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00020 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00021 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00022 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00023 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00025 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00026 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00027 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00029 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 * 00031 */ 00032 00033 #ifndef lint 00034 static const char rcsid[] _U_ = 00035 "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.19 2003/12/18 23:32:33 guy Exp $ (LBL)"; 00036 #endif 00037 00038 #include <pcap-int.h> 00039 #include <packet32.h> 00040 #include <Ntddndis.h> 00041 #ifdef HAVE_DAG_API 00042 #include <dagnew.h> 00043 #include <dagapi.h> 00044 #endif /* HAVE_DAG_API */ 00045 #ifdef __MINGW32__ 00046 int* _errno(); 00047 #define errno (*_errno()) 00048 #endif /* __MINGW32__ */ 00049 00050 #ifdef HAVE_REMOTE 00051 #include <pcap-remote.h> 00052 #endif /* HAVE_REMOTE */ 00053 00054 00055 static int pcap_setfilter_win32_npf(pcap_t *, struct bpf_program *); 00056 static int pcap_setfilter_win32_dag(pcap_t *, struct bpf_program *); 00057 static int pcap_getnonblock_win32(pcap_t *, char *); 00058 static int pcap_setnonblock_win32(pcap_t *, int, char *); 00059 00060 #define PcapBufSize 256000 /*dimension of the buffer in the pcap_t structure*/ 00061 #define SIZE_BUF 1000000 00062 00063 /* Equivalent to ntohs(), but a lot faster under Windows */ 00064 #define SWAPS(_X) ((_X & 0xff) << 8) | (_X >> 8) 00065 00066 /* 00067 * Header that the WinPcap driver associates to the packets. 00068 * Once was in bpf.h 00069 */ 00070 struct bpf_hdr { 00071 struct timeval bh_tstamp; /* time stamp */ 00072 bpf_u_int32 bh_caplen; /* length of captured portion */ 00073 bpf_u_int32 bh_datalen; /* original length of packet */ 00074 u_short bh_hdrlen; /* length of bpf header (this struct 00075 plus alignment padding) */ 00076 }; 00077 00078 /* Start winsock */ 00079 int 00080 wsockinit() 00081 { 00082 WORD wVersionRequested; 00083 WSADATA wsaData; 00084 int err; 00085 wVersionRequested = MAKEWORD( 1, 1); 00086 err = WSAStartup( wVersionRequested, &wsaData ); 00087 if ( err != 0 ) 00088 { 00089 return -1; 00090 } 00091 return 0; 00092 } 00093 00094 00095 static int 00096 pcap_stats_win32(pcap_t *p, struct pcap_stat *ps) 00097 { 00098 00099 if(PacketGetStats(p->adapter, (struct bpf_stat*)ps) != TRUE){ 00100 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStats error: %s", pcap_win32strerror()); 00101 return -1; 00102 } 00103 00104 // ps->ps_recv = p->md.stat.ps_recv + p->md.stat.ps_drop; 00105 return 0; 00106 } 00107 00108 static int 00109 pcap_read_win32_npf(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 00110 { 00111 int cc; 00112 int n = 0; 00113 register u_char *bp, *ep; 00114 00115 #ifdef HAVE_REMOTE 00116 static int samp_npkt; // parameter needed for sampling, with '1 out of N' method has been requested 00117 static struct timeval samp_time; // parameter needed for sampling, with '1 every N ms' method has been requested 00118 #endif /* HAVE_REMOTE */ 00119 00120 cc = p->cc; 00121 if (p->cc == 0) { 00122 /* 00123 * Has "pcap_breakloop()" been called? 00124 */ 00125 if (p->break_loop) { 00126 /* 00127 * Yes - clear the flag that indicates that it 00128 * has, and return -2 to indicate that we were 00129 * told to break out of the loop. 00130 */ 00131 p->break_loop = 0; 00132 return (-2); 00133 } 00134 00135 /* capture the packets */ 00136 if(PacketReceivePacket(p->adapter,p->Packet,TRUE)==FALSE){ 00137 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed"); 00138 return (-1); 00139 } 00140 00141 cc = p->Packet->ulBytesReceived; 00142 00143 bp = p->Packet->Buffer; 00144 } 00145 else 00146 bp = p->bp; 00147 00148 /* 00149 * Loop through each packet. 00150 */ 00151 #define bhp ((struct bpf_hdr *)bp) 00152 ep = bp + cc; 00153 while (1) { 00154 register int caplen, hdrlen; 00155 00156 /* 00157 * Has "pcap_breakloop()" been called? 00158 * If so, return immediately - if we haven't read any 00159 * packets, clear the flag and return -2 to indicate 00160 * that we were told to break out of the loop, otherwise 00161 * leave the flag set, so that the *next* call will break 00162 * out of the loop without having read any packets, and 00163 * return the number of packets we've processed so far. 00164 */ 00165 if (p->break_loop) { 00166 if (n == 0) { 00167 p->break_loop = 0; 00168 return (-2); 00169 } else { 00170 p->bp = bp; 00171 p->cc = ep - bp; 00172 return (n); 00173 } 00174 } 00175 if (bp >= ep) 00176 break; 00177 00178 caplen = bhp->bh_caplen; 00179 hdrlen = bhp->bh_hdrlen; 00180 00181 #ifdef HAVE_REMOTE 00182 if (p->rmt_samp.method == PCAP_SAMP_1_EVERY_N) 00183 { 00184 samp_npkt= (samp_npkt + 1) % p->rmt_samp.value; 00185 00186 // Discard all packets that are not '1 out of N' 00187 if (samp_npkt != 0) 00188 { 00189 bp += BPF_WORDALIGN(caplen + hdrlen); 00190 continue; 00191 } 00192 } 00193 00194 if (p->rmt_samp.method == PCAP_SAMP_FIRST_AFTER_N_MS) 00195 { 00196 struct pcap_pkthdr *pkt_header= (struct pcap_pkthdr*) bp; 00197 00198 // Check if the timestamp of the arrived packet is smaller than our target time 00199 if ( (pkt_header->ts.tv_sec < samp_time.tv_sec) || 00200 ( (pkt_header->ts.tv_sec == samp_time.tv_sec) && (pkt_header->ts.tv_usec < samp_time.tv_usec) ) ) 00201 { 00202 bp += BPF_WORDALIGN(caplen + hdrlen); 00203 continue; 00204 } 00205 00206 // The arrived packet is suitable for being sent to the remote host 00207 // So, let's update the target time 00208 samp_time.tv_usec= pkt_header->ts.tv_usec + p->rmt_samp.value * 1000; 00209 if (samp_time.tv_usec > 1000000) 00210 { 00211 samp_time.tv_sec= pkt_header->ts.tv_sec + samp_time.tv_usec / 1000000; 00212 samp_time.tv_usec= samp_time.tv_usec % 1000000; 00213 } 00214 } 00215 #endif /* HAVE_REMOTE */ 00216 00217 /* 00218 * XXX A bpf_hdr matches a pcap_pkthdr. 00219 */ 00220 (*callback)(user, (struct pcap_pkthdr*)bp, bp + hdrlen); 00221 bp += BPF_WORDALIGN(caplen + hdrlen); 00222 if (++n >= cnt && cnt > 0) { 00223 p->bp = bp; 00224 p->cc = ep - bp; 00225 return (n); 00226 } 00227 } 00228 #undef bhp 00229 p->cc = 0; 00230 return (n); 00231 } 00232 00233 #ifdef HAVE_DAG_API 00234 static int 00235 pcap_read_win32_dag(pcap_t *p, int cnt, pcap_handler callback, u_char *user) 00236 { 00237 u_char *dp = NULL; 00238 int packet_len = 0, caplen = 0; 00239 struct pcap_pkthdr pcap_header; 00240 u_char *endofbuf; 00241 int n = 0; 00242 dag_record_t *header; 00243 unsigned erf_record_len; 00244 ULONGLONG ts; 00245 int cc; 00246 unsigned swt; 00247 unsigned dfp = p->adapter->DagFastProcess; 00248 00249 cc = p->cc; 00250 if (cc == 0) /* Get new packets only if we have processed all the ones of the previous read */ 00251 { 00252 /* Get new packets from the network */ 00253 if(PacketReceivePacket(p->adapter, p->Packet, TRUE)==FALSE){ 00254 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read error: PacketReceivePacket failed"); 00255 return (-1); 00256 } 00257 00258 cc = p->Packet->ulBytesReceived; 00259 if(cc == 0) 00260 /* The timeout has expired but we no packets arrived */ 00261 return 0; 00262 header = (dag_record_t*)p->adapter->DagBuffer; 00263 } 00264 else 00265 header = (dag_record_t*)p->bp; 00266 00267 endofbuf = (char*)header + cc; 00268 00269 /* 00270 * Cycle through the packets 00271 */ 00272 do 00273 { 00274 erf_record_len = SWAPS(header->rlen); 00275 if((char*)header + erf_record_len > endofbuf) 00276 break; 00277 00278 /* Increase the number of captured packets */ 00279 p->md.stat.ps_recv++; 00280 00281 /* Find the beginning of the packet */ 00282 dp = ((u_char *)header) + dag_record_size; 00283 00284 /* Determine actual packet len */ 00285 switch(header->type) 00286 { 00287 case TYPE_ATM: 00288 packet_len = ATM_SNAPLEN; 00289 caplen = ATM_SNAPLEN; 00290 dp += 4; 00291 00292 break; 00293 00294 case TYPE_ETH: 00295 swt = SWAPS(header->wlen); 00296 packet_len = swt - (p->md.dag_fcs_bits); 00297 caplen = erf_record_len - dag_record_size - 2; 00298 if (caplen > packet_len) 00299 { 00300 caplen = packet_len; 00301 } 00302 dp += 2; 00303 00304 break; 00305 00306 case TYPE_HDLC_POS: 00307 swt = SWAPS(header->wlen); 00308 packet_len = swt - (p->md.dag_fcs_bits); 00309 caplen = erf_record_len - dag_record_size; 00310 if (caplen > packet_len) 00311 { 00312 caplen = packet_len; 00313 } 00314 00315 break; 00316 } 00317 00318 if(caplen > p->snapshot) 00319 caplen = p->snapshot; 00320 00321 /* 00322 * Has "pcap_breakloop()" been called? 00323 * If so, return immediately - if we haven't read any 00324 * packets, clear the flag and return -2 to indicate 00325 * that we were told to break out of the loop, otherwise 00326 * leave the flag set, so that the *next* call will break 00327 * out of the loop without having read any packets, and 00328 * return the number of packets we've processed so far. 00329 */ 00330 if (p->break_loop) 00331 { 00332 if (n == 0) 00333 { 00334 p->break_loop = 0; 00335 return (-2); 00336 } 00337 else 00338 { 00339 p->bp = (char*)header; 00340 p->cc = endofbuf - (char*)header; 00341 return (n); 00342 } 00343 } 00344 00345 if(!dfp) 00346 { 00347 /* convert between timestamp formats */ 00348 ts = header->ts; 00349 pcap_header.ts.tv_sec = (int)(ts >> 32); 00350 ts = (ts & 0xffffffffi64) * 1000000; 00351 ts += 0x80000000; /* rounding */ 00352 pcap_header.ts.tv_usec = (int)(ts >> 32); 00353 if (pcap_header.ts.tv_usec >= 1000000) { 00354 pcap_header.ts.tv_usec -= 1000000; 00355 pcap_header.ts.tv_sec++; 00356 } 00357 } 00358 00359 /* No underlaying filtering system. We need to filter on our own */ 00360 if (p->fcode.bf_insns) 00361 { 00362 if (bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen) == 0) 00363 { 00364 /* Move to next packet */ 00365 header = (dag_record_t*)((char*)header + erf_record_len); 00366 continue; 00367 } 00368 } 00369 00370 /* Fill the header for the user suppplied callback function */ 00371 pcap_header.caplen = caplen; 00372 pcap_header.len = packet_len; 00373 00374 /* Call the callback function */ 00375 (*callback)(user, &pcap_header, dp); 00376 00377 /* Move to next packet */ 00378 header = (dag_record_t*)((char*)header + erf_record_len); 00379 00380 /* Stop if the number of packets requested by user has been reached*/ 00381 if (++n >= cnt && cnt > 0) 00382 { 00383 p->bp = (char*)header; 00384 p->cc = endofbuf - (char*)header; 00385 return (n); 00386 } 00387 } 00388 while((u_char*)header < endofbuf); 00389 00390 return 1; 00391 } 00392 #endif /* HAVE_DAG_API */ 00393 00394 static void 00395 pcap_close_win32(pcap_t *p) 00396 { 00397 if (p->buffer != NULL) 00398 free(p->buffer); 00399 if (p->adapter != NULL) { 00400 PacketCloseAdapter(p->adapter); 00401 p->adapter = NULL; 00402 } 00403 } 00404 00405 pcap_t * 00406 pcap_open_live(const char *device, int snaplen, int promisc, int to_ms, 00407 char *ebuf) 00408 { 00409 register pcap_t *p; 00410 NetType type; 00411 00412 #ifdef HAVE_REMOTE 00413 char host[PCAP_BUF_SIZE + 1]; 00414 char port[PCAP_BUF_SIZE + 1]; 00415 char name[PCAP_BUF_SIZE + 1]; 00416 int srctype; 00417 00418 /* 00419 Retrofit; we have to make older applications compatible with the remote capture 00420 So, we're calling the pcap_open_remote() from here, that is a very dirty thing. 00421 Obviously, we cannot exploit all the new features; for instance, we cannot 00422 send authentication, we cannot use a UDP data connection, and so on. 00423 */ 00424 if (pcap_parsesrcstr(device, &srctype, host, port, name, ebuf) ) 00425 return NULL; 00426 00427 if (srctype == PCAP_SRC_IFREMOTE) 00428 { 00429 p= pcap_opensource_remote(device, NULL, ebuf); 00430 00431 if (p == NULL) 00432 return NULL; 00433 00434 p->snapshot= snaplen; 00435 p->timeout= to_ms; 00436 p->rmt_flags= (promisc) ? PCAP_OPENFLAG_PROMISCUOUS : 0; 00437 00438 return p; 00439 } 00440 #endif 00441 00442 /* Init WinSock */ 00443 wsockinit(); 00444 00445 p = (pcap_t *)malloc(sizeof(*p)); 00446 if (p == NULL) 00447 { 00448 snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); 00449 return (NULL); 00450 } 00451 memset(p, 0, sizeof(*p)); 00452 p->adapter=NULL; 00453 00454 p->adapter = PacketOpenAdapter((char*)device); 00455 00456 if (p->adapter == NULL) 00457 { 00458 /* Adapter detected but we are not able to open it. Return failure. */ 00459 snprintf(ebuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", pcap_win32strerror()); 00460 return NULL; 00461 } 00462 00463 /*get network type*/ 00464 if(PacketGetNetType (p->adapter,&type) == FALSE) 00465 { 00466 snprintf(ebuf, PCAP_ERRBUF_SIZE, "Cannot determine the network type: %s", pcap_win32strerror()); 00467 goto bad; 00468 } 00469 00470 /*Set the linktype*/ 00471 switch (type.LinkType) 00472 { 00473 case NdisMediumWan: 00474 p->linktype = DLT_EN10MB; 00475 break; 00476 00477 case NdisMedium802_3: 00478 p->linktype = DLT_EN10MB; 00479 /* 00480 * This is (presumably) a real Ethernet capture; give it a 00481 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so 00482 * that an application can let you choose it, in case you're 00483 * capturing DOCSIS traffic that a Cisco Cable Modem 00484 * Termination System is putting out onto an Ethernet (it 00485 * doesn't put an Ethernet header onto the wire, it puts raw 00486 * DOCSIS frames out on the wire inside the low-level 00487 * Ethernet framing). 00488 */ 00489 p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2); 00490 /* 00491 * If that fails, just leave the list empty. 00492 */ 00493 if (p->dlt_list != NULL) { 00494 p->dlt_list[0] = DLT_EN10MB; 00495 p->dlt_list[1] = DLT_DOCSIS; 00496 p->dlt_count = 2; 00497 } 00498 break; 00499 00500 case NdisMediumFddi: 00501 p->linktype = DLT_FDDI; 00502 break; 00503 00504 case NdisMedium802_5: 00505 p->linktype = DLT_IEEE802; 00506 break; 00507 00508 case NdisMediumArcnetRaw: 00509 p->linktype = DLT_ARCNET; 00510 break; 00511 00512 case NdisMediumArcnet878_2: 00513 p->linktype = DLT_ARCNET; 00514 break; 00515 00516 case NdisMediumAtm: 00517 p->linktype = DLT_ATM_RFC1483; 00518 break; 00519 00520 case NdisMediumCHDLC: 00521 p->linktype = DLT_CHDLC; 00522 break; 00523 00524 case NdisMediumPPPSerial: 00525 p->linktype = DLT_PPP_SERIAL; 00526 break; 00527 00528 case NdisMediumNull: 00529 p->linktype = DLT_NULL; 00530 break; 00531 00532 default: 00533 p->linktype = DLT_EN10MB; /*an unknown adapter is assumed to be ethernet*/ 00534 break; 00535 } 00536 00537 /* Set promisquous mode */ 00538 if (promisc) PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_PROMISCUOUS); 00539 else PacketSetHwFilter(p->adapter,NDIS_PACKET_TYPE_ALL_LOCAL); 00540 00541 /* Set the buffer size */ 00542 p->bufsize = PcapBufSize; 00543 00544 /* allocate Packet structure used during the capture */ 00545 if((p->Packet = PacketAllocatePacket())==NULL) 00546 { 00547 snprintf(ebuf, PCAP_ERRBUF_SIZE, "failed to allocate the PACKET structure"); 00548 goto bad; 00549 } 00550 00551 if(!(p->adapter->Flags & INFO_FLAG_DAG_CARD)) 00552 { 00553 /* 00554 * Traditional Adapter 00555 */ 00556 00557 p->buffer = (u_char *)malloc(PcapBufSize); 00558 if (p->buffer == NULL) 00559 { 00560 snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s", pcap_strerror(errno)); 00561 goto bad; 00562 } 00563 00564 PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize); 00565 00566 p->snapshot = snaplen; 00567 00568 /* allocate the standard buffer in the driver */ 00569 if(PacketSetBuff( p->adapter, SIZE_BUF)==FALSE) 00570 { 00571 snprintf(ebuf, PCAP_ERRBUF_SIZE,"driver error: not enough memory to allocate the kernel buffer\n"); 00572 goto bad; 00573 } 00574 00575 /* tell the driver to copy the buffer only if it contains at least 16K */ 00576 if(PacketSetMinToCopy(p->adapter,16000)==FALSE) 00577 { 00578 snprintf(ebuf, PCAP_ERRBUF_SIZE,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror()); 00579 goto bad; 00580 } 00581 } 00582 else 00583 #ifdef HAVE_DAG_API 00584 { 00585 /* 00586 * Dag Card 00587 */ 00588 LONG status; 00589 HKEY dagkey; 00590 DWORD lptype; 00591 DWORD lpcbdata; 00592 int postype = 0; 00593 char keyname[512]; 00594 00595 snprintf(keyname, sizeof(keyname), "%s\\CardParams\\%s", 00596 "SYSTEM\\CurrentControlSet\\Services\\DAG", 00597 strstr(_strlwr((char*)device), "dag")); 00598 do 00599 { 00600 status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, keyname, 0, KEY_READ, &dagkey); 00601 if(status != ERROR_SUCCESS) 00602 break; 00603 00604 status = RegQueryValueEx(dagkey, 00605 "PosType", 00606 NULL, 00607 &lptype, 00608 (char*)&postype, 00609 &lpcbdata); 00610 00611 if(status != ERROR_SUCCESS) 00612 { 00613 postype = 0; 00614 } 00615 00616 RegCloseKey(dagkey); 00617 } 00618 while(FALSE); 00619 00620 00621 p->snapshot = PacketSetSnapLen(p->adapter, snaplen); 00622 00623 /* Set the length of the FCS associated to any packet. This value 00624 * will be subtracted to the packet length */ 00625 p->md.dag_fcs_bits = p->adapter->DagFcsLen; 00626 } 00627 #else 00628 goto bad; 00629 #endif /* HAVE_DAG_API */ 00630 00631 PacketSetReadTimeout(p->adapter, to_ms); 00632 00633 #ifdef HAVE_DAG_API 00634 if(p->adapter->Flags & INFO_FLAG_DAG_CARD) 00635 { 00636 /* install dag specific handlers for read and setfilter */ 00637 p->read_op = pcap_read_win32_dag; 00638 p->setfilter_op = pcap_setfilter_win32_dag; 00639 } 00640 else 00641 { 00642 #endif /* HAVE_DAG_API */ 00643 /* install traditional npf handlers for read and setfilter */ 00644 p->read_op = pcap_read_win32_npf; 00645 p->setfilter_op = pcap_setfilter_win32_npf; 00646 #ifdef HAVE_DAG_API 00647 } 00648 #endif /* HAVE_DAG_API */ 00649 p->set_datalink_op = NULL; /* can't change data link type */ 00650 p->getnonblock_op = pcap_getnonblock_win32; 00651 p->setnonblock_op = pcap_setnonblock_win32; 00652 p->stats_op = pcap_stats_win32; 00653 p->close_op = pcap_close_win32; 00654 00655 return (p); 00656 bad: 00657 if (p->adapter) 00658 PacketCloseAdapter(p->adapter); 00659 if (p->buffer != NULL) 00660 free(p->buffer); 00661 if(p->Packet) 00662 PacketFreePacket(p->Packet); 00663 /* 00664 * Get rid of any link-layer type list we allocated. 00665 */ 00666 if (p->dlt_list != NULL) 00667 free(p->dlt_list); 00668 free(p); 00669 return (NULL); 00670 } 00671 00672 00673 static int 00674 pcap_setfilter_win32_npf(pcap_t *p, struct bpf_program *fp) 00675 { 00676 if(PacketSetBpf(p->adapter,fp)==FALSE){ 00677 /* kernel filter not installed. */ 00678 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Driver error: cannot set bpf filter: %s", pcap_win32strerror()); 00679 return (-1); 00680 } 00681 return (0); 00682 } 00683 00684 /* 00685 * We filter at user level, since the kernel driver does't process the packets 00686 */ 00687 static int 00688 pcap_setfilter_win32_dag(pcap_t *p, struct bpf_program *fp) { 00689 00690 if(!fp) 00691 { 00692 strncpy(p->errbuf, "setfilter: No filter specified", sizeof(p->errbuf)); 00693 return -1; 00694 } 00695 00696 /* Install a user level filter */ 00697 if (install_bpf_program(p, fp) < 0) 00698 { 00699 snprintf(p->errbuf, sizeof(p->errbuf), 00700 "setfilter, unable to install the filter: %s", pcap_strerror(errno)); 00701 return -1; 00702 } 00703 00704 p->md.use_bpf = 0; 00705 00706 return (0); 00707 } 00708 00709 static int 00710 pcap_getnonblock_win32(pcap_t *p, char *errbuf) 00711 { 00712 /* 00713 * XXX - if there were a PacketGetReadTimeout() call, we 00714 * would use it, and return 1 if the timeout is -1 00715 * and 0 otherwise. 00716 */ 00717 return (p->nonblock); 00718 } 00719 00720 static int 00721 pcap_setnonblock_win32(pcap_t *p, int nonblock, char *errbuf) 00722 { 00723 int newtimeout; 00724 00725 if (nonblock) { 00726 /* 00727 * Set the read timeout to -1 for non-blocking mode. 00728 */ 00729 newtimeout = -1; 00730 } else { 00731 /* 00732 * Restore the timeout set when the device was opened. 00733 * (Note that this may be -1, in which case we're not 00734 * really leaving non-blocking mode.) 00735 */ 00736 newtimeout = p->timeout; 00737 } 00738 if (!PacketSetReadTimeout(p->adapter, newtimeout)) { 00739 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, 00740 "PacketSetReadTimeout: %s", pcap_win32strerror()); 00741 return (-1); 00742 } 00743 p->nonblock = (newtimeout == -1); 00744 return (0); 00745 } 00746 00747 /* Set the driver working mode */ 00748 int 00749 pcap_setmode(pcap_t *p, int mode){ 00750 00751 if (p->adapter==NULL) 00752 { 00753 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "impossible to set mode while reading from a file"); 00754 return -1; 00755 } 00756 00757 if(PacketSetMode(p->adapter,mode)==FALSE) 00758 { 00759 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: working mode not recognized"); 00760 return -1; 00761 } 00762 00763 return 0; 00764 } 00765 00766 /* Send a packet to the network */ 00767 int 00768 pcap_sendpacket(pcap_t *p, u_char *buf, int size){ 00769 LPPACKET PacketToSend; 00770 00771 if (p->adapter==NULL) 00772 { 00773 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Writing a packet is allowed only on a physical adapter"); 00774 return -1; 00775 } 00776 00777 PacketToSend=PacketAllocatePacket(); 00778 PacketInitPacket(PacketToSend,buf,size); 00779 if(PacketSendPacket(p->adapter,PacketToSend,TRUE) == FALSE){ 00780 PacketFreePacket(PacketToSend); 00781 return -1; 00782 } 00783 00784 PacketFreePacket(PacketToSend); 00785 return 0; 00786 } 00787 00788 /* Set the dimension of the kernel-level capture buffer */ 00789 int 00790 pcap_setbuff(pcap_t *p, int dim) 00791 { 00792 #ifdef HAVE_REMOTE 00793 if (p->rmt_clientside) 00794 { 00795 /* Currently, this is a bug: the capture buffer cannot be set with remote capture */ 00796 return 0; 00797 } 00798 #endif /* HAVE_REMOTE */ 00799 00800 if (p->adapter==NULL) 00801 { 00802 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "The kernel buffer size cannot be set while reading from a file"); 00803 return -1; 00804 } 00805 00806 if(PacketSetBuff(p->adapter,dim)==FALSE) 00807 { 00808 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: not enough memory to allocate the kernel buffer"); 00809 return -1; 00810 } 00811 return 0; 00812 } 00813 00814 /*set the minimum amount of data that will release a read call*/ 00815 int 00816 pcap_setmintocopy(pcap_t *p, int size) 00817 { 00818 if (p->adapter==NULL) 00819 { 00820 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Impossible to set the mintocopy parameter on an offline capture"); 00821 return -1; 00822 } 00823 00824 if(PacketSetMinToCopy(p->adapter, size)==FALSE) 00825 { 00826 snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "driver error: unable to set the requested mintocopy size"); 00827 return -1; 00828 } 00829 return 0; 00830 }
documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.