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)
LDLIBS = -lrt -liphlpapi -lws2_32 -lwlanapi -lole32 -lsetupapi
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 \
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)
$(CC) $(CFLAGS) $(LDFLAGS) -o babeld $(OBJS) $(LDLIBS)
......@@ -48,4 +66,4 @@ uninstall:
clean:
-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:
In the Windows XP,
$ PLATFORM_DEFINES="-D_WIN32_WINNT=0x0503" make
$ WINVER=XP make
Later Windows Vista,
$ PLATFORM_DEFINES="-D_WIN32_WINNT=0x0600" make
$ WINVER=VISTA make
Interface Names
===============
In the Windows, GUID is used as unique interface names. You can list
all the interfaces by the following command:
Use network connection name as interface name.
$ ipv6 if | grep "^Interface" -A 1
Notes
=====
--
Interface 2: Automatic Tunneling Pseudo-Interface
Guid {48FCE3FC-EC30-E50E-F1A7-71172AEEE3AE}
--
Interface 1: Loopback Pseudo-Interface
Guid {6BD113CC-5EC2-7638-B953-0B889DA72014}
...
1. If network connection is disabeld, its interface name will NOT be
recognize by Babeld in the Cygwin.
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)
FOR_ALL_INTERFACES(ifp) {
/* 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);
#endif
if(ifindex > 0) {
unsigned char eui[8];
rc = if_eui64(ifp->name, ifindex, eui);
......@@ -390,7 +394,11 @@ main(int argc, char **argv)
ifname = if_indextoname(i, buf);
if(ifname == NULL)
continue;
#if defined (_WIN32_WINNT)
rc = if_eui64(cyginet_ifname(ifname), i, eui);
#else
rc = if_eui64(ifname, i, eui);
#endif
if(rc < 0)
continue;
memcpy(myid, eui, 8);
......
......@@ -348,7 +348,11 @@ parse_filter(gnc_t gnc, void *closure)
if(c < -1)
goto error;
filter->ifname = interface;
#if defined (_WIN32_WINNT)
filter->ifindex = if_nametoindex(cyginet_guidname(interface));
#else
filter->ifindex = if_nametoindex(interface);
#endif
} else if(strcmp(token, "allow") == 0) {
filter->result = 0;
} else if(strcmp(token, "deny") == 0) {
......@@ -644,7 +648,11 @@ renumber_filter(struct filter *filter)
{
while(filter) {
if(filter->ifname)
#if defined (_WIN32_WINNT)
filter->ifindex = if_nametoindex(cyginet_guidname(filter->ifname));
#else
filter->ifindex = if_nametoindex(filter->ifname);
#endif
filter = filter->next;
}
}
......
This diff is collapsed.
......@@ -60,6 +60,7 @@
#define RTM_CHANGE 0x3 /* Change Metrics or flags */
#define RTM_GET 0x4 /* Report Metrics */
#define IFF_RUNNING 0x40
/*
* Structure of a Link-Level sockaddr:
*/
......@@ -84,7 +85,7 @@ struct cyginet_route {
struct sockaddr gateway;
};
#if defined(INSIDE_CYGINET)
#if defined(INSIDE_BABELD_CYGINET)
struct ifaddrs {
struct ifaddrs *ifa_next;
......@@ -101,6 +102,15 @@ struct if_nameindex {
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 {
DWORD IfType;
IF_OPER_STATUS OperStatus;
......@@ -135,12 +145,15 @@ extern void freeifaddrs(struct ifaddrs *);
); \
}
#endif /* INSIDE_CYGINET */
#endif /* INSIDE_BABELD_CYGINET */
/* Export functions from cyginet */
int cyginet_startup();
void cyginet_cleanup();
char * cyginet_ifname(const char *);
char * cyginet_guidname(const char *);
int cyginet_start_monitor_route_changes(int);
int cyginet_stop_monitor_route_changes();
int cyginet_set_ipv6_forwards(int);
......
......@@ -409,7 +409,11 @@ check_interfaces(void)
unsigned int ifindex;
FOR_ALL_INTERFACES(ifp) {
#if defined (_WIN32_WINNT)
ifindex = if_nametoindex(cyginet_guidname(ifp->name));
#else
ifindex = if_nametoindex(ifp->name);
#endif
if(ifindex != ifp->ifindex) {
debugf("Noticed ifindex change for %s.\n", ifp->name);
ifp->ifindex = 0;
......
......@@ -111,3 +111,8 @@ void set_timeout(struct timeval *timeout, int msecs);
int interface_up(struct interface *ifp, int up);
int interface_ll_address(struct interface *ifp, const unsigned char *address);
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.
#include <netinet/in.h>
#include "babeld.h"
#if defined (_WIN32_WINNT)
#define KERNEL_INFINITY 9999
#else
#define KERNEL_INFINITY 0xFFFF
#endif
struct kernel_route {
unsigned char prefix[16];
......
......@@ -28,6 +28,7 @@ THE SOFTWARE.
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <assert.h>
#include <strings.h>
#include <netinet/in.h>
......@@ -58,11 +59,12 @@ THE SOFTWARE.
*
* 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] =
{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)
{
struct sockaddr_dl sdl;
char *tmp = NULL;
memset(&sdl, 0, sizeof(struct sockaddr_dl));
if (get_sdl(&sdl, ifname) < 0) {
return -1;
}
......@@ -92,7 +95,7 @@ if_eui64(char *ifname, int ifindex, unsigned char *eui)
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).
return -1 if an error occurs, 0 otherwise. */
static int
......@@ -112,9 +115,7 @@ get_sdl(struct sockaddr_dl *sdl, char *ifname)
static int old_forwarding = -1;
static int old_accept_redirects = -1;
static int ifindex_lo = -1;
static int if6index_lo = -1;
static int ifindex_lo = 1;
static int kernel_pipe_handles[2];
int
......@@ -340,7 +341,7 @@ kernel_interface_channel(const char *ifname, int ifindex)
*
* RTF_CLONING: generate new routes on use
*
* No corresponding function in the Windows.
* Not implemented in the Windows.
*
*/
int
......@@ -412,22 +413,11 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
if(metric == KERNEL_INFINITY) {
/* RTF_BLACKHOLE; */
/* ==> Set gateway to an unused ip address in the Windows */
if(ipv4) {
if (ifindex_lo < 0) {
ifindex_lo = cyginet_loopback_index(AF_INET);
ifindex_lo = cyginet_loopback_index(AF_UNSPEC);
if(ifindex_lo <= 0)
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) \
......@@ -502,10 +492,11 @@ kernel_route(int operation, const unsigned char *dest, unsigned short plen,
static void
print_kernel_route(int add, struct kernel_route *route)
{
char ifname[IFNAMSIZ];
char *ifname = NULL;
char guidname[IFNAMSIZ];
if(!if_indextoname(route->ifindex, ifname))
memcpy(ifname,"unk",4);
if(if_indextoname(route->ifindex, guidname))
ifname = cyginet_ifname(guidname);
fprintf(stderr,
"%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)
format_prefix(route->prefix, route->plen),
format_address(route->gw),
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)
struct sockaddr *sa;
if(ifindex_lo < 0) {
ifindex_lo = cyginet_loopback_index(AF_INET);
ifindex_lo = cyginet_loopback_index(AF_UNSPEC);
if(ifindex_lo <= 0)
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));
route -> plen = src -> plen;
route -> metric = src -> metric;
......@@ -575,9 +561,7 @@ parse_kernel_route(struct cyginet_route *src, struct kernel_route *route)
v4tov6(route->gw, (unsigned char *)&sin->sin_addr);
}
if((sa->sa_family == AF_INET6) && (route->ifindex == if6index_lo))
return -1;
if((sa->sa_family == AF_INET) && (route->ifindex == ifindex_lo))
if(route->ifindex == ifindex_lo)
return -1;
/* Netmask */
......@@ -627,16 +611,30 @@ kernel_routes(struct kernel_route *routes, int maxroutes)
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
kernel_addresses(char *ifname, int ifindex, int ll,
struct kernel_route *routes, int maxroutes)
{
struct ifaddrs *ifa, *ifap;
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);
if(rc < 0)
return -1;
......@@ -644,8 +642,14 @@ kernel_addresses(char *ifname, int ifindex, int ll,
ifap = ifa;
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) {
if((ifname != NULL && strcmp(ifap->ifa_name, ifname) != 0))
if((ifname != NULL && compare_ifname(ifap->ifa_name, ifname) != 0))
goto next;
if(ifap->ifa_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin6 = (struct sockaddr_in6*)ifap->ifa_addr;
......@@ -658,10 +662,10 @@ kernel_addresses(char *ifname, int ifindex, int ll,
reset those bytes to 0 before passing them to babeld. */
memset(routes[i].prefix + 2, 0, 2);
routes[i].plen = 128;
routes[i].metric = 0;
routes[i].metric = 1;
routes[i].ifindex = ifindex;
routes[i].proto = RTPROT_BABEL_LOCAL;
memset(routes[i].gw, 0, 16);
memcpy(routes[i].gw, routes[i].prefix, 16);
i++;
} else if(ifap->ifa_addr->sa_family == AF_INET) {
struct sockaddr_in *sin = (struct sockaddr_in*)ifap->ifa_addr;
......@@ -674,10 +678,10 @@ kernel_addresses(char *ifname, int ifindex, int ll,
memcpy(routes[i].prefix, v4prefix, 12);
memcpy(routes[i].prefix + 12, &sin->sin_addr, 4);
routes[i].plen = 128;
routes[i].metric = 0;
routes[i].metric = 1;
routes[i].ifindex = ifindex;
routes[i].proto = RTPROT_BABEL_LOCAL;
memset(routes[i].gw, 0, 16);
memcpy(routes[i].gw, routes[i].prefix, 16);
i++;
}
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