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

Reply via email to