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.