2 * Copyright (c) 1999, 2000
3 * Politecnico di Torino. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution, and (3) all advertising materials mentioning
11 * features or use of this software display the following acknowledgement:
12 * ``This product includes software developed by the Politecnico
13 * di Torino, and its contributors.'' Neither the name of
14 * the University nor the names of its contributors may be used to endorse
15 * or promote products derived from this software without specific prior
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 static const char rcsid
[] =
24 "@(#) $Header: /tcpdump/master/libpcap/pcap-win32.c,v 1.4 2002-12-19 09:05:48 guy Exp $ (LBL)";
32 #define errno (*_errno())
33 #endif /* __MINGW32__ */
35 #define PcapBufSize 256000 /*dimension of the buffer in the pcap_t structure*/
36 #define SIZE_BUF 1000000
42 WORD wVersionRequested
;
45 wVersionRequested
= MAKEWORD( 1, 1);
46 err
= WSAStartup( wVersionRequested
, &wsaData
);
56 pcap_stats(pcap_t
*p
, struct pcap_stat
*ps
)
59 if(PacketGetStats(p
->adapter
, (struct bpf_stat
*)ps
) != TRUE
){
60 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "PacketGetStats error: %s", pcap_win32strerror());
68 pcap_read(pcap_t
*p
, int cnt
, pcap_handler callback
, u_char
*user
)
72 register u_char
*bp
, *ep
;
77 /* capture the packets */
78 if(PacketReceivePacket(p
->adapter
,p
->Packet
,TRUE
)==FALSE
){
79 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "read error: PacketReceivePacket failed");
83 cc
= p
->Packet
->ulBytesReceived
;
85 bp
= p
->Packet
->Buffer
;
91 * Loop through each packet.
93 #define bhp ((struct bpf_hdr *)bp)
96 register int caplen
, hdrlen
;
97 caplen
= bhp
->bh_caplen
;
98 hdrlen
= bhp
->bh_hdrlen
;
101 * XXX A bpf_hdr matches a pcap_pkthdr.
103 (*callback
)(user
, (struct pcap_pkthdr
*)bp
, bp
+ hdrlen
);
104 bp
+= BPF_WORDALIGN(caplen
+ hdrlen
);
105 if (++n
>= cnt
&& cnt
> 0) {
118 pcap_open_live(char *device
, int snaplen
, int promisc
, int to_ms
, char *ebuf
)
126 p
= (pcap_t
*)malloc(sizeof(*p
));
128 snprintf(ebuf
, PCAP_ERRBUF_SIZE
, "malloc: %s", pcap_strerror(errno
));
131 memset(p
, 0, sizeof(*p
));
134 p
->adapter
=PacketOpenAdapter(device
);
135 if (p
->adapter
==NULL
) {
136 snprintf(ebuf
, PCAP_ERRBUF_SIZE
, "Error opening adapter: %s", pcap_win32strerror());
141 if(PacketGetNetType (p
->adapter
,&type
)==FALSE
)
143 snprintf(ebuf
, PCAP_ERRBUF_SIZE
, "Cannot determine the network type: %s", pcap_win32strerror());
148 switch (type
.LinkType
) {
151 p
->linktype
= DLT_EN10MB
;
154 case NdisMedium802_3
:
155 p
->linktype
= DLT_EN10MB
;
159 p
->linktype
= DLT_FDDI
;
162 case NdisMedium802_5
:
163 p
->linktype
= DLT_IEEE802
;
166 case NdisMediumArcnetRaw
:
167 p
->linktype
= DLT_ARCNET
;
169 case NdisMediumArcnet878_2
:
170 p
->linktype
= DLT_ARCNET
;
174 p
->linktype
= DLT_ATM_RFC1483
;
178 p
->linktype
= DLT_EN10MB
; /*an unknown adapter is assumed to be ethernet*/
181 /* Set promisquous mode */
182 if (promisc
) PacketSetHwFilter(p
->adapter
,NDIS_PACKET_TYPE_PROMISCUOUS
);
183 else PacketSetHwFilter(p
->adapter
,NDIS_PACKET_TYPE_ALL_LOCAL
);
185 /* Set the buffer size */
186 p
->bufsize
= PcapBufSize
;
188 p
->buffer
= (u_char
*)malloc(PcapBufSize
);
189 if (p
->buffer
== NULL
) {
190 snprintf(ebuf
, PCAP_ERRBUF_SIZE
, "malloc: %s", pcap_strerror(errno
));
194 p
->snapshot
= snaplen
;
196 /* allocate Packet structure used during the capture */
197 if((p
->Packet
= PacketAllocatePacket())==NULL
){
198 snprintf(ebuf
, PCAP_ERRBUF_SIZE
, "failed to allocate the PACKET structure");
202 PacketInitPacket(p
->Packet
,(BYTE
*)p
->buffer
,p
->bufsize
);
204 /* allocate the standard buffer in the driver */
205 if(PacketSetBuff( p
->adapter
, SIZE_BUF
)==FALSE
)
207 snprintf(ebuf
, PCAP_ERRBUF_SIZE
,"driver error: not enough memory to allocate the kernel buffer\n");
211 /* tell the driver to copy the buffer only if it contains at least 16K */
212 if(PacketSetMinToCopy(p
->adapter
,16000)==FALSE
)
214 snprintf(ebuf
, PCAP_ERRBUF_SIZE
,"Error calling PacketSetMinToCopy: %s\n", pcap_win32strerror());
218 PacketSetReadTimeout(p
->adapter
, to_ms
);
223 PacketCloseAdapter(p
->adapter
);
224 if (p
->buffer
!= NULL
)
232 pcap_setfilter(pcap_t
*p
, struct bpf_program
*fp
)
234 if(p
->adapter
==NULL
){
235 /* Offline capture: make our own copy of the filter */
236 if (install_bpf_program(p
, fp
) < 0)
239 else if(PacketSetBpf(p
->adapter
,fp
)==FALSE
){
240 /* kernel filter not installed. */
241 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "Driver error: cannot set bpf filter: %s", pcap_win32strerror());
248 /* Set the driver working mode */
250 pcap_setmode(pcap_t
*p
, int mode
){
252 if (p
->adapter
==NULL
)
254 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "impossible to set mode while reading from a file");
258 if(PacketSetMode(p
->adapter
,mode
)==FALSE
)
260 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "driver error: working mode not recognized");
267 /* Send a packet to the network */
269 pcap_sendpacket(pcap_t
*p
, u_char
*buf
, int size
){
270 LPPACKET PacketToSend
;
272 if (p
->adapter
==NULL
)
274 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "Writing a packet is allowed only on a physical adapter");
278 PacketToSend
=PacketAllocatePacket();
279 PacketInitPacket(PacketToSend
,buf
,size
);
280 if(PacketSendPacket(p
->adapter
,PacketToSend
,TRUE
) == FALSE
){
281 PacketFreePacket(PacketToSend
);
285 PacketFreePacket(PacketToSend
);
289 /* Set the dimension of the kernel-level capture buffer */
291 pcap_setbuff(pcap_t
*p
, int dim
)
293 if (p
->adapter
==NULL
)
295 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "The kernel buffer size cannot be set while reading from a file");
299 if(PacketSetBuff(p
->adapter
,dim
)==FALSE
)
301 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "driver error: not enough memory to allocate the kernel buffer");
307 /*set the minimum amount of data that will release a read call*/
309 pcap_setmintocopy(pcap_t
*p
, int size
)
311 if (p
->adapter
==NULL
)
313 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "Impossible to set the mintocopy parameter on an offline capture");
317 if(PacketSetMinToCopy(p
->adapter
, size
)==FALSE
)
319 snprintf(p
->errbuf
, PCAP_ERRBUF_SIZE
, "driver error: unable to set the requested mintocopy size");
326 pcap_set_datalink_platform(pcap_t
*p
, int dlt
)