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.