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 - 2002
    00003  *  Politecnico di Torino.  All rights reserved.
    00004  *
    00005  * Redistribution and use in source and binary forms, with or without
    00006  * modification, are permitted provided that: (1) source code distributions
    00007  * retain the above copyright notice and this paragraph in its entirety, (2)
    00008  * distributions including binary code include the above copyright notice and
    00009  * this paragraph in its entirety in the documentation or other materials
    00010  * provided with the distribution, and (3) all advertising materials mentioning
    00011  * features or use of this software display the following acknowledgement:
    00012  * ``This product includes software developed by the Politecnico
    00013  * di Torino, and its contributors.'' Neither the name of
    00014  * the University nor the names of its contributors may be used to endorse
    00015  * or promote products derived from this software without specific prior
    00016  * written permission.
    00017  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
    00018  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
    00019  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    00020  */
    00021
    00022 #include "pcap-int.h"
    00023 #include <packet32.h>
    00024
    00025 #ifdef REMOTE
    00026 #include <pcap-remote.h>
    00027 #endif
    00028
    00029
    00030 HANDLE
    00031 pcap_getevent(pcap_t *p)
    00032 {
    00033     if (p->adapter==NULL)
    00034     {
    00035         sprintf(p->errbuf, "The read event cannot be retrieved while reading from a file");
    00036         return NULL;
    00037     }
    00038
    00039     return PacketGetReadEvent(p->adapter);
    00040 }
    00041
    00042
    00043
    00044 /*
    00045 This way is definitely safer than passing the pcap_stat * from the userland. In fact, there could
    00046 happen than the user allocates a variable which is not big enough for the new structure, and the
    00047 library will write in a zone which is not allocated to this variable.
    00048 In this way, we're pretty sure we are writing on memory allocated to this variable.
    00049 */
    00050 struct pcap_stat *
    00051 pcap_stats_ex(pcap_t *p)
    00052 {
    00053 #ifdef REMOTE
    00054     if (p->rmt_clientside)
    00055     {
    00056         /* We are on an remote capture */
    00057         return pcap_stats_ex_remote(p);
    00058     }
    00059 #endif
    00060     if(PacketGetStatsEx(p->adapter, (struct bpf_stat*) (&p->md.stat) ) != TRUE){
    00061         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "PacketGetStatsEx error: %s", pcap_win32strerror());
    00062         return NULL;
    00063     }
    00064     return (&p->md.stat);
    00065 }
    00066
    00067
    00068 pcap_send_queue*
    00069 pcap_sendqueue_alloc(u_int memsize)
    00070 {
    00071
    00072     pcap_send_queue *tqueue;
    00073
    00074     /* Allocate the queue */
    00075     tqueue = (pcap_send_queue*)malloc(sizeof(pcap_send_queue));
    00076     if(tqueue == NULL){
    00077         return NULL;
    00078     }
    00079
    00080     /* Allocate the buffer */
    00081     tqueue->buffer = (char*)malloc(memsize);
    00082     if(tqueue->buffer == NULL){
    00083         free(tqueue);
    00084         return NULL;
    00085     }
    00086
    00087     tqueue->maxlen = memsize;
    00088     tqueue->len = 0;
    00089
    00090     return tqueue;
    00091 }
    00092
    00093 void
    00094 pcap_sendqueue_destroy(pcap_send_queue* queue)
    00095 {
    00096     free(queue->buffer);
    00097     free(queue);
    00098 }
    00099
    00100 int
    00101 pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
    00102 {
    00103
    00104     if(queue->len + sizeof(struct pcap_pkthdr) + pkt_header->caplen > queue->maxlen){
    00105         return -1;
    00106     }
    00107
    00108     /* Copy the pcap_pkthdr header*/
    00109     memcpy(queue->buffer + queue->len, pkt_header, sizeof(struct pcap_pkthdr));
    00110     queue->len += sizeof(struct pcap_pkthdr);
    00111
    00112     /* copy the packet */
    00113     memcpy(queue->buffer + queue->len, pkt_data, pkt_header->caplen);
    00114     queue->len += pkt_header->caplen;
    00115
    00116     return 0;
    00117 }
    00118
    00119 u_int
    00120 pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync){
    00121
    00122     u_int res;
    00123     DWORD error;
    00124     int errlen;
    00125
    00126     if (p->adapter==NULL)
    00127     {
    00128         sprintf(p->errbuf, "Cannot transmit a queue to an offline capture");
    00129         return -1;
    00130     }
    00131
    00132     res = PacketSendPackets(p->adapter,
    00133         queue->buffer,
    00134         queue->len,
    00135         (BOOLEAN)sync);
    00136
    00137     if(res != queue->len){
    00138         error = GetLastError();
    00139         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,error,0,p->errbuf,PCAP_ERRBUF_SIZE,NULL);
    00140         /*
    00141         * "FormatMessage()" "helpfully" sticks CR/LF at the end of
    00142         * the message.  Get rid of it.
    00143         */
    00144         errlen = strlen(p->errbuf);
    00145         if (errlen >= 2) {
    00146             p->errbuf[errlen - 1] = '\0';
    00147             p->errbuf[errlen - 2] = '\0';
    00148         }
    00149         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", p->errbuf);
    00150     }
    00151
    00152     return res;
    00153 }
    00154
    00155
    00156 #ifdef WE_HAVE_TO_DELETE_IT_ASAP
    00157 int
    00158 pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data)
    00159 {
    00160     /* Check the capture type */
    00161
    00162 #ifdef REMOTE
    00163     if (p->rmt_clientside)
    00164     {
    00165         /* We are on an remote capture */
    00166         if (!p->rmt_capstarted)
    00167         {
    00168             // if the capture has not started yet, please start it
    00169             if (pcap_startcapture_remote(p) )
    00170                 return -1;
    00171             p->rmt_capstarted= 1;
    00172         }
    00173         return pcap_next_ex_remote(p, pkt_header, pkt_data);
    00174     }
    00175 #endif
    00176
    00177     if (p->adapter!=NULL)
    00178     {
    00179         /* We are on a live capture */
    00180         int cc;
    00181         int n = 0;
    00182         register u_char *bp, *ep;
    00183
    00184         cc = p->cc;
    00185         if (p->cc == 0)
    00186         {
    00187             /* capture the packets */
    00188             if(PacketReceivePacket(p->adapter, p->Packet, TRUE) == FALSE)
    00189             {
    00190                 sprintf(p->errbuf, "read error: PacketReceivePacket failed");
    00191                 return (-1);
    00192             }
    00193
    00194             cc = p->Packet->ulBytesReceived;
    00195
    00196             bp = p->Packet->Buffer;
    00197         }
    00198         else
    00199             bp = p->bp;
    00200
    00201         /*
    00202          * Loop through each packet.
    00203          */
    00204         ep = bp + cc;
    00205         if (bp < ep)
    00206         {
    00207             register int caplen, hdrlen;
    00208             caplen = ((struct bpf_hdr *)bp)->bh_caplen;
    00209             hdrlen = ((struct bpf_hdr *)bp)->bh_hdrlen;
    00210
    00211             /*
    00212              * XXX A bpf_hdr matches a pcap_pkthdr.
    00213              */
    00214             *pkt_header = (struct pcap_pkthdr*)bp;
    00215             *pkt_data = bp + hdrlen;
    00216             bp += BPF_WORDALIGN(caplen + hdrlen);
    00217
    00218             p->bp = bp;
    00219             p->cc = ep - bp;
    00220             return (1);
    00221         }
    00222         else{
    00223             p->cc = 0;
    00224             return (0);
    00225         }
    00226     }
    00227     else
    00228     {
    00229         /* We are on an offline capture */
    00230         struct bpf_insn *fcode = p->fcode.bf_insns;
    00231         int status;
    00232         int n = 0;
    00233
    00234         struct pcap_pkthdr *h=(struct pcap_pkthdr*)(p->buffer+p->bufsize-sizeof(struct pcap_pkthdr));
    00235
    00236         while (1)
    00237         {
    00238             status = sf_next_packet(p, h, p->buffer, p->bufsize);
    00239             if (status==1)
    00240                 /* EOF */
    00241                 return (-2);
    00242             if (status==-1)
    00243                 /* Error */
    00244                 return (-1);
    00245
    00246             if (fcode == NULL ||
    00247                 bpf_filter(fcode, p->buffer, h->len, h->caplen))
    00248             {
    00249                 *pkt_header = h;
    00250                 *pkt_data = p->buffer;
    00251                 return (1);
    00252             }
    00253
    00254         }
    00255     }
    00256 }
    00257 #endif
    00258
    00259
    00260 int
    00261 pcap_setuserbuffer(pcap_t *p, int size)
    00262
    00263 {
    00264     unsigned char *new_buff;
    00265
    00266     if (!p->adapter) {
    00267         sprintf(p->errbuf,"Impossible to set user buffer while reading from a file");
    00268         return -1;
    00269     }
    00270
    00271     if (size<=0) {
    00272         /* Bogus parameter */
    00273         sprintf(p->errbuf,"Error: invalid size %d",size);
    00274         return -1;
    00275     }
    00276
    00277     /* Allocate the buffer */
    00278     new_buff=(unsigned char*)malloc(sizeof(char)*size);
    00279
    00280     if (!new_buff) {
    00281         sprintf(p->errbuf,"Error: not enough memory");
    00282         return -1;
    00283     }
    00284
    00285     free(p->buffer);
    00286
    00287     p->buffer=new_buff;
    00288     p->bufsize=size;
    00289
    00290     /* Associate the buffer with the capture packet */
    00291     PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
    00292
    00293     return 0;
    00294
    00295 }
    00296
    00297 int
    00298 pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks){
    00299
    00300     BOOLEAN res;
    00301
    00302     if (p->adapter==NULL)
    00303     {
    00304         sprintf(p->errbuf, "live dump needs a physical interface");
    00305         return -1;
    00306     }
    00307
    00308     /* Set the packet driver in dump mode */
    00309     res = PacketSetMode(p->adapter, PACKET_MODE_DUMP);
    00310     if(res == FALSE){
    00311         sprintf(p->errbuf, "Error setting dump mode");
    00312         return -1;
    00313     }
    00314
    00315     /* Set the name of the dump file */
    00316     res = PacketSetDumpName(p->adapter, filename, strlen(filename));
    00317     if(res == FALSE){
    00318         sprintf(p->errbuf, "Error setting kernel dump file name");
    00319         return -1;
    00320     }
    00321
    00322     /* Set the limits of the dump file */
    00323     res = PacketSetDumpLimits(p->adapter, maxsize, maxpacks);
    00324
    00325     return 0;
    00326 }
    00327
    00328 int
    00329 pcap_live_dump_ended(pcap_t *p, int sync){
    00330
    00331     if (p->adapter == NULL)
    00332     {
    00333         sprintf(p->errbuf, "wrong interface type. A physical interface is needed");
    00334         return -1;
    00335     }
    00336
    00337     return PacketIsDumpEnded(p->adapter, (BOOLEAN)sync);
    00338
    00339 }

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