Changeset 1601 for pjproject/trunk/pjlib/src/pj/ip_helper_win32.c
- Timestamp:
- Dec 1, 2007 8:52:57 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/src/pj/ip_helper_win32.c
r1450 r1601 28 28 # define PMIB_ICMP_EX void* 29 29 #endif 30 #include <winsock2.h> 31 32 /* If you encounter error "Cannot open include file: 'Iphlpapi.h' here, 33 * you need to install newer Platform SDK. Presumably you're using 34 * Microsoft Visual Studio 6? 35 */ 30 36 #include <Iphlpapi.h> 31 37 … … 42 48 PULONG pdwSize, 43 49 BOOL bOrder); 50 #if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 51 typedef DWORD (WINAPI *PFN_GetAdapterAddresses)(ULONG Family, 52 ULONG Flags, 53 PVOID Reserved, 54 PIP_ADAPTER_ADDRESSES AdapterAddresses, 55 PULONG SizePointer); 56 #endif /* PJ_HAS_IPV6 */ 44 57 typedef DWORD (WINAPI *PFN_GetIpForwardTable)(PMIB_IPFORWARDTABLE pIpForwardTable, 45 58 PULONG pdwSize, … … 49 62 static HANDLE s_hDLL; 50 63 static PFN_GetIpAddrTable s_pfnGetIpAddrTable; 64 #if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 65 static PFN_GetAdapterAddresses s_pfnGetAdapterAddresses; 66 #endif /* PJ_HAS_IPV6 */ 51 67 static PFN_GetIpForwardTable s_pfnGetIpForwardTable; 52 68 static PFN_GetIfEntry s_pfnGetIfEntry; 69 53 70 54 71 static void unload_iphlp_module(void) … … 58 75 s_pfnGetIpAddrTable = NULL; 59 76 s_pfnGetIpForwardTable = NULL; 77 s_pfnGetIfEntry = NULL; 78 #if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 79 s_pfnGetAdapterAddresses = NULL; 80 #endif 60 81 } 61 82 … … 91 112 } 92 113 114 #if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 115 static DWORD MyGetAdapterAddresses(ULONG Family, 116 ULONG Flags, 117 PVOID Reserved, 118 PIP_ADAPTER_ADDRESSES AdapterAddresses, 119 PULONG SizePointer) 120 { 121 if(NULL == s_pfnGetAdapterAddresses) { 122 s_pfnGetAdapterAddresses = (PFN_GetAdapterAddresses) 123 GetIpHlpApiProc(PJ_T("GetAdapterAddresses")); 124 } 125 126 if(NULL != s_pfnGetAdapterAddresses) { 127 return s_pfnGetAdapterAddresses(Family, Flags, Reserved, 128 AdapterAddresses, SizePointer); 129 } 130 131 return ERROR_NOT_SUPPORTED; 132 } 133 #endif /* PJ_HAS_IPV6 */ 93 134 94 135 #if PJ_IP_HELPER_IGNORE_LOOPBACK_IF … … 125 166 } 126 167 127 /* 128 * Enumerate the local IP interface currently active in the host.129 */ 130 PJ_DEF(pj_status_t) pj_enum_ip_interface(unsigned *p_cnt,131 pj_in_addr ifs[])168 /* Enumerate local IP interface using GetIpAddrTable() 169 * for IPv4 addresses only. 170 */ 171 static pj_status_t enum_ipv4_interface(unsigned *p_cnt, 172 pj_sockaddr ifs[]) 132 173 { 133 174 /* Provide enough buffer or otherwise it will fail with … … 160 201 MIB_IFROW ifRow; 161 202 162 /* Some Windows returns 0.0.0.0!*/203 /* Ignore 0.0.0.0 address (interface is down?) */ 163 204 if (pTab->table[i].dwAddr == 0) 164 205 continue; … … 175 216 #endif 176 217 177 ifs[*p_cnt].s_addr = pTab->table[i].dwAddr; 218 ifs[*p_cnt].ipv4.sin_family = PJ_AF_INET; 219 ifs[*p_cnt].ipv4.sin_addr.s_addr = pTab->table[i].dwAddr; 178 220 (*p_cnt)++; 179 221 } 180 222 181 223 return PJ_SUCCESS; 182 183 } 184 224 } 225 226 227 /* Enumerate local IP interface using GetAdapterAddresses(), 228 * which works for both IPv4 and IPv6. 229 */ 230 #if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 231 static pj_status_t enum_ipv4_ipv6_interface(int af, 232 unsigned *p_cnt, 233 pj_sockaddr ifs[]) 234 { 235 pj_uint8_t buffer[1024]; 236 IP_ADAPTER_ADDRESSES *adapter = (IP_ADAPTER_ADDRESSES*)buffer; 237 ULONG size = sizeof(buffer); 238 unsigned i; 239 DWORD rc; 240 241 rc = MyGetAdapterAddresses(af, 0, NULL, adapter, &size); 242 if (rc != ERROR_SUCCESS) 243 return PJ_RETURN_OS_ERROR(rc); 244 245 for (i=0; i<*p_cnt && adapter; ++i, adapter = adapter->Next) { 246 SOCKET_ADDRESS *pAddr = &adapter->FirstUnicastAddress->Address; 247 ifs[i].addr.sa_family = pAddr->lpSockaddr->sa_family; 248 pj_memcpy(&ifs[i], pAddr->lpSockaddr, pAddr->iSockaddrLength); 249 } 250 251 return PJ_SUCCESS; 252 } 253 #endif 254 255 256 /* 257 * Enumerate the local IP interface currently active in the host. 258 */ 259 PJ_DEF(pj_status_t) pj_enum_ip_interface(int af, 260 unsigned *p_cnt, 261 pj_sockaddr ifs[]) 262 { 263 pj_status_t status = -1; 264 265 PJ_ASSERT_RETURN(p_cnt && ifs, PJ_EINVAL); 266 PJ_ASSERT_RETURN(af==PJ_AF_UNSPEC || af==PJ_AF_INET || af==PJ_AF_INET6, 267 PJ_EAFNOTSUP); 268 269 #if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6!=0 270 status = enum_ipv4_ipv6_interface(af, p_cnt, ifs); 271 if (status != PJ_SUCCESS && (af==PJ_AF_INET || af==PJ_AF_UNSPEC)) 272 status = enum_ipv4_interface(p_cnt, ifs); 273 return status; 274 #else 275 if (af==PJ_AF_INET6) 276 return PJ_EIPV6NOTSUP; 277 else if (af != PJ_AF_INET && af != PJ_AF_UNSPEC) 278 return PJ_EAFNOTSUP; 279 280 status = enum_ipv4_interface(p_cnt, ifs); 281 return status; 282 #endif 283 } 185 284 186 285 /*
Note: See TracChangeset
for help on using the changeset viewer.