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

# Win32-Extensions.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 #include "pcap-int.h"
    00034 #include <packet32.h>
    00035
    00036 #ifdef HAVE_REMOTE
    00037 #include <pcap-remote.h>
    00038 #endif
    00039
    00040
    00041 HANDLE
    00042 pcap_getevent(pcap_t *p)
    00043 {
    00044     if (p->adapter==NULL)
    00045     {
    00046         sprintf(p->errbuf, "The read event cannot be retrieved while reading from a file");
    00047         return NULL;
    00048     }
    00049
    00050     return PacketGetReadEvent(p->adapter);
    00051 }
    00052
    00053
    00054
    00055 /*
    00056 This way is definitely safer than passing the pcap_stat * from the userland. In fact, there could
    00057 happen than the user allocates a variable which is not big enough for the new structure, and the
    00058 library will write in a zone which is not allocated to this variable.
    00059 In this way, we're pretty sure we are writing on memory allocated to this variable.
    00060 */
    00061 struct pcap_stat *
    00062 pcap_stats_ex(pcap_t *p, int *pcap_stat_size)
    00063 {
    00064     *pcap_stat_size= sizeof (struct pcap_stat);
    00065
    00066 #ifdef HAVE_REMOTE
    00067     if (p->rmt_clientside)
    00068     {
    00069         /* We are on an remote capture */
    00070         return pcap_stats_ex_remote(p);
    00071     }
    00072 #endif
    00073     if(PacketGetStatsEx(p->adapter, (struct bpf_stat*) (&p->md.stat) ) != TRUE){
    00074         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStatsEx error: %s", pcap_win32strerror());
    00075         return NULL;
    00076     }
    00077     return (&p->md.stat);
    00078 }
    00079
    00080
    00081 pcap_send_queue*
    00082 pcap_sendqueue_alloc(u_int memsize)
    00083 {
    00084
    00085     pcap_send_queue *tqueue;
    00086
    00087     /* Allocate the queue */
    00088     tqueue = (pcap_send_queue*)malloc(sizeof(pcap_send_queue));
    00089     if(tqueue == NULL){
    00090         return NULL;
    00091     }
    00092
    00093     /* Allocate the buffer */
    00094     tqueue->buffer = (char*)malloc(memsize);
    00095     if(tqueue->buffer == NULL){
    00096         free(tqueue);
    00097         return NULL;
    00098     }
    00099
    00100     tqueue->maxlen = memsize;
    00101     tqueue->len = 0;
    00102
    00103     return tqueue;
    00104 }
    00105
    00106 void
    00107 pcap_sendqueue_destroy(pcap_send_queue* queue)
    00108 {
    00109     free(queue->buffer);
    00110     free(queue);
    00111 }
    00112
    00113 int
    00114 pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
    00115 {
    00116
    00117     if(queue->len + sizeof(struct pcap_pkthdr) + pkt_header->caplen > queue->maxlen){
    00118         return -1;
    00119     }
    00120
    00121     /* Copy the pcap_pkthdr header*/
    00122     memcpy(queue->buffer + queue->len, pkt_header, sizeof(struct pcap_pkthdr));
    00123     queue->len += sizeof(struct pcap_pkthdr);
    00124
    00125     /* copy the packet */
    00126     memcpy(queue->buffer + queue->len, pkt_data, pkt_header->caplen);
    00127     queue->len += pkt_header->caplen;
    00128
    00129     return 0;
    00130 }
    00131
    00132 u_int
    00133 pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync){
    00134
    00135     u_int res;
    00136     DWORD error;
    00137     int errlen;
    00138
    00139     if (p->adapter==NULL)
    00140     {
    00141         sprintf(p->errbuf, "Cannot transmit a queue to an offline capture");
    00142         return -1;
    00143     }
    00144
    00145     res = PacketSendPackets(p->adapter,
    00146         queue->buffer,
    00147         queue->len,
    00148         (BOOLEAN)sync);
    00149
    00150     if(res != queue->len){
    00151         error = GetLastError();
    00152         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,error,0,p->errbuf,PCAP_ERRBUF_SIZE,NULL);
    00153         /*
    00154         * "FormatMessage()" "helpfully" sticks CR/LF at the end of
    00155         * the message.  Get rid of it.
    00156         */
    00157         errlen = strlen(p->errbuf);
    00158         if (errlen >= 2) {
    00159             p->errbuf[errlen - 1] = '\0';
    00160             p->errbuf[errlen - 2] = '\0';
    00161         }
    00162         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", p->errbuf);
    00163     }
    00164
    00165     return res;
    00166 }
    00167
    00168
    00169 #ifdef WE_HAVE_TO_DELETE_IT_ASAP
    00170 int
    00171 pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data)
    00172 {
    00173     /* Check the capture type */
    00174
    00175 #ifdef HAVE_REMOTE
    00176     if (p->rmt_clientside)
    00177     {
    00178         /* We are on an remote capture */
    00179         if (!p->rmt_capstarted)
    00180         {
    00181             // if the capture has not started yet, please start it
    00182             if (pcap_startcapture_remote(p) )
    00183                 return -1;
    00184             p->rmt_capstarted= 1;
    00185         }
    00186         return pcap_next_ex_remote(p, pkt_header, pkt_data);
    00187     }
    00188 #endif
    00189
    00190     if (p->adapter!=NULL)
    00191     {
    00192         /* We are on a live capture */
    00193         int cc;
    00194         int n = 0;
    00195         register u_char *bp, *ep;
    00196
    00197         cc = p->cc;
    00198         if (p->cc == 0)
    00199         {
    00200             /* capture the packets */
    00201             if(PacketReceivePacket(p->adapter, p->Packet, TRUE) == FALSE)
    00202             {
    00203                 sprintf(p->errbuf, "read error: PacketReceivePacket failed");
    00204                 return (-1);
    00205             }
    00206
    00207             cc = p->Packet->ulBytesReceived;
    00208
    00209             bp = p->Packet->Buffer;
    00210         }
    00211         else
    00212             bp = p->bp;
    00213
    00214         /*
    00215          * Loop through each packet.
    00216          */
    00217         ep = bp + cc;
    00218         if (bp < ep)
    00219         {
    00220             register int caplen, hdrlen;
    00221             caplen = ((struct bpf_hdr *)bp)->bh_caplen;
    00222             hdrlen = ((struct bpf_hdr *)bp)->bh_hdrlen;
    00223
    00224             /*
    00225              * XXX A bpf_hdr matches a pcap_pkthdr.
    00226              */
    00227             *pkt_header = (struct pcap_pkthdr*)bp;
    00228             *pkt_data = bp + hdrlen;
    00229             bp += BPF_WORDALIGN(caplen + hdrlen);
    00230
    00231             p->bp = bp;
    00232             p->cc = ep - bp;
    00233             return (1);
    00234         }
    00235         else{
    00236             p->cc = 0;
    00237             return (0);
    00238         }
    00239     }
    00240     else
    00241     {
    00242         /* We are on an offline capture */
    00243         struct bpf_insn *fcode = p->fcode.bf_insns;
    00244         int status;
    00245         int n = 0;
    00246
    00247         struct pcap_pkthdr *h=(struct pcap_pkthdr*)(p->buffer+p->bufsize-sizeof(struct pcap_pkthdr));
    00248
    00249         while (1)
    00250         {
    00251             status = sf_next_packet(p, h, p->buffer, p->bufsize);
    00252             if (status==1)
    00253                 /* EOF */
    00254                 return (-2);
    00255             if (status==-1)
    00256                 /* Error */
    00257                 return (-1);
    00258
    00259             if (fcode == NULL ||
    00260                 bpf_filter(fcode, p->buffer, h->len, h->caplen))
    00261             {
    00262                 *pkt_header = h;
    00263                 *pkt_data = p->buffer;
    00264                 return (1);
    00265             }
    00266
    00267         }
    00268     }
    00269 }
    00270 #endif
    00271
    00272
    00273 int
    00274 pcap_setuserbuffer(pcap_t *p, int size)
    00275
    00276 {
    00277     unsigned char *new_buff;
    00278
    00279     if (!p->adapter) {
    00280         sprintf(p->errbuf,"Impossible to set user buffer while reading from a file");
    00281         return -1;
    00282     }
    00283
    00284     if (size<=0) {
    00285         /* Bogus parameter */
    00286         sprintf(p->errbuf,"Error: invalid size %d",size);
    00287         return -1;
    00288     }
    00289
    00290     /* Allocate the buffer */
    00291     new_buff=(unsigned char*)malloc(sizeof(char)*size);
    00292
    00293     if (!new_buff) {
    00294         sprintf(p->errbuf,"Error: not enough memory");
    00295         return -1;
    00296     }
    00297
    00298     free(p->buffer);
    00299
    00300     p->buffer=new_buff;
    00301     p->bufsize=size;
    00302
    00303     /* Associate the buffer with the capture packet */
    00304     PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
    00305
    00306     return 0;
    00307
    00308 }
    00309
    00310 int
    00311 pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks){
    00312
    00313     BOOLEAN res;
    00314
    00315     if (p->adapter==NULL)
    00316     {
    00317         sprintf(p->errbuf, "live dump needs a physical interface");
    00318         return -1;
    00319     }
    00320
    00321     /* Set the packet driver in dump mode */
    00322     res = PacketSetMode(p->adapter, PACKET_MODE_DUMP);
    00323     if(res == FALSE){
    00324         sprintf(p->errbuf, "Error setting dump mode");
    00325         return -1;
    00326     }
    00327
    00328     /* Set the name of the dump file */
    00329     res = PacketSetDumpName(p->adapter, filename, strlen(filename));
    00330     if(res == FALSE){
    00331         sprintf(p->errbuf, "Error setting kernel dump file name");
    00332         return -1;
    00333     }
    00334
    00335     /* Set the limits of the dump file */
    00336     res = PacketSetDumpLimits(p->adapter, maxsize, maxpacks);
    00337
    00338     return 0;
    00339 }
    00340
    00341 int
    00342 pcap_live_dump_ended(pcap_t *p, int sync){
    00343
    00344     if (p->adapter == NULL)
    00345     {
    00346         sprintf(p->errbuf, "wrong interface type. A physical interface is needed");
    00347         return -1;
    00348     }
    00349
    00350     return PacketIsDumpEnded(p->adapter, (BOOLEAN)sync);
    00351
    00352 }
    00353
    00354
    00355 int pcap_offline_filter(struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data)
    00356 {
    00357     struct bpf_insn *fcode = prog->bf_insns;
    00358
    00359     if (fcode != NULL)
    00360         return (bpf_filter(fcode, (u_char *) pkt_data, header->len, header->caplen));
    00361     else
    00362         return 0;
    00363 }

documentation. Copyright (c) 2002-2003 Politecnico di Torino. All rights reserved.