メイン   モジュール   デー タ構造   ファイルリスト   データフィールド   グローバル   関連ページ   注意事項   English

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.
2005 translated by Telebusiness,Inc.
 All rights reserved.