1/*
| 1/*
|
2 * Copyright (c) 2002 - 2003 3 * NetGroup, Politecnico di Torino (Italy)
| 2 * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy) 3 * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
|
4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution.
| 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution.
|
15 * 3. Neither the name of the Politecnico di Torino nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission.
| 15 * 3. Neither the name of the Politecnico di Torino, CACE Technologies 16 * nor the names of its contributors may be used to endorse or promote 17 * products derived from this software without specific prior written 18 * permission.
|
18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 * 31 */ 32 33#ifndef lint 34static const char rcsid[] _U_ =
| 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 */ 33 34#ifndef lint 35static const char rcsid[] _U_ =
|
35 "@(#) $Header: /tcpdump/master/libpcap/fad-win32.c,v 1.11.2.1 2005/09/01 22:07:41 risso Exp $ (LBL)";
| 36 "@(#) $Header: /tcpdump/master/libpcap/fad-win32.c,v 1.11.2.3 2006/02/22 17:09:32 gianluca Exp $ (LBL)";
|
36#endif 37 38#ifdef HAVE_CONFIG_H 39#include "config.h" 40#endif 41 42#include <pcap.h> 43#include <pcap-int.h>
| 37#endif 38 39#ifdef HAVE_CONFIG_H 40#include "config.h" 41#endif 42 43#include <pcap.h> 44#include <pcap-int.h>
|
44#include <packet32.h>
| 45#include <Packet32.h>
|
45 46#include <errno.h> 47 48/* 49 * Add an entry to the list of addresses for an interface. 50 * "curdev" is the entry for that interface. 51 */ 52static int 53add_addr_to_list(pcap_if_t *curdev, struct sockaddr *addr, 54 struct sockaddr *netmask, struct sockaddr *broadaddr, 55 struct sockaddr *dstaddr, char *errbuf) 56{ 57 pcap_addr_t *curaddr, *prevaddr, *nextaddr; 58 59 /* 60 * Allocate the new entry and fill it in. 61 */ 62 curaddr = (pcap_addr_t*)malloc(sizeof(pcap_addr_t)); 63 if (curaddr == NULL) { 64 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 65 "malloc: %s", pcap_strerror(errno)); 66 return (-1); 67 } 68 69 curaddr->next = NULL; 70 if (addr != NULL) { 71 curaddr->addr = (struct sockaddr*)dup_sockaddr(addr, sizeof(struct sockaddr_storage)); 72 if (curaddr->addr == NULL) { 73 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 74 "malloc: %s", pcap_strerror(errno)); 75 free(curaddr); 76 return (-1); 77 } 78 } else 79 curaddr->addr = NULL; 80 81 if (netmask != NULL) { 82 curaddr->netmask = (struct sockaddr*)dup_sockaddr(netmask, sizeof(struct sockaddr_storage)); 83 if (curaddr->netmask == NULL) { 84 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 85 "malloc: %s", pcap_strerror(errno)); 86 free(curaddr); 87 return (-1); 88 } 89 } else 90 curaddr->netmask = NULL; 91 92 if (broadaddr != NULL) { 93 curaddr->broadaddr = (struct sockaddr*)dup_sockaddr(broadaddr, sizeof(struct sockaddr_storage)); 94 if (curaddr->broadaddr == NULL) { 95 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 96 "malloc: %s", pcap_strerror(errno)); 97 free(curaddr); 98 return (-1); 99 } 100 } else 101 curaddr->broadaddr = NULL; 102 103 if (dstaddr != NULL) { 104 curaddr->dstaddr = (struct sockaddr*)dup_sockaddr(dstaddr, sizeof(struct sockaddr_storage)); 105 if (curaddr->dstaddr == NULL) { 106 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 107 "malloc: %s", pcap_strerror(errno)); 108 free(curaddr); 109 return (-1); 110 } 111 } else 112 curaddr->dstaddr = NULL; 113 114 /* 115 * Find the end of the list of addresses. 116 */ 117 for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) { 118 nextaddr = prevaddr->next; 119 if (nextaddr == NULL) { 120 /* 121 * This is the end of the list. 122 */ 123 break; 124 } 125 } 126 127 if (prevaddr == NULL) { 128 /* 129 * The list was empty; this is the first member. 130 */ 131 curdev->addresses = curaddr; 132 } else { 133 /* 134 * "prevaddr" is the last member of the list; append 135 * this member to it. 136 */ 137 prevaddr->next = curaddr; 138 } 139 140 return (0); 141} 142 143 144static int 145pcap_add_if_win32(pcap_if_t **devlist, char *name, const char *desc, 146 char *errbuf) 147{ 148 pcap_if_t *curdev; 149 npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES]; 150 LONG if_addr_size; 151 int res = 0; 152 153 if_addr_size = MAX_NETWORK_ADDRESSES; 154 155 /* 156 * Add an entry for this interface, with no addresses. 157 */ 158 if (add_or_find_if(&curdev, devlist, name, 0, desc, errbuf) == -1) { 159 /* 160 * Failure. 161 */ 162 return (-1); 163 } 164 165 /* 166 * Get the list of addresses for the interface. 167 */ 168 if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) { 169 /* 170 * Failure. 171 * 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. 175 * 176 * We return an entry with an empty address list. 177 */ 178 return (0); 179 } 180 181 /* 182 * Now add the addresses. 183 */ 184 while (if_addr_size-- > 0) { 185 /* 186 * "curdev" is an entry for this interface; add an entry for 187 * this address to its list of addresses. 188 */ 189 if(curdev == NULL) 190 break; 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, 195 NULL, 196 errbuf); 197 if (res == -1) { 198 /* 199 * Failure. 200 */ 201 break; 202 } 203 } 204 205 return (res); 206} 207 208 209/* 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. 214 * 215 * Win32 implementation, based on WinPcap 216 */ 217int 218pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 219{ 220 pcap_if_t *devlist = NULL; 221 int ret = 0; 222 const char *desc; 223 char *AdaptersName; 224 ULONG NameLength; 225 char *name; 226
| 46 47#include <errno.h> 48 49/* 50 * Add an entry to the list of addresses for an interface. 51 * "curdev" is the entry for that interface. 52 */ 53static int 54add_addr_to_list(pcap_if_t *curdev, struct sockaddr *addr, 55 struct sockaddr *netmask, struct sockaddr *broadaddr, 56 struct sockaddr *dstaddr, char *errbuf) 57{ 58 pcap_addr_t *curaddr, *prevaddr, *nextaddr; 59 60 /* 61 * Allocate the new entry and fill it in. 62 */ 63 curaddr = (pcap_addr_t*)malloc(sizeof(pcap_addr_t)); 64 if (curaddr == NULL) { 65 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 66 "malloc: %s", pcap_strerror(errno)); 67 return (-1); 68 } 69 70 curaddr->next = NULL; 71 if (addr != NULL) { 72 curaddr->addr = (struct sockaddr*)dup_sockaddr(addr, sizeof(struct sockaddr_storage)); 73 if (curaddr->addr == NULL) { 74 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 75 "malloc: %s", pcap_strerror(errno)); 76 free(curaddr); 77 return (-1); 78 } 79 } else 80 curaddr->addr = NULL; 81 82 if (netmask != NULL) { 83 curaddr->netmask = (struct sockaddr*)dup_sockaddr(netmask, sizeof(struct sockaddr_storage)); 84 if (curaddr->netmask == NULL) { 85 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 86 "malloc: %s", pcap_strerror(errno)); 87 free(curaddr); 88 return (-1); 89 } 90 } else 91 curaddr->netmask = NULL; 92 93 if (broadaddr != NULL) { 94 curaddr->broadaddr = (struct sockaddr*)dup_sockaddr(broadaddr, sizeof(struct sockaddr_storage)); 95 if (curaddr->broadaddr == NULL) { 96 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 97 "malloc: %s", pcap_strerror(errno)); 98 free(curaddr); 99 return (-1); 100 } 101 } else 102 curaddr->broadaddr = NULL; 103 104 if (dstaddr != NULL) { 105 curaddr->dstaddr = (struct sockaddr*)dup_sockaddr(dstaddr, sizeof(struct sockaddr_storage)); 106 if (curaddr->dstaddr == NULL) { 107 (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, 108 "malloc: %s", pcap_strerror(errno)); 109 free(curaddr); 110 return (-1); 111 } 112 } else 113 curaddr->dstaddr = NULL; 114 115 /* 116 * Find the end of the list of addresses. 117 */ 118 for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) { 119 nextaddr = prevaddr->next; 120 if (nextaddr == NULL) { 121 /* 122 * This is the end of the list. 123 */ 124 break; 125 } 126 } 127 128 if (prevaddr == NULL) { 129 /* 130 * The list was empty; this is the first member. 131 */ 132 curdev->addresses = curaddr; 133 } else { 134 /* 135 * "prevaddr" is the last member of the list; append 136 * this member to it. 137 */ 138 prevaddr->next = curaddr; 139 } 140 141 return (0); 142} 143 144 145static int 146pcap_add_if_win32(pcap_if_t **devlist, char *name, const char *desc, 147 char *errbuf) 148{ 149 pcap_if_t *curdev; 150 npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES]; 151 LONG if_addr_size; 152 int res = 0; 153 154 if_addr_size = MAX_NETWORK_ADDRESSES; 155 156 /* 157 * Add an entry for this interface, with no addresses. 158 */ 159 if (add_or_find_if(&curdev, devlist, name, 0, desc, errbuf) == -1) { 160 /* 161 * Failure. 162 */ 163 return (-1); 164 } 165 166 /* 167 * Get the list of addresses for the interface. 168 */ 169 if (!PacketGetNetInfoEx((void *)name, if_addrs, &if_addr_size)) { 170 /* 171 * Failure. 172 * 173 * We don't return an error, because this can happen with 174 * NdisWan interfaces, and we want to supply them even 175 * if we can't supply their addresses. 176 * 177 * We return an entry with an empty address list. 178 */ 179 return (0); 180 } 181 182 /* 183 * Now add the addresses. 184 */ 185 while (if_addr_size-- > 0) { 186 /* 187 * "curdev" is an entry for this interface; add an entry for 188 * this address to its list of addresses. 189 */ 190 if(curdev == NULL) 191 break; 192 res = add_addr_to_list(curdev, 193 (struct sockaddr *)&if_addrs[if_addr_size].IPAddress, 194 (struct sockaddr *)&if_addrs[if_addr_size].SubnetMask, 195 (struct sockaddr *)&if_addrs[if_addr_size].Broadcast, 196 NULL, 197 errbuf); 198 if (res == -1) { 199 /* 200 * Failure. 201 */ 202 break; 203 } 204 } 205 206 return (res); 207} 208 209 210/* 211 * Get a list of all interfaces that are up and that we can open. 212 * Returns -1 on error, 0 otherwise. 213 * The list, as returned through "alldevsp", may be null if no interfaces 214 * were up and could be opened. 215 * 216 * Win32 implementation, based on WinPcap 217 */ 218int 219pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf) 220{ 221 pcap_if_t *devlist = NULL; 222 int ret = 0; 223 const char *desc; 224 char *AdaptersName; 225 ULONG NameLength; 226 char *name; 227
|
227 if(!PacketGetAdapterNames(NULL, &NameLength) && NameLength == 0)
| 228 if (!PacketGetAdapterNames(NULL, &NameLength))
|
228 {
| 229 {
|
229 /* 230 * If PacketGetAdapterNames *and* sets the lenght of the buffer to zero, 231 * it means there was an error. 232 */ 233 snprintf(errbuf, PCAP_ERRBUF_SIZE, "PacketGetAdapterNames failed: %s", pcap_win32strerror()); 234 *alldevsp = NULL; 235 return -1;
| 230 DWORD last_error = GetLastError(); 231 232 if (last_error != ERROR_INSUFFICIENT_BUFFER) 233 { 234 snprintf(errbuf, PCAP_ERRBUF_SIZE, 235 "PacketGetAdapterNames: %s", 236 pcap_win32strerror()); 237 return (-1); 238 }
|
236 } 237 238 if (NameLength > 0) 239 AdaptersName = (char*) malloc(NameLength); 240 else 241 {
| 239 } 240 241 if (NameLength > 0) 242 AdaptersName = (char*) malloc(NameLength); 243 else 244 {
|
242 snprintf(errbuf, PCAP_ERRBUF_SIZE, "no adapters found.");
| |
243 *alldevsp = NULL; 244 return 0; 245 } 246 if (AdaptersName == NULL) 247 { 248 snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters."); 249 return (-1); 250 } 251 252 if (!PacketGetAdapterNames(AdaptersName, &NameLength)) { 253 snprintf(errbuf, PCAP_ERRBUF_SIZE, 254 "PacketGetAdapterNames: %s", 255 pcap_win32strerror()); 256 free(AdaptersName); 257 return (-1); 258 } 259 260 /* 261 * "PacketGetAdapterNames()" returned a list of 262 * null-terminated ASCII interface name strings, 263 * terminated by a null string, followed by a list 264 * of null-terminated ASCII interface description 265 * strings, terminated by a null string. 266 * This means there are two ASCII nulls at the end 267 * of the first list. 268 * 269 * Find the end of the first list; that's the 270 * beginning of the second list. 271 */ 272 desc = &AdaptersName[0]; 273 while (*desc != '\0' || *(desc + 1) != '\0') 274 desc++; 275 276 /* 277 * Found it - "desc" points to the first of the two 278 * nulls at the end of the list of names, so the 279 * first byte of the list of descriptions is two bytes 280 * after it. 281 */ 282 desc += 2; 283 284 /* 285 * Loop over the elements in the first list. 286 */ 287 name = &AdaptersName[0]; 288 while (*name != '\0') { 289 /* 290 * Add an entry for this interface. 291 */ 292 if (pcap_add_if_win32(&devlist, name, desc, errbuf) == -1) { 293 /* 294 * Failure. 295 */ 296 ret = -1; 297 break; 298 } 299 name += strlen(name) + 1; 300 desc += strlen(desc) + 1; 301 } 302 303 if (ret == -1) { 304 /* 305 * We had an error; free the list we've been constructing. 306 */ 307 if (devlist != NULL) { 308 pcap_freealldevs(devlist); 309 devlist = NULL; 310 } 311 } 312 313 *alldevsp = devlist; 314 free(AdaptersName); 315 return (ret); 316}
| 245 *alldevsp = NULL; 246 return 0; 247 } 248 if (AdaptersName == NULL) 249 { 250 snprintf(errbuf, PCAP_ERRBUF_SIZE, "Cannot allocate enough memory to list the adapters."); 251 return (-1); 252 } 253 254 if (!PacketGetAdapterNames(AdaptersName, &NameLength)) { 255 snprintf(errbuf, PCAP_ERRBUF_SIZE, 256 "PacketGetAdapterNames: %s", 257 pcap_win32strerror()); 258 free(AdaptersName); 259 return (-1); 260 } 261 262 /* 263 * "PacketGetAdapterNames()" returned a list of 264 * null-terminated ASCII interface name strings, 265 * terminated by a null string, followed by a list 266 * of null-terminated ASCII interface description 267 * strings, terminated by a null string. 268 * This means there are two ASCII nulls at the end 269 * of the first list. 270 * 271 * Find the end of the first list; that's the 272 * beginning of the second list. 273 */ 274 desc = &AdaptersName[0]; 275 while (*desc != '\0' || *(desc + 1) != '\0') 276 desc++; 277 278 /* 279 * Found it - "desc" points to the first of the two 280 * nulls at the end of the list of names, so the 281 * first byte of the list of descriptions is two bytes 282 * after it. 283 */ 284 desc += 2; 285 286 /* 287 * Loop over the elements in the first list. 288 */ 289 name = &AdaptersName[0]; 290 while (*name != '\0') { 291 /* 292 * Add an entry for this interface. 293 */ 294 if (pcap_add_if_win32(&devlist, name, desc, errbuf) == -1) { 295 /* 296 * Failure. 297 */ 298 ret = -1; 299 break; 300 } 301 name += strlen(name) + 1; 302 desc += strlen(desc) + 1; 303 } 304 305 if (ret == -1) { 306 /* 307 * We had an error; free the list we've been constructing. 308 */ 309 if (devlist != NULL) { 310 pcap_freealldevs(devlist); 311 devlist = NULL; 312 } 313 } 314 315 *alldevsp = devlist; 316 free(AdaptersName); 317 return (ret); 318}
|