2 * Copyright (c) 1999, 2002
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/fad-win32.c,v 1.5 2003-03-12 13:28:54 risso Exp $ (LBL)";
38 #ifdef HAVE_SOCKADDR_SA_LEN
39 #define SA_LEN(addr) ((addr)->sa_len)
40 #else /* HAVE_SOCKADDR_SA_LEN */
41 #define SA_LEN(addr) (sizeof (struct sockaddr))
42 #endif /* HAVE_SOCKADDR_SA_LEN */
46 * Add an entry to the list of addresses for an interface.
47 * "curdev" is the entry for that interface.
50 add_addr_to_list(pcap_if_t
*curdev
, struct sockaddr
*addr
,
51 struct sockaddr
*netmask
, struct sockaddr
*broadaddr
,
52 struct sockaddr
*dstaddr
, char *errbuf
)
54 pcap_addr_t
*curaddr
, *prevaddr
, *nextaddr
;
57 * Allocate the new entry and fill it in.
59 curaddr
= (pcap_addr_t
*)malloc(sizeof(pcap_addr_t
));
60 if (curaddr
== NULL
) {
61 (void)snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
62 "malloc: %s", pcap_strerror(errno
));
68 curaddr
->addr
= (struct sockaddr
*)dup_sockaddr(addr
, SA_LEN(addr
));
69 if (curaddr
->addr
== NULL
) {
70 (void)snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
71 "malloc: %s", pcap_strerror(errno
));
78 if (netmask
!= NULL
) {
79 curaddr
->netmask
= (struct sockaddr
*)dup_sockaddr(netmask
, SA_LEN(netmask
));
80 if (curaddr
->netmask
== NULL
) {
81 (void)snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
82 "malloc: %s", pcap_strerror(errno
));
87 curaddr
->netmask
= NULL
;
89 if (broadaddr
!= NULL
) {
90 curaddr
->broadaddr
= (struct sockaddr
*)dup_sockaddr(broadaddr
, SA_LEN(broadaddr
));
91 if (curaddr
->broadaddr
== NULL
) {
92 (void)snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
93 "malloc: %s", pcap_strerror(errno
));
98 curaddr
->broadaddr
= NULL
;
100 if (dstaddr
!= NULL
) {
101 curaddr
->dstaddr
= (struct sockaddr
*)dup_sockaddr(dstaddr
, SA_LEN(dstaddr
));
102 if (curaddr
->dstaddr
== NULL
) {
103 (void)snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
104 "malloc: %s", pcap_strerror(errno
));
109 curaddr
->dstaddr
= NULL
;
112 * Find the end of the list of addresses.
114 for (prevaddr
= curdev
->addresses
; prevaddr
!= NULL
; prevaddr
= nextaddr
) {
115 nextaddr
= prevaddr
->next
;
116 if (nextaddr
== NULL
) {
118 * This is the end of the list.
124 if (prevaddr
== NULL
) {
126 * The list was empty; this is the first member.
128 curdev
->addresses
= curaddr
;
131 * "prevaddr" is the last member of the list; append
134 prevaddr
->next
= curaddr
;
142 pcap_add_if_win32(pcap_if_t
**devlist
, char *name
, const char *desc
,
146 npf_if_addr if_addrs
[16];
153 * Add an entry for this interface, with no addresses.
155 if (add_or_find_if(&curdev
, devlist
, (char *)name
, 0, (char *)desc
,
164 * Get the list of addresses for the interface.
166 * XXX - what about IPv6?
168 if (!PacketGetNetInfoEx((void *)name
, if_addrs
, &if_addr_size
)) {
172 * We don't return an error, because this can happen with
173 * NdisWan interfaces, and we want to supply them even
174 * if we can't supply their addresses.
176 * We return an entry with an empty address list.
182 * Now add the addresses.
184 while (if_addr_size
-- > 0) {
186 * "curdev" is an entry for this interface; add an entry for
187 * this address to its list of addresses.
191 res
= add_addr_to_list(curdev
,
192 (struct sockaddr
*)&if_addrs
[if_addr_size
].IPAddress
,
193 (struct sockaddr
*)&if_addrs
[if_addr_size
].SubnetMask
,
194 (struct sockaddr
*)&if_addrs
[if_addr_size
].Broadcast
,
210 * Get a list of all interfaces that are up and that we can open.
211 * Returns -1 on error, 0 otherwise.
212 * The list, as returned through "alldevsp", may be null if no interfaces
213 * were up and could be opened.
215 * Win32 implementation, based on WinPcap
218 pcap_findalldevs(pcap_if_t
**alldevsp
, char *errbuf
)
220 pcap_if_t
*devlist
= NULL
;
222 DWORD dwWindowsMajorVersion
;
226 dwVersion
= GetVersion(); /* get the OS version */
227 dwWindowsMajorVersion
= (DWORD
)(LOBYTE(LOWORD(dwVersion
)));
228 if (dwVersion
>= 0x80000000 && dwWindowsMajorVersion
>= 4) {
230 * Windows 95, 98, ME.
232 char AdaptersName
[8192];
233 ULONG NameLength
= 8192;
236 if (!PacketGetAdapterNames(AdaptersName
, &NameLength
)) {
237 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
238 "PacketGetAdapterNames: %s",
239 pcap_win32strerror());
244 * "PacketGetAdapterNames()" returned a list of
245 * null-terminated ASCII interface name strings,
246 * terminated by a null string, followed by a list
247 * of null-terminated ASCII interface description
248 * strings, terminated by a null string.
249 * This means there are two ASCII nulls at the end
252 * Find the end of the first list; that's the
253 * beginning of the second list.
255 desc
= &AdaptersName
[0];
256 while (*desc
!= '\0' || *(desc
+ 1) != '\0')
260 * Found it - "desc" points to the first of the two
261 * nulls at the end of the list of names, so the
262 * first byte of the list of descriptions is two bytes
268 * Loop over the elements in the first list.
270 name
= &AdaptersName
[0];
271 while (*name
!= '\0') {
273 * Add an entry for this interface.
275 if (pcap_add_if_win32(&devlist
, name
, desc
,
283 name
+= strlen(name
) + 1;
284 desc
+= strlen(desc
) + 1;
288 * Windows NT (NT 4.0, W2K, WXP).
290 WCHAR AdaptersName
[8192];
291 ULONG NameLength
= 8192;
294 char ascii_name
[8192];
295 char ascii_desc
[8192];
298 if (!PacketGetAdapterNames((PTSTR
)AdaptersName
, &NameLength
)) {
299 snprintf(errbuf
, PCAP_ERRBUF_SIZE
,
300 "PacketGetAdapterNames: %s",
301 pcap_win32strerror());
306 * "PacketGetAdapterNames()" returned a list of
307 * null-terminated Unicode interface name strings,
308 * terminated by a null string, followed by a list
309 * of null-terminated ASCII interface description
310 * strings, terminated by a null string.
311 * This means there are two Unicode nulls at the end
314 * Find the end of the first list; that's the
315 * beginning of the second list.
317 t
= &AdaptersName
[0];
318 while (*t
!= '\0' || *(t
+ 1) != '\0')
322 * Found it - "t" points to the first of the two
323 * nulls at the end of the list of names, so the
324 * first byte of the list of descriptions is two wide
325 * characters after it.
328 desc
= (const char *)t
;
331 * Loop over the elements in the first list.
333 * We assume all characters in the name string are valid
336 uc_name
= &AdaptersName
[0];
337 while (*uc_name
!= '\0') {
339 while ((*p
++ = (char)*uc_name
++) != '\0')
342 while ((*p
++ = *desc
++) != '\0')
346 * Add an entry for this interface.
348 if (pcap_add_if_win32(&devlist
, ascii_name
,
349 ascii_desc
, errbuf
) == -1) {
361 * We had an error; free the list we've been constructing.
363 if (devlist
!= NULL
) {
364 pcap_freealldevs(devlist
);