Commit 07b5479c authored by Jondy Zhao's avatar Jondy Zhao

Metric 0 is invalid in the cygwin, use 1 instead;

define KERNEL_IFNINITY as 9999 other than 0xFFFF as the same reason;
Use connection name as interface name instead GUID;
Add platform macro in the Makefile and source files;
Update README.cygwin as the changes.
parent 7ca8acee
...@@ -9,10 +9,28 @@ CFLAGS = $(CDEBUGFLAGS) $(DEFINES) $(EXTRA_DEFINES) ...@@ -9,10 +9,28 @@ CFLAGS = $(CDEBUGFLAGS) $(DEFINES) $(EXTRA_DEFINES)
LDLIBS = -lrt -liphlpapi -lws2_32 -lwlanapi -lole32 -lsetupapi LDLIBS = -lrt -liphlpapi -lws2_32 -lwlanapi -lole32 -lsetupapi
SRCS = babeld.c net.c kernel.c util.c interface.c source.c neighbour.c \ SRCS = babeld.c net.c kernel.c util.c interface.c source.c neighbour.c \
route.c xroute.c message.c resend.c configuration.c local.c cyginet.c route.c xroute.c message.c resend.c configuration.c local.c
OBJS = babeld.o net.o kernel.o util.o interface.o source.o neighbour.o \ OBJS = babeld.o net.o kernel.o util.o interface.o source.o neighbour.o \
route.o xroute.o message.o resend.o configuration.o local.o cyginet.o route.o xroute.o message.o resend.o configuration.o local.o
KERNEL_SOUCES = kernel_netlink.c kernel_socket.c
ifneq "$(WINVER)" ""
SRCS += cyginet.c
OBJS += cyginet.o
KERNEL_SOUCES += kernel_cygwin.c
ifeq "$(WINVER)" "XP"
DEFINES += -D_WIN32_WINNT=0x0503
endif
ifeq "$(WINVER)" "VISTA"
DEFINES += -D_WIN32_WINNT=0x0600
endif
endif
babeld: $(OBJS) babeld: $(OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) -o babeld $(OBJS) $(LDLIBS) $(CC) $(CFLAGS) $(LDFLAGS) -o babeld $(OBJS) $(LDLIBS)
...@@ -48,4 +66,4 @@ uninstall: ...@@ -48,4 +66,4 @@ uninstall:
clean: clean:
-rm -f babeld babeld.html *.o *~ core TAGS gmon.out -rm -f babeld babeld.html *.o *~ core TAGS gmon.out
kernel.o: kernel_netlink.c kernel_socket.c kernel_cygwin.c kernel.o: $(KERNEL_SOURCES)
...@@ -25,28 +25,40 @@ Required packages: ...@@ -25,28 +25,40 @@ Required packages:
In the Windows XP, In the Windows XP,
$ PLATFORM_DEFINES="-D_WIN32_WINNT=0x0503" make $ WINVER=XP make
Later Windows Vista, Later Windows Vista,
$ PLATFORM_DEFINES="-D_WIN32_WINNT=0x0600" make $ WINVER=VISTA make
Interface Names Interface Names
=============== ===============
In the Windows, GUID is used as unique interface names. You can list Use network connection name as interface name.
all the interfaces by the following command:
$ ipv6 if | grep "^Interface" -A 1 Notes
=====
-- 1. If network connection is disabeld, its interface name will NOT be
Interface 2: Automatic Tunneling Pseudo-Interface recognize by Babeld in the Cygwin.
Guid {48FCE3FC-EC30-E50E-F1A7-71172AEEE3AE}
--
Interface 1: Loopback Pseudo-Interface
Guid {6BD113CC-5EC2-7638-B953-0B889DA72014}
...
When call babled, use GUID as interface name: 2. For the option "-z", kind value could be "0", "1", others is not
supported. Because no any API channels in the Windows XP, even for
wireless interface.
$ ./babeld.exe {6BD113CC-5EC2-7638-B953-0B889DA72014} 3. Only -t 0, -T 0 is valid, no multi-route tables in the Windows.
4. IPV6_TCLASS doesn't work, so babeld will complain:
"Couldn't set traffic class"
5. Ipv6 option "IPV6_V6ONLY" only works in the Windows Vista later.
6. If one connection is assigned more than one ipv4 address, babeld
returns the first one only, is it right? I'm not sure.
7. Regarding IPV6CTL_FORWARDING and IPV6CTL_SENDREDIRECTS, MSDN says
that you can set both of options for Ipv4 in the registry:
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters",
but says nothing for Ipv6. Does it work for ipv6 in the registry:
"HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters"
?
\ No newline at end of file
...@@ -371,7 +371,11 @@ main(int argc, char **argv) ...@@ -371,7 +371,11 @@ main(int argc, char **argv)
FOR_ALL_INTERFACES(ifp) { FOR_ALL_INTERFACES(ifp) {
/* ifp->ifindex is not necessarily valid at this point */ /* ifp->ifindex is not necessarily valid at this point */
#if defined (_WIN32_WINNT)
int ifindex = if_nametoindex(cyginet_guidname(ifp->name));
#else
int ifindex = if_nametoindex(ifp->name); int ifindex = if_nametoindex(ifp->name);
#endif
if(ifindex > 0) { if(ifindex > 0) {
unsigned char eui[8]; unsigned char eui[8];
rc = if_eui64(ifp->name, ifindex, eui); rc = if_eui64(ifp->name, ifindex, eui);
...@@ -390,7 +394,11 @@ main(int argc, char **argv) ...@@ -390,7 +394,11 @@ main(int argc, char **argv)
ifname = if_indextoname(i, buf); ifname = if_indextoname(i, buf);
if(ifname == NULL) if(ifname == NULL)
continue; continue;
#if defined (_WIN32_WINNT)
rc = if_eui64(cyginet_ifname(ifname), i, eui);
#else
rc = if_eui64(ifname, i, eui); rc = if_eui64(ifname, i, eui);
#endif
if(rc < 0) if(rc < 0)
continue; continue;
memcpy(myid, eui, 8); memcpy(myid, eui, 8);
......
...@@ -348,7 +348,11 @@ parse_filter(gnc_t gnc, void *closure) ...@@ -348,7 +348,11 @@ parse_filter(gnc_t gnc, void *closure)
if(c < -1) if(c < -1)
goto error; goto error;
filter->ifname = interface; filter->ifname = interface;
#if defined (_WIN32_WINNT)
filter->ifindex = if_nametoindex(cyginet_guidname(interface));
#else
filter->ifindex = if_nametoindex(interface); filter->ifindex = if_nametoindex(interface);
#endif
} else if(strcmp(token, "allow") == 0) { } else if(strcmp(token, "allow") == 0) {
filter->result = 0; filter->result = 0;
} else if(strcmp(token, "deny") == 0) { } else if(strcmp(token, "deny") == 0) {
...@@ -644,7 +648,11 @@ renumber_filter(struct filter *filter) ...@@ -644,7 +648,11 @@ renumber_filter(struct filter *filter)
{ {
while(filter) { while(filter) {
if(filter->ifname) if(filter->ifname)
#if defined (_WIN32_WINNT)
filter->ifindex = if_nametoindex(cyginet_guidname(filter->ifname));
#else
filter->ifindex = if_nametoindex(filter->ifname); filter->ifindex = if_nametoindex(filter->ifname);
#endif
filter = filter->next; filter = filter->next;
} }
} }
......
...@@ -37,13 +37,25 @@ ...@@ -37,13 +37,25 @@
#include <unistd.h> #include <unistd.h>
#include <wchar.h> #include <wchar.h>
#define INSIDE_CYGINET #define INSIDE_BABELD_CYGINET
#include "cyginet.h" #include "cyginet.h"
#undef INSIDE_CYGINET #undef INSIDE_BABELD_CYGINET
#if defined (TEST_CYGINET)
#define kdebugf printf
#else
void do_debugf(int level, const char *format, ...);
#define kdebugf(_args...) \
do { \
do_debugf(3, _args); \
} while(0)
#endif
static HRESULT (WINAPI *ws_guidfromstring)(LPCTSTR psz, LPGUID pguid) = NULL; static HRESULT (WINAPI *ws_guidfromstring)(LPCTSTR psz, LPGUID pguid) = NULL;
static HANDLE event_notify_monitor_thread = WSA_INVALID_EVENT; static HANDLE event_notify_monitor_thread = WSA_INVALID_EVENT;
static PLIBWINET_INTERFACE_MAP_TABLE interface_map_table = NULL;
static void static void
plen2mask(int n, struct in_addr *dest) plen2mask(int n, struct in_addr *dest)
{ {
...@@ -93,10 +105,131 @@ mask2len(const unsigned char *p, const int size) ...@@ -93,10 +105,131 @@ mask2len(const unsigned char *p, const int size)
return i; return i;
} }
static void
libwinet_free_interface_map_table()
{
PLIBWINET_INTERFACE_MAP_TABLE p = interface_map_table;
PLIBWINET_INTERFACE_MAP_TABLE s;
while (p) {
if ( p -> AdapterName )
FREE(p -> AdapterName);
if (p -> FriendlyName)
FREE(p -> FriendlyName);
s = p;
p = p -> next;
FREE(s);
}
interface_map_table = NULL;
}
static int
libwinet_refresh_interface_map_table()
{
IP_ADAPTER_ADDRESSES *pAdaptAddr = NULL;
IP_ADAPTER_ADDRESSES *pTmpAdaptAddr = NULL;
DWORD dwRet = 0;
DWORD dwSize = 0x10000;
dwRet = GetAdaptersAddresses(AF_UNSPEC,
GAA_FLAG_SKIP_UNICAST \
| GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \
| GAA_FLAG_SKIP_DNS_SERVER,
NULL,
pAdaptAddr,
&dwSize
);
if (ERROR_BUFFER_OVERFLOW == dwRet) {
FREE(pAdaptAddr);
if (NULL == (pAdaptAddr = (IP_ADAPTER_ADDRESSES*)MALLOC(dwSize)))
return 0;
dwRet = GetAdaptersAddresses(AF_UNSPEC,
GAA_FLAG_SKIP_UNICAST \
| GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \
| GAA_FLAG_SKIP_DNS_SERVER,
NULL,
pAdaptAddr,
&dwSize
);
}
if (NO_ERROR == dwRet) {
if (interface_map_table)
libwinet_free_interface_map_table();
PLIBWINET_INTERFACE_MAP_TABLE p;
size_t len;
interface_map_table = NULL;
pTmpAdaptAddr = pAdaptAddr;
while (pTmpAdaptAddr) {
p = MALLOC(sizeof(LIBWINET_INTERFACE_MAP_TABLE));
if (!p) {
dwRet = ERROR_BUFFER_OVERFLOW;
break;
}
p -> next = interface_map_table;
len = WideCharToMultiByte(CP_ACP,
0,
pTmpAdaptAddr -> FriendlyName,
-1,
NULL,
0,
NULL,
NULL
);
p -> FriendlyName = MALLOC(len + 1);
if (!p -> FriendlyName) {
dwRet = ERROR_BUFFER_OVERFLOW;
break;
}
if (WideCharToMultiByte(CP_ACP,
0,
pTmpAdaptAddr -> FriendlyName,
-1,
p -> FriendlyName,
len,
NULL,
NULL
) == 0) {
dwRet = ERROR_BUFFER_OVERFLOW;
break;
}
len = strlen(pTmpAdaptAddr -> AdapterName);
p -> AdapterName = MALLOC(len + 1);
if (!p -> AdapterName) {
dwRet = ERROR_BUFFER_OVERFLOW;
break;
}
memcpy(p -> AdapterName, pTmpAdaptAddr -> AdapterName, len);
*(p -> AdapterName + len) = 0;
p -> IfType = pTmpAdaptAddr -> IfType;
p -> PhysicalAddressLength = pTmpAdaptAddr -> PhysicalAddressLength;
memcpy(p -> PhysicalAddress,
pTmpAdaptAddr -> PhysicalAddress,
p -> PhysicalAddressLength
);
pTmpAdaptAddr = pTmpAdaptAddr->Next;
interface_map_table = p;
}
if (ERROR_BUFFER_OVERFLOW == dwRet)
libwinet_free_interface_map_table();
}
FREE(pAdaptAddr);
return (NO_ERROR == dwRet);
}
static int static int
libwinet_get_interface_info(const char *ifname, libwinet_get_interface_info(const char *ifname,
int family,
int ifindex,
PLIBWINET_INTERFACE pinfo) PLIBWINET_INTERFACE pinfo)
{ {
IP_ADAPTER_ADDRESSES *pAdaptAddr = NULL; IP_ADAPTER_ADDRESSES *pAdaptAddr = NULL;
...@@ -104,12 +237,37 @@ libwinet_get_interface_info(const char *ifname, ...@@ -104,12 +237,37 @@ libwinet_get_interface_info(const char *ifname,
DWORD dwRet = 0; DWORD dwRet = 0;
DWORD dwSize = 0x10000; DWORD dwSize = 0x10000;
DWORD dwReturn = 0; DWORD dwReturn = 0;
ULONG family = AF_UNSPEC;
WCHAR *friendlyname;
size_t size;
size = MultiByteToWideChar(CP_ACP,
0,
ifname,
-1,
NULL,
0
);
friendlyname = MALLOC(size * sizeof(WCHAR));
if (!friendlyname)
return -1;
if (MultiByteToWideChar(CP_ACP,
0,
ifname,
-1,
friendlyname,
size
) == 0) {
FREE(friendlyname);
return -1;
}
dwRet = GetAdaptersAddresses(family, dwRet = GetAdaptersAddresses(family,
GAA_FLAG_SKIP_ANYCAST \ GAA_FLAG_SKIP_UNICAST \
| GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \ | GAA_FLAG_SKIP_MULTICAST \
| GAA_FLAG_SKIP_DNS_SERVER \ | GAA_FLAG_SKIP_DNS_SERVER,
| GAA_FLAG_SKIP_FRIENDLY_NAME,
NULL, NULL,
pAdaptAddr, pAdaptAddr,
&dwSize &dwSize
...@@ -119,10 +277,10 @@ libwinet_get_interface_info(const char *ifname, ...@@ -119,10 +277,10 @@ libwinet_get_interface_info(const char *ifname,
if (NULL == (pAdaptAddr = (IP_ADAPTER_ADDRESSES*)MALLOC(dwSize))) if (NULL == (pAdaptAddr = (IP_ADAPTER_ADDRESSES*)MALLOC(dwSize)))
return -1; return -1;
dwRet = GetAdaptersAddresses(family, dwRet = GetAdaptersAddresses(family,
GAA_FLAG_SKIP_ANYCAST \ GAA_FLAG_SKIP_UNICAST \
| GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \ | GAA_FLAG_SKIP_MULTICAST \
| GAA_FLAG_SKIP_DNS_SERVER \ | GAA_FLAG_SKIP_DNS_SERVER,
| GAA_FLAG_SKIP_FRIENDLY_NAME,
NULL, NULL,
pAdaptAddr, pAdaptAddr,
&dwSize &dwSize
...@@ -133,14 +291,7 @@ libwinet_get_interface_info(const char *ifname, ...@@ -133,14 +291,7 @@ libwinet_get_interface_info(const char *ifname,
pTmpAdaptAddr = pAdaptAddr; pTmpAdaptAddr = pAdaptAddr;
while (pTmpAdaptAddr) { while (pTmpAdaptAddr) {
/* For ipv4, two contidions: if (wcscmp(friendlyname, pTmpAdaptAddr -> FriendlyName) == 0) {
AdapterName equals ifname and IfIndex is nonzero.
For ipv6, only judge Ipv6IfIndex
*/
if (family == AF_INET6 ? pTmpAdaptAddr -> Ipv6IfIndex == ifindex \
: (pTmpAdaptAddr -> IfIndex != 0) \
&& (strcmp(ifname, pTmpAdaptAddr -> AdapterName) == 0)
) {
memset(pinfo, 0, sizeof(pinfo)); memset(pinfo, 0, sizeof(pinfo));
pinfo -> IfType = pTmpAdaptAddr -> IfType; pinfo -> IfType = pTmpAdaptAddr -> IfType;
pinfo -> Mtu = pTmpAdaptAddr -> Mtu; pinfo -> Mtu = pTmpAdaptAddr -> Mtu;
...@@ -158,9 +309,9 @@ libwinet_get_interface_info(const char *ifname, ...@@ -158,9 +309,9 @@ libwinet_get_interface_info(const char *ifname,
pTmpAdaptAddr = pTmpAdaptAddr->Next; pTmpAdaptAddr = pTmpAdaptAddr->Next;
} }
FREE(pAdaptAddr);
} }
FREE(pAdaptAddr);
return dwReturn; return dwReturn;
} }
...@@ -168,7 +319,7 @@ static int ...@@ -168,7 +319,7 @@ static int
libwinet_run_command(const char *command) libwinet_run_command(const char *command)
{ {
FILE *output; FILE *output;
kdebugf("libwinet_run_command: %s\n", command);
output = popen (command, "r"); output = popen (command, "r");
if (!output) if (!output)
return -1; return -1;
...@@ -325,7 +476,7 @@ libwinet_is_wireless_interface(const char *ifname) ...@@ -325,7 +476,7 @@ libwinet_is_wireless_interface(const char *ifname)
if (NULL == ws_guidfromstring) if (NULL == ws_guidfromstring)
return -1; return -1;
if (!(*ws_guidfromstring)(ifname, &ifguid)) if (!(*ws_guidfromstring)(cyginet_guidname(ifname), &ifguid))
return -1; return -1;
/* variables used for WlanEnumInterfaces */ /* variables used for WlanEnumInterfaces */
...@@ -581,7 +732,6 @@ libwinet_edit_route_entry(const struct sockaddr *dest, ...@@ -581,7 +732,6 @@ libwinet_edit_route_entry(const struct sockaddr *dest,
unsigned int metric, unsigned int metric,
int cmdflag) int cmdflag)
{ {
#if _WIN32_WINNT < _WIN32_WINNT_VISTA #if _WIN32_WINNT < _WIN32_WINNT_VISTA
/* Add ipv6 route before Windows Vista */ /* Add ipv6 route before Windows Vista */
...@@ -841,14 +991,17 @@ libwinet_get_loopback_index(int family) ...@@ -841,14 +991,17 @@ libwinet_get_loopback_index(int family)
dwReturn = family == AF_INET ? dwReturn = family == AF_INET ?
pTmpAdaptAddr -> IfIndex : pTmpAdaptAddr -> IfIndex :
pTmpAdaptAddr -> Ipv6IfIndex; pTmpAdaptAddr -> Ipv6IfIndex;
/* Loopback interface doesn't support both of Ipv4 or Ipv6 */
if (dwReturn)
break; break;
} }
pTmpAdaptAddr = pTmpAdaptAddr->Next; pTmpAdaptAddr = pTmpAdaptAddr->Next;
} }
}
FREE(pAdaptAddr); FREE(pAdaptAddr);
}
return dwReturn; return dwReturn;
} }
...@@ -890,7 +1043,7 @@ int cyginet_interface_wireless(const char *ifname, int ifindex) ...@@ -890,7 +1043,7 @@ int cyginet_interface_wireless(const char *ifname, int ifindex)
{ {
LIBWINET_INTERFACE winf; LIBWINET_INTERFACE winf;
if (1 == libwinet_get_interface_info(ifname, AF_INET6, ifindex, &winf)) { if (1 == libwinet_get_interface_info(ifname, &winf)) {
if (IF_TYPE_IEEE80211 == winf.IfType) if (IF_TYPE_IEEE80211 == winf.IfType)
return 1; return 1;
...@@ -911,7 +1064,7 @@ cyginet_interface_mtu(const char *ifname, int ifindex) ...@@ -911,7 +1064,7 @@ cyginet_interface_mtu(const char *ifname, int ifindex)
{ {
LIBWINET_INTERFACE winf; LIBWINET_INTERFACE winf;
if (1 == libwinet_get_interface_info(ifname, AF_INET6, ifindex, &winf)) if (1 == libwinet_get_interface_info(ifname, &winf))
return winf.Mtu; return winf.Mtu;
return -1; return -1;
...@@ -921,11 +1074,20 @@ int ...@@ -921,11 +1074,20 @@ int
cyginet_interface_operational(const char *ifname, int ifindex) cyginet_interface_operational(const char *ifname, int ifindex)
{ {
LIBWINET_INTERFACE winf; LIBWINET_INTERFACE winf;
int rc = -1;
if (1 == libwinet_get_interface_info(ifname, AF_INET6, ifindex, &winf)) if (1 == libwinet_get_interface_info(ifname, &winf)) {
return winf.OperStatus; switch (winf.OperStatus) {
case IfOperStatusUp:
return -1; rc = IFF_UP;
break;
case IfOperStatusDormant:
rc = IFF_RUNNING;
break;
default:
rc = 0;
}
}
return rc;
} }
int int
...@@ -933,14 +1095,83 @@ cyginet_interface_ipv4(const char *ifname, ...@@ -933,14 +1095,83 @@ cyginet_interface_ipv4(const char *ifname,
int ifindex, int ifindex,
unsigned char *addr_r) unsigned char *addr_r)
{ {
LIBWINET_INTERFACE winf; IP_ADAPTER_ADDRESSES *pAdaptAddr = NULL;
IP_ADAPTER_ADDRESSES *pTmpAdaptAddr = NULL;
DWORD dwRet = 0;
DWORD dwSize = 0x10000;
DWORD dwReturn = 0;
ULONG family = AF_INET;
if (1 == libwinet_get_interface_info(ifname, AF_INET, ifindex, &winf)) { WCHAR *friendlyname;
size_t size;
memcpy(addr_r, &((struct sockaddr_in*)&winf.Address)->sin_addr, 4); size = MultiByteToWideChar(CP_ACP,
return 1; 0,
ifname,
-1,
NULL,
0
);
friendlyname = MALLOC(size * sizeof(WCHAR));
if (!friendlyname)
return -1;
if (MultiByteToWideChar(CP_ACP,
0,
ifname,
-1,
friendlyname,
size
) == 0) {
FREE(friendlyname);
return -1;
} }
dwRet = GetAdaptersAddresses(family,
GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \
| GAA_FLAG_SKIP_DNS_SERVER,
NULL,
pAdaptAddr,
&dwSize
);
if (ERROR_BUFFER_OVERFLOW == dwRet) {
FREE(pAdaptAddr);
if (NULL == (pAdaptAddr = (IP_ADAPTER_ADDRESSES*)MALLOC(dwSize)))
return -1; return -1;
dwRet = GetAdaptersAddresses(family,
GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \
| GAA_FLAG_SKIP_DNS_SERVER,
NULL,
pAdaptAddr,
&dwSize
);
}
if (NO_ERROR == dwRet) {
pTmpAdaptAddr = pAdaptAddr;
while (pTmpAdaptAddr) {
if (wcscmp(friendlyname, pTmpAdaptAddr -> FriendlyName) == 0) {
/* Copy first unicast address */
if (pTmpAdaptAddr -> FirstUnicastAddress) {
SOCKADDR *s;
s = (pTmpAdaptAddr -> FirstUnicastAddress -> Address).lpSockaddr;
memcpy(addr_r, &(((struct sockaddr_in *)s) -> sin_addr), 4);
dwReturn = 1;
if (pTmpAdaptAddr->FirstUnicastAddress->Next)
fprintf(stderr,
"Warning: more than one ipv4 address configured"
"in the interface '%s', but only the first one returned\n",
ifname
);
break;
}
}
pTmpAdaptAddr = pTmpAdaptAddr->Next;
}
FREE(pAdaptAddr);
}
return dwReturn;
} }
int int
...@@ -951,32 +1182,49 @@ cyginet_interface_sdl(struct sockaddr_dl *sdl, char *ifname) ...@@ -951,32 +1182,49 @@ cyginet_interface_sdl(struct sockaddr_dl *sdl, char *ifname)
DWORD dwRet = 0; DWORD dwRet = 0;
DWORD dwSize = 0x10000; DWORD dwSize = 0x10000;
DWORD dwReturn = -1; DWORD dwReturn = -1;
DWORD dwFamily = AF_UNSPEC; DWORD dwFamily = AF_INET6;
size_t size; size_t size;
WCHAR *friendlyname;
int ifindex; size = MultiByteToWideChar(CP_ACP,
0,
if (0 == (ifindex = if_nametoindex(ifname))) ifname,
-1,
NULL,
0
);
friendlyname = MALLOC(size * sizeof(WCHAR));
if (!friendlyname)
return -1; return -1;
if (MultiByteToWideChar(CP_ACP,
0,
ifname,
-1,
friendlyname,
size
) == 0) {
FREE(friendlyname);
return -1;
}
dwRet = GetAdaptersAddresses(dwFamily, dwRet = GetAdaptersAddresses(dwFamily,
GAA_FLAG_SKIP_ANYCAST \ GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \ | GAA_FLAG_SKIP_MULTICAST \
| GAA_FLAG_SKIP_DNS_SERVER \ | GAA_FLAG_SKIP_DNS_SERVER,
| GAA_FLAG_SKIP_FRIENDLY_NAME,
NULL, NULL,
pAdaptAddr, pAdaptAddr,
&dwSize &dwSize
); );
if (ERROR_BUFFER_OVERFLOW == dwRet) { if (ERROR_BUFFER_OVERFLOW == dwRet) {
FREE(pAdaptAddr); FREE(pAdaptAddr);
if (NULL == (pAdaptAddr = (IP_ADAPTER_ADDRESSES*)MALLOC(dwSize))) if (NULL == (pAdaptAddr = (IP_ADAPTER_ADDRESSES*)MALLOC(dwSize))){
FREE(friendlyname);
return -1; return -1;
}
dwRet = GetAdaptersAddresses(dwFamily, dwRet = GetAdaptersAddresses(dwFamily,
GAA_FLAG_SKIP_ANYCAST \ GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \ | GAA_FLAG_SKIP_MULTICAST \
| GAA_FLAG_SKIP_DNS_SERVER \ | GAA_FLAG_SKIP_DNS_SERVER,
| GAA_FLAG_SKIP_FRIENDLY_NAME,
NULL, NULL,
pAdaptAddr, pAdaptAddr,
&dwSize &dwSize
...@@ -988,7 +1236,7 @@ cyginet_interface_sdl(struct sockaddr_dl *sdl, char *ifname) ...@@ -988,7 +1236,7 @@ cyginet_interface_sdl(struct sockaddr_dl *sdl, char *ifname)
while (pTmpAdaptAddr) { while (pTmpAdaptAddr) {
if (pTmpAdaptAddr -> Ipv6IfIndex == ifindex) { if (wcscmp(pTmpAdaptAddr -> FriendlyName, friendlyname) == 0) {
size = strlen(ifname); size = strlen(ifname);
sdl -> sdl_family = 0; sdl -> sdl_family = 0;
sdl -> sdl_index = pTmpAdaptAddr -> Ipv6IfIndex; sdl -> sdl_index = pTmpAdaptAddr -> Ipv6IfIndex;
...@@ -1010,16 +1258,18 @@ cyginet_interface_sdl(struct sockaddr_dl *sdl, char *ifname) ...@@ -1010,16 +1258,18 @@ cyginet_interface_sdl(struct sockaddr_dl *sdl, char *ifname)
pTmpAdaptAddr = pTmpAdaptAddr->Next; pTmpAdaptAddr = pTmpAdaptAddr->Next;
} }
FREE(pAdaptAddr);
} }
FREE(pAdaptAddr); FREE(friendlyname);
return dwReturn; return dwReturn;
} }
/* In the windows, loopback interface index is alawys 1 */
int int
cyginet_loopback_index(int family) cyginet_loopback_index(int family)
{ {
return libwinet_get_loopback_index(family); return 1;
} }
/* /*
...@@ -1090,7 +1340,7 @@ cyginet_dump_route_table(struct cyginet_route *routes, int maxroutes) ...@@ -1090,7 +1340,7 @@ cyginet_dump_route_table(struct cyginet_route *routes, int maxroutes)
for (i = 0; for (i = 0;
i < (int) pIpForwardTable->dwNumEntries; i < (int) pIpForwardTable->dwNumEntries;
i++, proute ++, pRow ++) { i++, proute ++, pRow ++) {
/* libwinet_map_ifindex_to_ipv6ifindex */ /* Here the ifindex is the index of ipv4 interface */
proute -> ifindex = pRow -> dwForwardIfIndex; proute -> ifindex = pRow -> dwForwardIfIndex;
proute -> metric = pRow -> dwForwardMetric1; proute -> metric = pRow -> dwForwardMetric1;
proute -> proto = pRow -> dwForwardProto; proute -> proto = pRow -> dwForwardProto;
...@@ -1191,7 +1441,8 @@ cyginet_read_route_socket(void *buffer, size_t size) ...@@ -1191,7 +1441,8 @@ cyginet_read_route_socket(void *buffer, size_t size)
return 0; return 0;
} }
int cyginet_startup() int
cyginet_startup()
{ {
WORD wVersionRequested; WORD wVersionRequested;
WSADATA wsaData; WSADATA wsaData;
...@@ -1201,11 +1452,44 @@ int cyginet_startup() ...@@ -1201,11 +1452,44 @@ int cyginet_startup()
return WSAStartup(wVersionRequested, &wsaData); return WSAStartup(wVersionRequested, &wsaData);
} }
void cyginet_cleanup() void
cyginet_cleanup()
{ {
WSACleanup(); WSACleanup();
} }
char *
cyginet_guidname(const char * ifname)
{
PLIBWINET_INTERFACE_MAP_TABLE p;
if (!interface_map_table)
libwinet_refresh_interface_map_table();
p = interface_map_table;
while (p) {
if (strcmp(ifname, p -> FriendlyName) == 0)
return p -> AdapterName;
p = p -> next;
}
return NULL;
}
char *
cyginet_ifname(const char * guidname)
{
PLIBWINET_INTERFACE_MAP_TABLE p;
if (!interface_map_table)
libwinet_refresh_interface_map_table();
p = interface_map_table;
while (p) {
if (strcmp(guidname, p -> AdapterName) == 0)
return p -> FriendlyName;
p = p -> next;
}
return NULL;
}
/* The following functions are reserved. */ /* The following functions are reserved. */
#if 0 #if 0
...@@ -1524,9 +1808,10 @@ libwinet_map_ifindex_to_ipv6ifindex(int ifindex) ...@@ -1524,9 +1808,10 @@ libwinet_map_ifindex_to_ipv6ifindex(int ifindex)
pTmpAdaptAddr = pTmpAdaptAddr->Next; pTmpAdaptAddr = pTmpAdaptAddr->Next;
} }
}
FREE(pAdaptAddr); FREE(pAdaptAddr);
}
return dwReturn; return dwReturn;
} }
...@@ -1830,68 +2115,10 @@ DWORD GetInterfaceIndexForAddress(SOCKADDR *pAddr) ...@@ -1830,68 +2115,10 @@ DWORD GetInterfaceIndexForAddress(SOCKADDR *pAddr)
} }
}
FREE(pAdaptAddr); FREE(pAdaptAddr);
return dwReturn;
}
VOID PrintAllInterfaces()
{
IP_ADAPTER_ADDRESSES *pAdaptAddr = NULL;
IP_ADAPTER_ADDRESSES *pTmpAdaptAddr = NULL;
DWORD dwRet = 0;
DWORD dwSize = 0x10000;
DWORD Family = AF_UNSPEC;
if (NULL == (pAdaptAddr = (IP_ADAPTER_ADDRESSES*)MALLOC(dwSize))) {
printf("Memory error.\n");
return ;
}
dwRet = GetAdaptersAddresses(Family,
GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \
|GAA_FLAG_SKIP_DNS_SERVER,
NULL,
pAdaptAddr,
&dwSize
);
if (ERROR_BUFFER_OVERFLOW == dwRet) {
FREE(pAdaptAddr);
if (NULL == (pAdaptAddr = (IP_ADAPTER_ADDRESSES*)MALLOC(dwSize))) {
printf("Memory error.\n");
return ;
}
dwRet = GetAdaptersAddresses(Family,
GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \
|GAA_FLAG_SKIP_DNS_SERVER,
NULL,
pAdaptAddr,
&dwSize
);
}
if (NO_ERROR == dwRet) {
pTmpAdaptAddr = pAdaptAddr;
while (pTmpAdaptAddr) {
printf("If6Index:\t %ld\n", pTmpAdaptAddr -> Ipv6IfIndex);
printf("If4Index:\t %ld\n", pTmpAdaptAddr -> IfIndex);
printf("Friendly Name:\t %S\n", pTmpAdaptAddr -> FriendlyName);
printf("Adapter Name:\t %s\n", pTmpAdaptAddr -> AdapterName);
printf("IfType:\t %ld\n", pTmpAdaptAddr -> IfType);
printf("Oper Status:\t %d\n", pTmpAdaptAddr -> OperStatus);
printf("\n\n");
pTmpAdaptAddr = pTmpAdaptAddr->Next;
} }
}
else
printf("GetAdaptersAddresses failed.\n");
FREE(pAdaptAddr); return dwReturn;
} }
void WaitForNetworkChnages() void WaitForNetworkChnages()
...@@ -1956,6 +2183,64 @@ DWORD GetConnectedNetworks() ...@@ -1956,6 +2183,64 @@ DWORD GetConnectedNetworks()
/* ------------------------------------------------------------- */ /* ------------------------------------------------------------- */
#ifdef TEST_CYGINET #ifdef TEST_CYGINET
VOID PrintAllInterfaces()
{
IP_ADAPTER_ADDRESSES *pAdaptAddr = NULL;
IP_ADAPTER_ADDRESSES *pTmpAdaptAddr = NULL;
DWORD dwRet = 0;
DWORD dwSize = 0x10000;
DWORD Family = AF_UNSPEC;
if (NULL == (pAdaptAddr = (IP_ADAPTER_ADDRESSES*)MALLOC(dwSize))) {
printf("Memory error.\n");
return ;
}
dwRet = GetAdaptersAddresses(Family,
GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \
|GAA_FLAG_SKIP_DNS_SERVER,
NULL,
pAdaptAddr,
&dwSize
);
if (ERROR_BUFFER_OVERFLOW == dwRet) {
FREE(pAdaptAddr);
if (NULL == (pAdaptAddr = (IP_ADAPTER_ADDRESSES*)MALLOC(dwSize))) {
printf("Memory error.\n");
return ;
}
dwRet = GetAdaptersAddresses(Family,
GAA_FLAG_SKIP_ANYCAST \
| GAA_FLAG_SKIP_MULTICAST \
|GAA_FLAG_SKIP_DNS_SERVER,
NULL,
pAdaptAddr,
&dwSize
);
}
if (NO_ERROR == dwRet) {
pTmpAdaptAddr = pAdaptAddr;
while (pTmpAdaptAddr) {
printf("If6Index:\t %ld\n", pTmpAdaptAddr -> Ipv6IfIndex);
printf("If4Index:\t %ld\n", pTmpAdaptAddr -> IfIndex);
printf("Friendly Name:\t %S\n", pTmpAdaptAddr -> FriendlyName);
printf("Adapter Name:\t %s\n", pTmpAdaptAddr -> AdapterName);
printf("IfType:\t %ld\n", pTmpAdaptAddr -> IfType);
printf("Oper Status:\t %d\n", pTmpAdaptAddr -> OperStatus);
printf("\n\n");
pTmpAdaptAddr = pTmpAdaptAddr->Next;
}
}
else
printf("GetAdaptersAddresses failed.\n");
FREE(pAdaptAddr);
}
static void static void
runTestCases() runTestCases()
{ {
...@@ -1990,6 +2275,31 @@ runTestCases() ...@@ -1990,6 +2275,31 @@ runTestCases()
printf("if_indextoname failed\n"); printf("if_indextoname failed\n");
} }
printf("\n\nTest cyginet_ifname works in the Cygwin:\n\n");
{
struct if_nameindex * ptr = (struct if_nameindex *)if_nameindex();
if (ptr) {
struct if_nameindex * p = ptr;
while (p -> if_index) {
printf("%s:\t\t%s\n", p -> if_name, cyginet_ifname(p -> if_name));
p ++;
}
if_freenameindex(ptr);
}
}
printf("\n\nTest cyginet_guidname works in the Cygwin:\n\n");
{
PLIBWINET_INTERFACE_MAP_TABLE p = interface_map_table;
while (p) {
printf("%s:\t\t%s\n",
p -> FriendlyName,
cyginet_guidname(p -> FriendlyName)
);
p = p -> next;
}
}
#if _WIN32_WINNT < _WIN32_WINNT_VISTA #if _WIN32_WINNT < _WIN32_WINNT_VISTA
printf("\n\nTest libwinet_dump_ipv6_route_table:\n\n"); printf("\n\nTest libwinet_dump_ipv6_route_table:\n\n");
...@@ -2007,17 +2317,13 @@ runTestCases() ...@@ -2007,17 +2317,13 @@ runTestCases()
printf("\n\nTest libwinet_is_wireless_interface:\n\n"); printf("\n\nTest libwinet_is_wireless_interface:\n\n");
{ {
struct if_nameindex * ptr = (struct if_nameindex *)if_nameindex(); PLIBWINET_INTERFACE_MAP_TABLE p = interface_map_table;
if (ptr) { while (p) {
struct if_nameindex * p = ptr;
while (p -> if_index) {
printf("%s is wireless netcard: %d\n", printf("%s is wireless netcard: %d\n",
p -> if_name, p -> FriendlyName,
libwinet_is_wireless_interface(p -> if_name) libwinet_is_wireless_interface(p -> FriendlyName)
); );
p ++; p = p -> next;
}
if_freenameindex(ptr);
} }
} }
...@@ -2055,88 +2361,65 @@ runTestCases() ...@@ -2055,88 +2361,65 @@ runTestCases()
printf("\n\nTest cyginet_interface_wireless:\n\n"); printf("\n\nTest cyginet_interface_wireless:\n\n");
{ {
struct if_nameindex * ptr = (struct if_nameindex *)if_nameindex();
if (ptr) {
struct if_nameindex * p = ptr;
int n; int n;
while (p -> if_index) { PLIBWINET_INTERFACE_MAP_TABLE p = interface_map_table;
n = cyginet_interface_wireless(p -> if_name, p -> if_index); while (p) {
printf("%s is wireless netcard: %d\n", p -> if_name, n); n = cyginet_interface_wireless(p -> FriendlyName, 1);
p ++; printf("%s is wireless netcard: %d\n", p -> FriendlyName, n);
} p = p -> next;
if_freenameindex(ptr);
} }
} }
printf("\n\nTest cyginet_interface_mtu:\n\n"); printf("\n\nTest cyginet_interface_mtu:\n\n");
{ {
struct if_nameindex * ptr = (struct if_nameindex *)if_nameindex();
if (ptr) {
struct if_nameindex * p = ptr;
int n; int n;
while (p -> if_index) { PLIBWINET_INTERFACE_MAP_TABLE p = interface_map_table;
n = cyginet_interface_mtu(p -> if_name, p -> if_index); while (p) {
printf("mtu of %s is : %d\n", p -> if_name, n); n = cyginet_interface_mtu(p -> FriendlyName, 1);
p ++; printf("mtu of %s is : %d\n", p -> FriendlyName, n);
} p = p -> next;
if_freenameindex(ptr);
} }
} }
printf("\n\nTest cyginet_interface_operational:\n\n"); printf("\n\nTest cyginet_interface_operational:\n\n");
{ {
struct if_nameindex * ptr = (struct if_nameindex *)if_nameindex();
if (ptr) {
struct if_nameindex * p = ptr;
int n; int n;
while (p -> if_index) { PLIBWINET_INTERFACE_MAP_TABLE p = interface_map_table;
n = cyginet_interface_operational(p -> if_name, p -> if_index); while (p) {
printf("%s is up: %d\n", p -> if_name, n); n = cyginet_interface_operational(p -> FriendlyName, 1);
p ++; printf("%s is up: %d\n", p -> FriendlyName, n);
} p = p -> next;
if_freenameindex(ptr);
} }
} }
printf("\n\nTest cyginet_interface_ipv4:\n\n"); printf("\n\nTest cyginet_interface_ipv4:\n\n");
{ {
struct sockaddr_in sa; struct sockaddr_in sa;
struct if_nameindex * ptr = (struct if_nameindex *)if_nameindex();
if (ptr) {
struct if_nameindex * p = ptr;
int n; int n;
while (p -> if_index) { PLIBWINET_INTERFACE_MAP_TABLE p = interface_map_table;
while (p) {
memset(&sa, 0, sizeof(sa)); memset(&sa, 0, sizeof(sa));
n = cyginet_interface_ipv4(p -> if_name, n = cyginet_interface_ipv4(p -> FriendlyName, 1, (unsigned char*)&sa);
p -> if_index, printf("get ipv4 from %s: %d\n", p -> FriendlyName, n);
(unsigned char*)&sa p = p -> next;
);
printf("get ipv4 from %s: %d\n", p -> if_name, n);
p ++;
}
if_freenameindex(ptr);
} }
} }
printf("\n\nTest cyginet_interface_sdl:\n\n"); printf("\n\nTest cyginet_interface_sdl:\n\n");
{ {
struct sockaddr_dl sdl;
struct if_nameindex * ptr = (struct if_nameindex *)if_nameindex();
if (ptr) {
struct if_nameindex * p = ptr;
int n; int n;
while (p -> if_index) { struct sockaddr_dl sdl;
PLIBWINET_INTERFACE_MAP_TABLE p = interface_map_table;
while (p) {
memset(&sdl, 0, sizeof(struct sockaddr_dl)); memset(&sdl, 0, sizeof(struct sockaddr_dl));
n = cyginet_interface_sdl(&sdl, p -> if_name); n = cyginet_interface_sdl(&sdl, p -> FriendlyName);
printf("get sdl from %s: %d\n", p -> if_name, n); printf("get sdl from %s: %d\n", p -> FriendlyName, n);
if (0 == n) { if (0 == n) {
printf("sdl_len is %d\n", sdl.sdl_len); printf("sdl_len is %d\n", sdl.sdl_len);
printf("sdl_nlen is %d\n", sdl.sdl_nlen); printf("sdl_nlen is %d\n", sdl.sdl_nlen);
printf("sdl_alen is %d\n", sdl.sdl_alen); printf("sdl_alen is %d\n", sdl.sdl_alen);
} }
p ++; p = p -> next;
}
if_freenameindex(ptr);
} }
} }
...@@ -2343,11 +2626,30 @@ int main(int argc, char* argv[]) ...@@ -2343,11 +2626,30 @@ int main(int argc, char* argv[])
else else
printf("The Winsock 2.2 dll was found okay\n"); printf("The Winsock 2.2 dll was found okay\n");
/* PrintAllInterfaces(); */
printf("\n\nTest libwinet_refresh_interface_map_table:\n\n");
{
if (libwinet_refresh_interface_map_table()) {
PLIBWINET_INTERFACE_MAP_TABLE p = interface_map_table;
while (p) {
printf("Friendly Name:\t %s\n", p -> FriendlyName);
printf("Adapter Name:\t %s\n", p -> AdapterName);
printf("IfType:\t %ld\n", p -> IfType);
p = p -> next;
}
}
else
printf("libwinet_refresh_interface_map_table failed\n");
}
runTestCases(); runTestCases();
printf("\n\nTest libwinet_free_interface_map_table:\n\n");
libwinet_free_interface_map_table();
WSACleanup(); WSACleanup();
return 0; return 0;
} }
#endif /* TEST_CYGINET */ #endif /* TEST_CYGINET */
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
#define RTM_CHANGE 0x3 /* Change Metrics or flags */ #define RTM_CHANGE 0x3 /* Change Metrics or flags */
#define RTM_GET 0x4 /* Report Metrics */ #define RTM_GET 0x4 /* Report Metrics */
#define IFF_RUNNING 0x40
/* /*
* Structure of a Link-Level sockaddr: * Structure of a Link-Level sockaddr:
*/ */
...@@ -84,7 +85,7 @@ struct cyginet_route { ...@@ -84,7 +85,7 @@ struct cyginet_route {
struct sockaddr gateway; struct sockaddr gateway;
}; };
#if defined(INSIDE_CYGINET) #if defined(INSIDE_BABELD_CYGINET)
struct ifaddrs { struct ifaddrs {
struct ifaddrs *ifa_next; struct ifaddrs *ifa_next;
...@@ -101,6 +102,15 @@ struct if_nameindex { ...@@ -101,6 +102,15 @@ struct if_nameindex {
char *if_name; char *if_name;
}; };
typedef struct _LIBWINET_INTERFACE_MAP_TABLE {
PCHAR FriendlyName;
PCHAR AdapterName;
BYTE PhysicalAddress[MAX_ADAPTER_ADDRESS_LENGTH];
DWORD PhysicalAddressLength;
DWORD IfType;
VOID *next;
} LIBWINET_INTERFACE_MAP_TABLE, *PLIBWINET_INTERFACE_MAP_TABLE;
typedef struct _LIBWINET_INTERFACE { typedef struct _LIBWINET_INTERFACE {
DWORD IfType; DWORD IfType;
IF_OPER_STATUS OperStatus; IF_OPER_STATUS OperStatus;
...@@ -135,12 +145,15 @@ extern void freeifaddrs(struct ifaddrs *); ...@@ -135,12 +145,15 @@ extern void freeifaddrs(struct ifaddrs *);
); \ ); \
} }
#endif /* INSIDE_CYGINET */ #endif /* INSIDE_BABELD_CYGINET */
/* Export functions from cyginet */ /* Export functions from cyginet */
int cyginet_startup(); int cyginet_startup();
void cyginet_cleanup(); void cyginet_cleanup();
char * cyginet_ifname(const char *);
char * cyginet_guidname(const char *);
int cyginet_start_monitor_route_changes(int); int cyginet_start_monitor_route_changes(int);
int cyginet_stop_monitor_route_changes(); int cyginet_stop_monitor_route_changes();
int cyginet_set_ipv6_forwards(int); int cyginet_set_ipv6_forwards(int);
......
...@@ -409,7 +409,11 @@ check_interfaces(void) ...@@ -409,7 +409,11 @@ check_interfaces(void)
unsigned int ifindex; unsigned int ifindex;
FOR_ALL_INTERFACES(ifp) { FOR_ALL_INTERFACES(ifp) {
#if defined (_WIN32_WINNT)
ifindex = if_nametoindex(cyginet_guidname(ifp->name));
#else
ifindex = if_nametoindex(ifp->name); ifindex = if_nametoindex(ifp->name);
#endif
if(ifindex != ifp->ifindex) { if(ifindex != ifp->ifindex) {
debugf("Noticed ifindex change for %s.\n", ifp->name); debugf("Noticed ifindex change for %s.\n", ifp->name);
ifp->ifindex = 0; ifp->ifindex = 0;
......
...@@ -111,3 +111,8 @@ void set_timeout(struct timeval *timeout, int msecs); ...@@ -111,3 +111,8 @@ void set_timeout(struct timeval *timeout, int msecs);
int interface_up(struct interface *ifp, int up); int interface_up(struct interface *ifp, int up);
int interface_ll_address(struct interface *ifp, const unsigned char *address); int interface_ll_address(struct interface *ifp, const unsigned char *address);
void check_interfaces(void); void check_interfaces(void);
#if defined (_WIN32_WINNT)
char * cyginet_ifname(const char *);
char * cyginet_guidname(const char *);
#endif
...@@ -23,7 +23,11 @@ THE SOFTWARE. ...@@ -23,7 +23,11 @@ THE SOFTWARE.
#include <netinet/in.h> #include <netinet/in.h>
#include "babeld.h" #include "babeld.h"
#if defined (_WIN32_WINNT)
#define KERNEL_INFINITY 9999
#else
#define KERNEL_INFINITY 0xFFFF #define KERNEL_INFINITY 0xFFFF
#endif
struct kernel_route { struct kernel_route {
unsigned char prefix[16]; unsigned char prefix[16];
......
...@@ -28,6 +28,7 @@ THE SOFTWARE. ...@@ -28,6 +28,7 @@ THE SOFTWARE.
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include <time.h> #include <time.h>
#include <assert.h>
#include <strings.h> #include <strings.h>
#include <netinet/in.h> #include <netinet/in.h>
...@@ -58,11 +59,12 @@ THE SOFTWARE. ...@@ -58,11 +59,12 @@ THE SOFTWARE.
* *
* 3. kernel_interface_ipv4 * 3. kernel_interface_ipv4
* *
* ? interface name, ipv4, ifindex, Oh, they're mass. * How to deal with many ipv4 address assigned in one interface,
* now only the first one returned.
* *
*/ */
static int get_sdl(struct sockaddr_dl *sdl, char *ifname); static int get_sdl(struct sockaddr_dl *sdl, char *guidname);
static const unsigned char v4prefix[16] = static const unsigned char v4prefix[16] =
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 }; {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
...@@ -74,6 +76,7 @@ if_eui64(char *ifname, int ifindex, unsigned char *eui) ...@@ -74,6 +76,7 @@ if_eui64(char *ifname, int ifindex, unsigned char *eui)
{ {
struct sockaddr_dl sdl; struct sockaddr_dl sdl;
char *tmp = NULL; char *tmp = NULL;
memset(&sdl, 0, sizeof(struct sockaddr_dl));
if (get_sdl(&sdl, ifname) < 0) { if (get_sdl(&sdl, ifname) < 0) {
return -1; return -1;
} }
...@@ -92,7 +95,7 @@ if_eui64(char *ifname, int ifindex, unsigned char *eui) ...@@ -92,7 +95,7 @@ if_eui64(char *ifname, int ifindex, unsigned char *eui)
return 0; return 0;
} }
/* fill sdl with the structure corresponding to ifname. /* Fill sdl with the structure corresponding to ifname.
Warning: make a syscall (and get all interfaces). Warning: make a syscall (and get all interfaces).
return -1 if an error occurs, 0 otherwise. */ return -1 if an error occurs, 0 otherwise. */
static int static int
...@@ -112,9 +115,7 @@ get_sdl(struct sockaddr_dl *sdl, char *ifname) ...@@ -112,9 +115,7 @@ get_sdl(struct sockaddr_dl *sdl, char *ifname)
static int old_forwarding = -1; static int old_forwarding = -1;
static int old_accept_redirects = -1; static int old_accept_redirects = -1;
static int ifindex_lo = -1; static int ifindex_lo = 1;
static int if6index_lo = -1;
static int kernel_pipe_handles[2]; static int kernel_pipe_handles[2];
int int
...@@ -340,7 +341,7 @@ kernel_interface_channel(const char *ifname, int ifindex) ...@@ -340,7 +341,7 @@ kernel_interface_channel(const char *ifname, int ifindex)
* *
* RTF_CLONING: generate new routes on use * RTF_CLONING: generate new routes on use
* *
* No corresponding function in the Windows. * Not implemented in the Windows.
* *
*/ */
int int
...@@ -412,22 +413,11 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -412,22 +413,11 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
if(metric == KERNEL_INFINITY) { if(metric == KERNEL_INFINITY) {
/* RTF_BLACKHOLE; */ /* RTF_BLACKHOLE; */
/* ==> Set gateway to an unused ip address in the Windows */ /* ==> Set gateway to an unused ip address in the Windows */
if(ipv4) {
if (ifindex_lo < 0) { if (ifindex_lo < 0) {
ifindex_lo = cyginet_loopback_index(AF_INET); ifindex_lo = cyginet_loopback_index(AF_UNSPEC);
if(ifindex_lo <= 0) if(ifindex_lo <= 0)
return -1; return -1;
} }
route_ifindex = ifindex_lo;
}
else {
if (if6index_lo < 0) {
if6index_lo = cyginet_loopback_index(AF_INET6);
if(if6index_lo <= 0)
return -1;
}
route_ifindex = if6index_lo;
}
} }
#define PUSHADDR(dst, src) \ #define PUSHADDR(dst, src) \
...@@ -502,10 +492,11 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen, ...@@ -502,10 +492,11 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
static void static void
print_kernel_route(int add, struct kernel_route *route) print_kernel_route(int add, struct kernel_route *route)
{ {
char ifname[IFNAMSIZ]; char *ifname = NULL;
char guidname[IFNAMSIZ];
if(!if_indextoname(route->ifindex, ifname)) if(if_indextoname(route->ifindex, guidname))
memcpy(ifname,"unk",4); ifname = cyginet_ifname(guidname);
fprintf(stderr, fprintf(stderr,
"%s kernel route: dest: %s gw: %s metric: %d if: %s(%d) \n", "%s kernel route: dest: %s gw: %s metric: %d if: %s(%d) \n",
...@@ -514,7 +505,8 @@ print_kernel_route(int add, struct kernel_route *route) ...@@ -514,7 +505,8 @@ print_kernel_route(int add, struct kernel_route *route)
format_prefix(route->prefix, route->plen), format_prefix(route->prefix, route->plen),
format_address(route->gw), format_address(route->gw),
route->metric, route->metric,
ifname, route->ifindex ifname ? ifname : "unk",
route->ifindex
); );
} }
...@@ -524,17 +516,11 @@ parse_kernel_route(struct cyginet_route *src, struct kernel_route *route) ...@@ -524,17 +516,11 @@ parse_kernel_route(struct cyginet_route *src, struct kernel_route *route)
struct sockaddr *sa; struct sockaddr *sa;
if(ifindex_lo < 0) { if(ifindex_lo < 0) {
ifindex_lo = cyginet_loopback_index(AF_INET); ifindex_lo = cyginet_loopback_index(AF_UNSPEC);
if(ifindex_lo <= 0) if(ifindex_lo <= 0)
return -1; return -1;
} }
if(if6index_lo < 0) {
if6index_lo = cyginet_loopback_index(AF_INET6);
if(if6index_lo <= 0)
return -1;
}
memset(route, 0, sizeof(struct kernel_route)); memset(route, 0, sizeof(struct kernel_route));
route -> plen = src -> plen; route -> plen = src -> plen;
route -> metric = src -> metric; route -> metric = src -> metric;
...@@ -575,9 +561,7 @@ parse_kernel_route(struct cyginet_route *src, struct kernel_route *route) ...@@ -575,9 +561,7 @@ parse_kernel_route(struct cyginet_route *src, struct kernel_route *route)
v4tov6(route->gw, (unsigned char *)&sin->sin_addr); v4tov6(route->gw, (unsigned char *)&sin->sin_addr);
} }
if((sa->sa_family == AF_INET6) && (route->ifindex == if6index_lo)) if(route->ifindex == ifindex_lo)
return -1;
if((sa->sa_family == AF_INET) && (route->ifindex == ifindex_lo))
return -1; return -1;
/* Netmask */ /* Netmask */
...@@ -627,16 +611,30 @@ kernel_routes(struct kernel_route *routes, int maxroutes) ...@@ -627,16 +611,30 @@ kernel_routes(struct kernel_route *routes, int maxroutes)
return count; return count;
} }
/* Note: ifname returned by getifaddrs maybe includes a suffix number,
it looks like:
{C05BAB6E-B82D-4C4D-AF07-EFF7C45C5DB0}_1
{C05BAB6E-B82D-4C4D-AF07-EFF7C45C5DB0}_2
...
*/
static int
compare_ifname(const char * ifapname, const char * ifname)
{
assert(ifname);
char * guidname = cyginet_guidname(ifname);
if (guidname)
return strncmp(guidname, ifapname, strlen(guidname));
return -1;
}
int int
kernel_addresses(char *ifname, int ifindex, int ll, kernel_addresses(char *ifname, int ifindex, int ll,
struct kernel_route *routes, int maxroutes) struct kernel_route *routes, int maxroutes)
{ {
struct ifaddrs *ifa, *ifap; struct ifaddrs *ifa, *ifap;
int rc, i; int rc, i;
/* Two issues:
* 1. ifname maybe includes a suffix number in the cygwin
* 2. Ipv4 IfIndex maybe need to be changed as Ipv6IfIndex
*/
rc = getifaddrs(&ifa); rc = getifaddrs(&ifa);
if(rc < 0) if(rc < 0)
return -1; return -1;
...@@ -644,8 +642,14 @@ kernel_addresses(char *ifname, int ifindex, int ll, ...@@ -644,8 +642,14 @@ kernel_addresses(char *ifname, int ifindex, int ll,
ifap = ifa; ifap = ifa;
i = 0; i = 0;
/* In the Linux, metric is set to 0, but it's invalid in the
Windows, so we set metric to 1 here.
And gateway to be set as 0 in the Linux, as the same reason, we
set it as prefix in the Windows.
*/
while(ifap && i < maxroutes) { while(ifap && i < maxroutes) {
if((ifname != NULL && strcmp(ifap->ifa_name, ifname) != 0)) if((ifname != NULL && compare_ifname(ifap->ifa_name, ifname) != 0))
goto next; goto next;
if(ifap->ifa_addr->sa_family == AF_INET6) { if(ifap->ifa_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ifap->ifa_addr; struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ifap->ifa_addr;
...@@ -658,10 +662,10 @@ kernel_addresses(char *ifname, int ifindex, int ll, ...@@ -658,10 +662,10 @@ kernel_addresses(char *ifname, int ifindex, int ll,
reset those bytes to 0 before passing them to babeld. */ reset those bytes to 0 before passing them to babeld. */
memset(routes[i].prefix + 2, 0, 2); memset(routes[i].prefix + 2, 0, 2);
routes[i].plen = 128; routes[i].plen = 128;
routes[i].metric = 0; routes[i].metric = 1;
routes[i].ifindex = ifindex; routes[i].ifindex = ifindex;
routes[i].proto = RTPROT_BABEL_LOCAL; routes[i].proto = RTPROT_BABEL_LOCAL;
memset(routes[i].gw, 0, 16); memcpy(routes[i].gw, routes[i].prefix, 16);
i++; i++;
} else if(ifap->ifa_addr->sa_family == AF_INET) { } else if(ifap->ifa_addr->sa_family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in*)ifap->ifa_addr; struct sockaddr_in *sin = (struct sockaddr_in*)ifap->ifa_addr;
...@@ -674,10 +678,10 @@ kernel_addresses(char *ifname, int ifindex, int ll, ...@@ -674,10 +678,10 @@ kernel_addresses(char *ifname, int ifindex, int ll,
memcpy(routes[i].prefix, v4prefix, 12); memcpy(routes[i].prefix, v4prefix, 12);
memcpy(routes[i].prefix + 12, &sin->sin_addr, 4); memcpy(routes[i].prefix + 12, &sin->sin_addr, 4);
routes[i].plen = 128; routes[i].plen = 128;
routes[i].metric = 0; routes[i].metric = 1;
routes[i].ifindex = ifindex; routes[i].ifindex = ifindex;
routes[i].proto = RTPROT_BABEL_LOCAL; routes[i].proto = RTPROT_BABEL_LOCAL;
memset(routes[i].gw, 0, 16); memcpy(routes[i].gw, routes[i].prefix, 16);
i++; i++;
} }
next: next:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment