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
[email protected]
https://lists.sourceforge.net/lists/listinfo/vde-users