1/* $NetBSD: getifaddrs_w32.c,v 1.2 2017/01/28 21:31:50 christos Exp $ */ 2 3/*********************************************************************** 4 * Copyright (c) 2009, Secure Endpoints Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * - Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 14 * - Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in 16 * the documentation and/or other materials provided with the 17 * distribution. 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 22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 30 * OF THE POSSIBILITY OF SUCH DAMAGE. 31 * 32 **********************************************************************/ 33 34#include<config.h> 35 36#include <krb5/roken.h> 37 38#include <ifaddrs.h> 39 40#ifndef _WIN32 41#error This is a Windows specific implementation. 42#endif 43 44static struct sockaddr * 45dupaddr(const sockaddr_gen * src) 46{ 47 sockaddr_gen * d = malloc(sizeof(*d)); 48 49 if (d) { 50 memcpy(d, src, sizeof(*d)); 51 } 52 53 return (struct sockaddr *) d; 54} 55 56int ROKEN_LIB_FUNCTION 57rk_getifaddrs(struct ifaddrs **ifpp) 58{ 59 SOCKET s = INVALID_SOCKET; 60 size_t il_len = 8192; 61 int ret = -1; 62 INTERFACE_INFO *il = NULL; 63 64 *ifpp = NULL; 65 66 s = socket(AF_INET, SOCK_DGRAM, 0); 67 if (s == INVALID_SOCKET) 68 return -1; 69 70 for (;;) { 71 DWORD cbret = 0; 72 73 il = malloc(il_len); 74 if (!il) 75 break; 76 77 ZeroMemory(il, il_len); 78 79 if (WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, 80 (LPVOID) il, (DWORD) il_len, &cbret, 81 NULL, NULL) == 0) { 82 il_len = cbret; 83 break; 84 } 85 86 free (il); 87 il = NULL; 88 89 if (WSAGetLastError() == WSAEFAULT && cbret > il_len) { 90 il_len = cbret; 91 } else { 92 break; 93 } 94 } 95 96 if (!il) 97 goto _exit; 98 99 /* il is an array of INTERFACE_INFO structures. il_len has the 100 actual size of the buffer. The number of elements is 101 il_len/sizeof(INTERFACE_INFO) */ 102 103 { 104 size_t n = il_len / sizeof(INTERFACE_INFO); 105 size_t i; 106 107 for (i = 0; i < n; i++ ) { 108 struct ifaddrs *ifp; 109 110 ifp = malloc(sizeof(*ifp)); 111 if (ifp == NULL) 112 break; 113 114 ZeroMemory(ifp, sizeof(*ifp)); 115 116 ifp->ifa_next = NULL; 117 ifp->ifa_name = NULL; 118 ifp->ifa_flags = il[i].iiFlags; 119 ifp->ifa_addr = dupaddr(&il[i].iiAddress); 120 ifp->ifa_netmask = dupaddr(&il[i].iiNetmask); 121 ifp->ifa_broadaddr = dupaddr(&il[i].iiBroadcastAddress); 122 ifp->ifa_data = NULL; 123 124 *ifpp = ifp; 125 ifpp = &ifp->ifa_next; 126 } 127 128 if (i == n) 129 ret = 0; 130 } 131 132 _exit: 133 134 if (s != INVALID_SOCKET) 135 closesocket(s); 136 137 if (il) 138 free (il); 139 140 return ret; 141} 142 143void ROKEN_LIB_FUNCTION 144rk_freeifaddrs(struct ifaddrs *ifp) 145{ 146 struct ifaddrs *p, *q; 147 148 for(p = ifp; p; ) { 149 if (p->ifa_name) 150 free(p->ifa_name); 151 if(p->ifa_addr) 152 free(p->ifa_addr); 153 if(p->ifa_dstaddr) 154 free(p->ifa_dstaddr); 155 if(p->ifa_netmask) 156 free(p->ifa_netmask); 157 if(p->ifa_data) 158 free(p->ifa_data); 159 q = p; 160 p = p->ifa_next; 161 free(q); 162 } 163} 164