Main Page   Modules   Data Structures   File List   Data Fields   Globals  

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 HANDLE
00026 pcap_getevent(pcap_t *p)
00027 {
00028     if (p->adapter==NULL)
00029     {
00030         sprintf(p->errbuf, "The read event cannot be retrieved while reading from a file");
00031         return NULL;
00032     }   
00033 
00034     return PacketGetReadEvent(p->adapter);
00035 }
00036 
00037 pcap_send_queue* 
00038 pcap_sendqueue_alloc(u_int memsize)
00039 {
00040 
00041     pcap_send_queue *tqueue;
00042 
00043     /* Allocate the queue */
00044     tqueue = (pcap_send_queue*)malloc(sizeof(pcap_send_queue));
00045     if(tqueue == NULL){
00046         return NULL;
00047     }
00048 
00049     /* Allocate the buffer */
00050     tqueue->buffer = (char*)malloc(memsize);
00051     if(tqueue->buffer == NULL){
00052         free(tqueue);
00053         return NULL;
00054     }
00055 
00056     tqueue->maxlen = memsize;
00057     tqueue->len = 0;
00058 
00059     return tqueue;
00060 }
00061 
00062 void 
00063 pcap_sendqueue_destroy(pcap_send_queue* queue)
00064 {
00065     free(queue->buffer);
00066     free(queue);
00067 }
00068 
00069 int 
00070 pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data)
00071 {
00072 
00073     if(queue->len + sizeof(struct pcap_pkthdr) + pkt_header->caplen > queue->maxlen){
00074         return -1;
00075     }
00076 
00077     /* Copy the pcap_pkthdr header*/
00078     memcpy(queue->buffer + queue->len, pkt_header, sizeof(struct pcap_pkthdr));
00079     queue->len += sizeof(struct pcap_pkthdr);
00080 
00081     /* copy the packet */
00082     memcpy(queue->buffer + queue->len, pkt_data, pkt_header->caplen);
00083     queue->len += pkt_header->caplen;
00084 
00085     return 0;
00086 }
00087 
00088 u_int 
00089 pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync){
00090 
00091     u_int res;
00092     DWORD error;
00093     int errlen;
00094 
00095     if (p->adapter==NULL)
00096     {
00097         sprintf(p->errbuf, "Cannot transmit a queue to an offline capture");
00098         return -1;
00099     }   
00100 
00101     res = PacketSendPackets(p->adapter,
00102         queue->buffer,
00103         queue->len,
00104         (BOOLEAN)sync);
00105 
00106     if(res != queue->len){
00107         error = GetLastError();
00108         FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,error,0,p->errbuf,PCAP_ERRBUF_SIZE,NULL);
00109         /*
00110         * "FormatMessage()" "helpfully" sticks CR/LF at the end of
00111         * the message.  Get rid of it.
00112         */
00113         errlen = strlen(p->errbuf);
00114         if (errlen >= 2) {
00115             p->errbuf[errlen - 1] = '\0';
00116             p->errbuf[errlen - 2] = '\0';
00117         }
00118         snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Error opening adapter: %s", p->errbuf);
00119     }
00120 
00121     return res;
00122 }
00123 
00124 
00125 int 
00126 pcap_read_ex(pcap_t *p, struct pcap_pkthdr **pkt_header, u_char **pkt_data)
00127 {
00128     /* Check the capture type */
00129     if (p->adapter!=NULL)
00130     {
00131         /* We are on a live capture */
00132         int cc;
00133         int n = 0;
00134         register u_char *bp, *ep;
00135         
00136         cc = p->cc;
00137         if (p->cc == 0) 
00138         {
00139             /* capture the packets */
00140             if(PacketReceivePacket(p->adapter, p->Packet, TRUE) == FALSE)
00141             {
00142                 sprintf(p->errbuf, "read error: PacketReceivePacket failed");
00143                 return (-1);
00144             }
00145             
00146             cc = p->Packet->ulBytesReceived;
00147             
00148             bp = p->Packet->Buffer;
00149         } 
00150         else
00151             bp = p->bp;
00152         
00153         /*
00154          * Loop through each packet.
00155          */
00156         ep = bp + cc;
00157         if (bp < ep) 
00158         {
00159             register int caplen, hdrlen;
00160             caplen = ((struct bpf_hdr *)bp)->bh_caplen;
00161             hdrlen = ((struct bpf_hdr *)bp)->bh_hdrlen;
00162             
00163             /*
00164              * XXX A bpf_hdr matches a pcap_pkthdr.
00165              */
00166             *pkt_header = (struct pcap_pkthdr*)bp;
00167             *pkt_data = bp + hdrlen;
00168             bp += BPF_WORDALIGN(caplen + hdrlen);
00169             
00170             p->bp = bp;
00171             p->cc = ep - bp;
00172             return (1);
00173         }
00174         else{
00175             p->cc = 0;
00176             return (0);
00177         }
00178     }   
00179     else
00180     {
00181         /* We are on an offline capture */
00182         struct bpf_insn *fcode = p->fcode.bf_insns;
00183         int status;
00184         int n = 0;
00185         
00186         struct pcap_pkthdr *h=(struct pcap_pkthdr*)(p->buffer+p->bufsize-sizeof(struct pcap_pkthdr));
00187         
00188         while (1)
00189         {
00190             status = sf_next_packet(p, h, p->buffer, p->bufsize);
00191             if (status==1)
00192                 /* EOF */
00193                 return (-2);
00194             if (status==-1)
00195                 /* Error */
00196                 return (-1);
00197             
00198             if (fcode == NULL ||
00199                 bpf_filter(fcode, p->buffer, h->len, h->caplen)) 
00200             {
00201                 *pkt_header = h;
00202                 *pkt_data = p->buffer;
00203                 return (1);
00204             }           
00205             
00206         }
00207     }
00208 }
00209 
00210 
00211 int
00212 pcap_setuserbuffer(pcap_t *p, int size)
00213 
00214 {
00215     unsigned char *new_buff;
00216 
00217     if (!p->adapter) {
00218         sprintf(p->errbuf,"Impossible to set user buffer while reading from a file");
00219         return -1;
00220     }
00221 
00222     if (size<=0) {
00223         /* Bogus parameter */
00224         sprintf(p->errbuf,"Error: invalid size %d",size);
00225         return -1;
00226     }
00227 
00228     /* Allocate the buffer */
00229     new_buff=(unsigned char*)malloc(sizeof(char)*size);
00230 
00231     if (!new_buff) {
00232         sprintf(p->errbuf,"Error: not enough memory");
00233         return -1;
00234     }
00235 
00236     free(p->buffer);
00237     
00238     p->buffer=new_buff;
00239     p->bufsize=size;
00240 
00241     /* Associate the buffer with the capture packet */
00242     PacketInitPacket(p->Packet,(BYTE*)p->buffer,p->bufsize);
00243 
00244     return 0;
00245 
00246 }
00247 
00248 int
00249 pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks){
00250 
00251     BOOLEAN res;
00252 
00253     if (p->adapter==NULL)
00254     {
00255         sprintf(p->errbuf, "live dump needs a physical interface");
00256         return -1;
00257     }   
00258 
00259     /* Set the packet driver in dump mode */
00260     res = PacketSetMode(p->adapter, PACKET_MODE_DUMP);
00261     if(res == FALSE){
00262         sprintf(p->errbuf, "Error setting dump mode");
00263         return -1;
00264     }
00265 
00266     /* Set the name of the dump file */
00267     res = PacketSetDumpName(p->adapter, filename, strlen(filename));
00268     if(res == FALSE){
00269         sprintf(p->errbuf, "Error setting kernel dump file name");
00270         return -1;
00271     }
00272 
00273     /* Set the limits of the dump file */
00274     res = PacketSetDumpLimits(p->adapter, maxsize, maxpacks);
00275 
00276     return 0;
00277 }
00278 
00279 int 
00280 pcap_live_dump_ended(pcap_t *p, int sync){
00281 
00282     if (p->adapter == NULL)
00283     {
00284         sprintf(p->errbuf, "wrong interface type. A physical interface is needed");
00285         return -1;
00286     }   
00287 
00288     return PacketIsDumpEnded(p->adapter, (BOOLEAN)sync);
00289 
00290 }

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