Main Page   Modules   Data Structures   File List   Data Fields   Globals   Related Pages  

Pcap-win32.c

Go to the documentation of this file.
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.