2 This file is part of catta.
4 catta is free software; you can redistribute it and/or modify it
5 under the terms of the GNU Lesser General Public License as
6 published by the Free Software Foundation; either version 2.1 of the
7 License, or (at your option) any later version.
9 catta is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
12 Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with catta; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 #include "iface-windows.h"
23 #include <stdlib.h> // wcstombs
24 #include <catta/malloc.h>
25 #include <catta/log.h>
28 #include "util.h" // catta_format_mac_address
31 // for the luid-to-idx hashmap
32 static unsigned luid_hash(const void *data)
34 return ((NET_LUID *)data)->Info.NetLuidIndex;
36 static int luid_equal(const void *a, const void *b)
38 return (((NET_LUID *)a)->Value == ((NET_LUID *)b)->Value);
41 static CattaIfIndex find_ifindex(CattaInterfaceMonitor *m, NET_LUID luid)
43 CattaIfIndex *pi = NULL;
46 if((pi = catta_hashmap_lookup(m->osdep.idxmap, &luid)) == NULL) {
47 // allocate memory for the hashmap key and value
48 key = catta_malloc(sizeof(luid));
49 pi = catta_malloc(sizeof(CattaIfIndex));
55 // find an index for this luid
57 if(*pi < 0) // overflow
61 if(catta_hashmap_replace(m->osdep.idxmap, key, pi) < 0)
74 // integrate the information from an IP_ADAPTER_ADDRESSES structure
75 // as returned by GetAdaptersAddresses into the CattaInterfaceMonitor
76 static void ip_adapter_address(CattaInterfaceMonitor *m, IP_ADAPTER_ADDRESSES *p)
82 // look up the interface index by LUID
83 if((idx = find_ifindex(m, p->Luid)) < 0) {
84 catta_log_error("could not allocate index ip_adapter_address");
88 // find the CattaHwInterface by index or allocate a new one
89 if((hw = catta_interface_monitor_get_hw_interface(m, idx)) == NULL) {
90 if((hw = catta_hw_interface_new(m, idx)) == NULL) {
91 catta_log_error("catta_hw_interface_new failed in ip_adapter_address");
96 // fill the CattaHwInterface struct with data
98 (p->OperStatus & IfOperStatusUp) &&
99 !(p->IfType & IF_TYPE_SOFTWARE_LOOPBACK) &&
100 !(p->Flags & IP_ADAPTER_NO_MULTICAST) &&
101 (m->server->config.allow_point_to_point || !(p->IfType & IF_TYPE_PPP));
102 // XXX what about IF_TYPE_TUNNEL?
104 n = wcstombs(NULL, p->FriendlyName, 0) + 1;
105 catta_free(hw->name);
106 hw->name = catta_new(char, n);
107 wcstombs(hw->name, p->FriendlyName, n);
111 hw->mac_address_size = p->PhysicalAddressLength;
112 if (hw->mac_address_size > CATTA_MAC_ADDRESS_MAX)
113 hw->mac_address_size = CATTA_MAC_ADDRESS_MAX;
114 memcpy(hw->mac_address, p->PhysicalAddress, hw->mac_address_size);
116 // XXX process addresses
118 // XXX debugging, remove
121 catta_log_debug("======\n name: %s\n index:%d\n mtu:%d\n mac:%s\n flags_ok:%d\n======",
124 catta_format_mac_address(mac, sizeof(mac), hw->mac_address, hw->mac_address_size),
130 int catta_interface_monitor_init_osdep(CattaInterfaceMonitor *m)
133 m->osdep.idxmap = catta_hashmap_new(luid_hash, luid_equal, catta_free, catta_free);
134 if(m->osdep.idxmap == NULL) {
135 catta_log_error("out of memory in catta_interface_monitor_init_osdep");
139 // XXX register callbacks to get notified of interface/address changes
144 void catta_interface_monitor_free_osdep(CattaInterfaceMonitor *m)
146 catta_hashmap_free(m->osdep.idxmap);
149 void catta_interface_monitor_sync(CattaInterfaceMonitor *m)
151 IP_ADAPTER_ADDRESSES *buf = NULL;
152 IP_ADAPTER_ADDRESSES *p;
153 ULONG bufsize = 15000;
156 // allocate a buffer and call GetAdaptersAddresses
157 // retry with the correct size if the buffer was too small
159 catta_free(buf); // no-op on first iteration
160 if((buf = catta_malloc(bufsize)) == NULL) {
161 catta_log_error("malloc failed in catta_interface_monitor_sync");
165 r = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, buf, &bufsize);
166 } while(r == ERROR_BUFFER_OVERFLOW);
169 catta_log_error("GetAdaptersAddresses failed: %u", (unsigned int)r);
173 // XXX remove interfaces for adapters that are no longer in the list
175 // create 'CattaInterface's for every adapter
176 for(p=buf; p; p=p->Next)
177 ip_adapter_address(m, p);
181 m->list_complete = 1;
182 catta_interface_monitor_check_relevant(m);
183 catta_interface_monitor_update_rrs(m, 0);
184 catta_log_info("Network interface enumeration completed.");