Revision: 530 http://vde.svn.sourceforge.net/vde/?rev=530&view=rev Author: danielel Date: 2012-01-17 05:18:53 +0000 (Tue, 17 Jan 2012) Log Message: ----------- Added minimal olsr support, work in progress
Modified Paths: -------------- branches/vde-router/vde-2/src/vde_router/Makefile.am branches/vde-router/vde-2/src/vde_router/vde_router.c branches/vde-router/vde-2/src/vde_router/vde_router.h branches/vde-router/vde-2/src/vde_router/vder_arp.c branches/vde-router/vde-2/src/vde_router/vder_arp.h branches/vde-router/vde-2/src/vde_router/vder_packet.c Added Paths: ----------- branches/vde-router/vde-2/src/vde_router/vder_olsr.c branches/vde-router/vde-2/src/vde_router/vder_olsr.h Modified: branches/vde-router/vde-2/src/vde_router/Makefile.am =================================================================== --- branches/vde-router/vde-2/src/vde_router/Makefile.am 2011-12-30 21:14:29 UTC (rev 529) +++ branches/vde-router/vde-2/src/vde_router/Makefile.am 2012-01-17 05:18:53 UTC (rev 530) @@ -13,6 +13,7 @@ bin_PROGRAMS = vde_router vde_router_SOURCES = rbtree.h vde_headers.h vder_arp.h vder_datalink.h vder_icmp.h \ vde_router.h vder_packet.h vder_queue.h rbtree.c vder_arp.c vder_datalink.c \ - vder_icmp.c vde_router.c vder_packet.c vder_queue.c vder_udp.c vder_dhcp.c + vder_icmp.c vde_router.c vder_packet.c vder_queue.c vder_udp.c vder_dhcp.c \ + vder_olsr.c vde_router_LDADD = $(top_builddir)/src/common/libvdecommon.la $(top_builddir)/src/lib/libvdeplug.la -lpthread Modified: branches/vde-router/vde-2/src/vde_router/vde_router.c =================================================================== --- branches/vde-router/vde-2/src/vde_router/vde_router.c 2011-12-30 21:14:29 UTC (rev 529) +++ branches/vde-router/vde-2/src/vde_router/vde_router.c 2012-01-17 05:18:53 UTC (rev 530) @@ -7,6 +7,7 @@ * * For the router engine see vder_datalink.c */ +#include "vder_olsr.h" #include "vder_datalink.h" #include "vde_router.h" #include "vder_queue.h" @@ -63,6 +64,7 @@ printoutc(fd, "connect create a new interface connect it to vde socket"); printoutc(fd, "ifconfig show/change interface addresses configuration"); printoutc(fd, "dhcpd start/stop dhcp server on a specific interface"); + printoutc(fd, "olsr start/stop OLSR"); printoutc(fd, "route show/change routing table"); printoutc(fd, "arp show neighbors ip/mac associations"); printoutc(fd, "queue show/change outgoing frames queues"); @@ -117,6 +119,18 @@ printoutc(fd, "dhcpd start eth0 10.0.0.101 10.0.0.120"); printoutc(fd, "dhcpd stop eth0"); return 0; + } else if (match_input("olsr",arg)) { + printoutc(fd, "Syntax:"); + printoutc(fd, "\tolsr start <devname> [<devname> [<devname> [<...>]]]"); + printoutc(fd, "--or--"); + printoutc(fd, "\tolsr stop"); + printoutc(fd, "Start/stop olsr service on specified interface(s). Devices/machines connected to the router"); + printoutc(fd, "will be notified about routing via OLSR messages"); + printoutc(fd, ""); + printoutc(fd, "Examples:"); + printoutc(fd, "olsr start eth0 eth1"); + printoutc(fd, "olsr stop"); + return 0; } else if (match_input("route",arg)) { printoutc(fd, "Syntax:"); printoutc(fd, "\troute [<action> <address> <netmask> [gw <gateway>] [via <interface>] [metric <metric>]]"); @@ -1114,7 +1128,60 @@ return 0; } +static int olsr(int fd,char *s) +{ + char *nextargs = NULL, *arg; + struct olsr_setup *olsr_settings; + struct vder_iface *selected = NULL; + enum command_action_enum action = -1; + static pthread_t olsr_thread; + + arg = strtok_r(s, " ", &nextargs); + if(!arg) { + printoutc(fd, "Error: arguments required"); + return EINVAL; + } + if ((!arg) || (strlen(arg) < 4) || ((strncmp(arg, "start", 5) != 0) && (strncmp(arg, "stop", 4) != 0))) { + printoutc(fd, "Invalid action \"%s\".", arg); + return EINVAL; + } + if (strncmp(arg, "start", 5) == 0) + action = ACTION_ADD; + else + action = ACTION_DELETE; + + if (action == ACTION_ADD) { + olsr_settings = malloc(sizeof(struct olsr_setup)); + memset(olsr_settings, 0, sizeof(struct olsr_setup)); + arg = strtok_r(NULL, " ", &nextargs); + while (arg) { + if ((strlen(arg) < 4) || (strncmp(arg, "eth", 3)!= 0)) { + printoutc(fd, "Invalid interface \"%s\".", arg); + free(olsr_settings); + return EINVAL; + } + selected = select_interface(arg); + if (!selected) { + free(olsr_settings); + return ENXIO; + } + olsr_settings->ifaces[olsr_settings->n_ifaces++] = selected; + arg = strtok_r(NULL, " ", &nextargs); + } + if (olsr_settings->n_ifaces == 0) { + free(olsr_settings); + return EINVAL; + } + pthread_create(&olsr_thread, 0, vder_olsr_loop, olsr_settings); + } else { + pthread_cancel(olsr_thread); + /* stop */ + } + return 0; +} + + #define WITHFILE 0x80 static struct comlist { char *tag; @@ -1130,6 +1197,7 @@ {"ipfilter", filter, WITHFILE}, {"queue", queue, WITHFILE}, {"dhcpd", dhcpd, 0 }, + {"olsr", olsr, 0 }, {"logout",logout, 0}, {"shutdown",doshutdown, 0} }; Modified: branches/vde-router/vde-2/src/vde_router/vde_router.h =================================================================== --- branches/vde-router/vde-2/src/vde_router/vde_router.h 2011-12-30 21:14:29 UTC (rev 529) +++ branches/vde-router/vde-2/src/vde_router/vde_router.h 2012-01-17 05:18:53 UTC (rev 530) @@ -49,15 +49,8 @@ uint32_t stats_bytes; }; -/* Interface */ -struct vder_arp_entry { - struct rb_node rb_node; - uint32_t ipaddr; - uint8_t macaddr[6]; -}; - /* route */ struct vder_route { struct vder_route *next; Modified: branches/vde-router/vde-2/src/vde_router/vder_arp.c =================================================================== --- branches/vde-router/vde-2/src/vde_router/vder_arp.c 2011-12-30 21:14:29 UTC (rev 529) +++ branches/vde-router/vde-2/src/vde_router/vder_arp.c 2012-01-17 05:18:53 UTC (rev 530) @@ -4,6 +4,7 @@ * */ #include "vde_router.h" +#include "vder_arp.h" #include "vde_headers.h" #include "vder_datalink.h" #include <unistd.h> @@ -152,3 +153,29 @@ } return found; } + +int vder_arp_get_neighbors(struct vder_iface *vif, uint32_t *neighbors, int vector_size) +{ + int i = 0; + struct rb_node *node; + if (vector_size <= 0) + return -EINVAL; + + node = vif->arp_table.rb_node; + while(node) { + struct vder_arp_entry *entry = rb_entry(node, struct vder_arp_entry, rb_node); + neighbors[i++] = entry->ipaddr; + if (i == vector_size) + return i; + node = node->rb_left; + } + node = vif->arp_table.rb_node; + while(node) { + struct vder_arp_entry *entry = rb_entry(node, struct vder_arp_entry, rb_node); + neighbors[i++] = entry->ipaddr; + if (i == vector_size) + return i; + node = node->rb_right; + } + return i; +} Modified: branches/vde-router/vde-2/src/vde_router/vder_arp.h =================================================================== --- branches/vde-router/vde-2/src/vde_router/vder_arp.h 2011-12-30 21:14:29 UTC (rev 529) +++ branches/vde-router/vde-2/src/vde_router/vder_arp.h 2012-01-17 05:18:53 UTC (rev 530) @@ -5,6 +5,16 @@ */ #ifndef __VDER_ARP #define __VDER_ARP +#include "vde_router.h" +#include <stdint.h> + +/* Interface */ +struct vder_arp_entry { + struct rb_node rb_node; + uint32_t ipaddr; + uint8_t macaddr[6]; +}; + void vder_add_arp_entry(struct vder_iface *vif, struct vder_arp_entry *p); struct vder_arp_entry *vder_get_arp_entry(struct vder_iface *vif, uint32_t addr); size_t vder_arp_query(struct vder_iface *oif, uint32_t tgt); @@ -16,5 +26,8 @@ /* O(N) search by macaddr (required by dhcp server) */ struct vder_arp_entry *vder_arp_get_record_by_macaddr(struct vder_iface *vif, uint8_t *mac); +/* O(N) list of neighbors (required by olsr) */ +int vder_arp_get_neighbors(struct vder_iface *vif, uint32_t *neighbors, int vector_size); + #endif Added: branches/vde-router/vde-2/src/vde_router/vder_olsr.c =================================================================== --- branches/vde-router/vde-2/src/vde_router/vder_olsr.c (rev 0) +++ branches/vde-router/vde-2/src/vde_router/vder_olsr.c 2012-01-17 05:18:53 UTC (rev 530) @@ -0,0 +1,240 @@ +#include "vder_udp.h" +#include "vder_arp.h" +#include "vder_olsr.h" +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/time.h> + + +#define OLSR_MSG_INTERVAL 6000 + +struct olsr_route_entry +{ + struct olsr_route_entry *next; + unsigned long time_left; + uint32_t destination; + uint32_t gateway; + struct vder_iface *iface; + uint16_t metric; +}; + +struct olsr_mid_entry +{ + struct olsr_mid_entry *next; + struct vder_iface *iface; + uint32_t addr; +}; + +struct olsr_hello_entry +{ + struct olsr_hello_entry *next; + struct vder_iface *iface; + uint32_t addr; +}; + +static struct olsr_route_entry *or_list = NULL; + +static struct vder_udp_socket *udpsock; +static struct olsr_setup *settings; + +/* return a list of other interfaces local ip addresses */ +static struct olsr_mid_entry *mid_list_alloc(struct vder_iface *dst_if) +{ + struct olsr_mid_entry *list = NULL, *p; + int i; + + for (i = 0; i < settings->n_ifaces; i++) { + struct vder_iface *cur = settings->ifaces[i]; + if (cur != dst_if) { + struct vder_ip4address *addr = cur->address_list; + while (addr) { + p = malloc(sizeof(struct olsr_mid_entry)); + if (!p) + return list; + p->next = list; + p->iface = cur; + p->addr = addr->address; + list = p; + addr = addr->next; + } + } + } + return list; +} + +static struct olsr_hello_entry *hello_list_alloc(struct vder_iface *dst_if) +{ + + struct olsr_hello_entry *list = NULL, *p; + int i; + + for (i = 0; i < settings->n_ifaces; i++) { + struct vder_iface *cur = settings->ifaces[i]; + if (cur == dst_if) { + struct vder_ip4address *addr = cur->address_list; + while (addr) { + p = malloc(sizeof(struct olsr_hello_entry)); + if (!p) + return list; + p->next = list; + p->iface = cur; + p->addr = addr->address; + list = p; + addr = addr->next; + } + } + } + return list; +} + +static void hello_list_free(struct olsr_hello_entry *l) +{ + struct olsr_hello_entry *p; + while(l) { + p = l; + l = p->next; + free(p); + } +} + +static void mid_list_free(struct olsr_mid_entry *l) +{ + struct olsr_mid_entry *p; + while(l) { + p = l; + l = p->next; + free(p); + } +} + + +static void olsr_make_dgram(struct vder_iface *vif) +{ + + uint32_t orig, dest; + uint8_t dgram[2000]; + int size = 0; + struct olsr_hello_entry *elist, *ep; + struct olsr_mid_entry *mlist, *mp; + struct olsrhdr *ohdr; + uint32_t netmask, bcast; + + static uint8_t hello_counter = 0, mid_counter = 0, tc_counter = 0; + static uint16_t pkt_counter = 0; + + ohdr = (struct olsrhdr *)dgram; + size += sizeof(struct olsrhdr); + + elist = hello_list_alloc(vif); + ep = elist; + if (!ep) + return; + netmask = vder_get_netmask(vif, ep->addr); + bcast = vder_get_broadcast(ep->addr, netmask); + while (ep) { + struct olsrmsg *msg_hello; + struct olsr_hmsg_hello *hello; + struct olsr_link *hlink; + uint32_t neighbors[256]; + int n_vec_size, i; + + msg_hello = (struct olsrmsg *) (dgram + size); + size += sizeof(struct olsrmsg); + msg_hello->type = OLSRMSG_HELLO; + msg_hello->vtime = 60; /* one hot minute */ + msg_hello->orig = ep->addr; + msg_hello->ttl = 1; + msg_hello->hop = 0; + msg_hello->seq = htons(hello_counter++); + + hello = (struct olsr_hmsg_hello *)(dgram + size); + size += sizeof(struct olsr_hmsg_hello); + hello->reserved = 0; + hello->htime = 0x05; /* Todo: find and define values */ + hello->willingness = 0x07; + + n_vec_size = vder_arp_get_neighbors(vif, neighbors, 256); + if (n_vec_size < 1) + return; + msg_hello->size = htons(sizeof(struct olsrmsg) + + sizeof(struct olsr_hmsg_hello) + n_vec_size * ((sizeof(struct olsr_link) + sizeof(struct olsr_neighbor)))); + + + printf("%d neighbors \n", n_vec_size); + if (n_vec_size > 0) { + for (i = 0; i < n_vec_size; i ++) { + struct olsr_neighbor *neigh; + hlink = (struct olsr_link *) (dgram + size); + size += (sizeof(struct olsr_link)); + hlink->reserved = 0; + hlink->link_code = OLSRLINK_SYMMETRIC; + hlink->link_msg_size = htons(sizeof(struct olsr_link) + sizeof(struct olsr_neighbor)); + neigh = (struct olsr_neighbor *) (dgram + size); + size += (sizeof(struct olsr_neighbor)); + neigh->addr = neighbors[i]; + neigh->lq = 0xFF; + neigh->nlq = 0xFF; + } + } + ep = ep->next; + } + hello_list_free(elist); + mlist = mid_list_alloc(vif); + /* TODO: Add MID msg */ + mid_list_free(mlist); + + /* TODO: Add TC msg */ + + ohdr->len = htons(size); + ohdr->seq = htons(pkt_counter++); + + if ( 0 > vder_udpsocket_sendto_broadcast(udpsock, dgram, size + 8, vif, bcast, OLSR_PORT) ) { + perror("olsr send"); + } +} + +static void olsr_recv(uint8_t *buffer, int len) +{ + +} + + +void *vder_olsr_loop(void *olsr_settings) +{ + uint32_t from_ip; + uint16_t from_port; + unsigned char buffer[2000]; + int len; + int i; + struct timeval now, last_out; + + settings = (struct olsr_setup *) olsr_settings; + if(settings->n_ifaces <= 0) + return NULL; + if (!udpsock) + udpsock = vder_udpsocket_open(OLSR_PORT); + if (!udpsock) + return NULL; + gettimeofday(&last_out, NULL); + + + while(1) { + len = vder_udpsocket_recvfrom(udpsock, buffer, OLSR_MSG_INTERVAL, &from_ip, &from_port, -1); + if (len < 0) { + perror("udp recv"); + return NULL; + } + if ((len > 0) && (from_port == OLSR_PORT)) { + olsr_recv(buffer, len); + } + sleep(1); + gettimeofday(&now, NULL); + if ((now.tv_sec - last_out.tv_sec) >= (OLSR_MSG_INTERVAL / 1000)) { + for (i = 0; i < settings->n_ifaces; i++) + olsr_make_dgram(settings->ifaces[i]); + last_out = now; + } + } +} + Added: branches/vde-router/vde-2/src/vde_router/vder_olsr.h =================================================================== --- branches/vde-router/vde-2/src/vde_router/vder_olsr.h (rev 0) +++ branches/vde-router/vde-2/src/vde_router/vder_olsr.h 2012-01-17 05:18:53 UTC (rev 530) @@ -0,0 +1,79 @@ +#ifndef __VDER_OLSR +#define __VDER_OLSR + +#include "vder_arp.h" +#include "vde_router.h" + +#define OLSR_PORT (htons(698)) + +#define OLSRMSG_HELLO 0xc9 +#define OLSRMSG_MID 0x03 +#define OLSRMSG_TC 0xca + +#define OLSRLINK_SYMMETRIC 0x06 +#define OLSRLINK_MPR 0x10 + +struct __attribute__((packed)) olsr_link +{ + uint8_t link_code; + uint8_t reserved; + uint16_t link_msg_size; +}; + +struct __attribute__((packed)) olsr_neighbor +{ + uint32_t addr; + uint8_t lq; + uint8_t nlq; + uint16_t reserved; +}; + +struct __attribute__((packed)) olsr_hmsg_hello +{ + uint16_t reserved; + uint8_t htime; + uint8_t willingness; +}; + +struct __attribute__((packed)) olsr_hmsg_tc +{ + uint16_t ansn; + uint32_t addr; + uint8_t lq; + uint8_t nlq; + uint16_t reserved; +}; + +struct __attribute__((packed)) olsr_hmsg_mid +{ + uint16_t seq; + uint32_t addr; +}; + +struct __attribute__((packed)) olsrmsg +{ + uint8_t type; + uint8_t vtime; + uint16_t size; + uint32_t orig; + uint8_t ttl; + uint8_t hop; + uint16_t seq; + uint8_t data[0]; +}; + +struct __attribute__((packed)) olsrhdr +{ + uint16_t len; + uint16_t seq; +}; + + +struct olsr_setup { + int n_ifaces; + struct vder_iface *ifaces[64]; +}; + +void *vder_olsr_loop(void *olsr_setup); + +#endif Modified: branches/vde-router/vde-2/src/vde_router/vder_packet.c =================================================================== --- branches/vde-router/vde-2/src/vde_router/vder_packet.c 2011-12-30 21:14:29 UTC (rev 529) +++ branches/vde-router/vde-2/src/vde_router/vder_packet.c 2012-01-17 05:18:53 UTC (rev 530) @@ -141,8 +141,10 @@ iph->protocol = protocol; iph->ttl = DEFAULT_TTL; iph->daddr = dst_ip; - //iph->saddr = vder_get_right_localip(iface, iph->daddr); - iph->saddr = 0; + if (dst_ip != (htonl((uint32_t) -1))) + iph->saddr = vder_get_right_localip(iface, iph->daddr); + else + iph->saddr = 0; iph->check = htons(vder_ip_checksum(iph)); return vder_sendto(iface, vdb, bcast_macaddr); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------------ Keep Your Developer Skills Current with LearnDevNow! The most comprehensive online learning library for Microsoft developers is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3, Metro Style Apps, more. Free future releases when you subscribe now! http://p.sf.net/sfu/learndevnow-d2d _______________________________________________ vde-users mailing list vde-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/vde-users