Revision: 528
http://vde.svn.sourceforge.net/vde/?rev=528&view=rev
Author: danielel
Date: 2011-12-30 10:33:54 +0000 (Fri, 30 Dec 2011)
Log Message:
-----------
Added DHCP client
Added arp command to show arp tables
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_datalink.c
branches/vde-router/vde-2/src/vde_router/vder_packet.c
branches/vde-router/vde-2/src/vde_router/vder_packet.h
branches/vde-router/vde-2/src/vde_router/vder_queue.c
branches/vde-router/vde-2/src/vde_router/vder_udp.c
branches/vde-router/vde-2/src/vde_router/vder_udp.h
Added Paths:
-----------
branches/vde-router/vde-2/src/vde_router/vder_dhcp.c
branches/vde-router/vde-2/src/vde_router/vder_dhcp.h
Removed Paths:
-------------
branches/vde-router/vde-2/src/vde_router/vder_dhcpd.c
branches/vde-router/vde-2/src/vde_router/vder_dhcpd.h
Modified: branches/vde-router/vde-2/src/vde_router/Makefile.am
===================================================================
--- branches/vde-router/vde-2/src/vde_router/Makefile.am 2011-12-27
14:45:35 UTC (rev 527)
+++ branches/vde-router/vde-2/src/vde_router/Makefile.am 2011-12-30
10:33:54 UTC (rev 528)
@@ -13,6 +13,6 @@
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_dhcpd.c
+ vder_icmp.c vde_router.c vder_packet.c vder_queue.c vder_udp.c
vder_dhcp.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-27
14:45:35 UTC (rev 527)
+++ branches/vde-router/vde-2/src/vde_router/vde_router.c 2011-12-30
10:33:54 UTC (rev 528)
@@ -11,7 +11,7 @@
#include "vde_router.h"
#include "vder_queue.h"
#include "vder_packet.h"
-#include "vder_dhcpd.h"
+#include "vder_dhcp.h"
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
@@ -64,6 +64,7 @@
printoutc(fd, "ifconfig show/change interface addresses
configuration");
printoutc(fd, "dhcpd start/stop dhcp server on a
specific interface");
printoutc(fd, "route show/change routing table");
+ printoutc(fd, "arp show neighbors ip/mac
associations");
printoutc(fd, "queue show/change outgoing frames
queues");
printoutc(fd, "ipfilter show/change ip filtering
configuration");
printoutc(fd, "stats print interface statistics");
@@ -87,17 +88,21 @@
} else if (match_input("ifconfig",arg)) {
printoutc(fd, "Syntax:");
printoutc(fd, "\tifconfig [<devname> [<action> <address>
<netmask>]]");
+ printoutc(fd, "--or--");
+ printoutc(fd, "\tifconfig <devname> add dhcp");
printoutc(fd, "Show/store IP address configuration. If no
<devname> is provided, the default action");
printoutc(fd, "will be to display the current configuration for
all the existing ethernet devices.");
printoutc(fd, "<action> can be \"add\" or \"del\". If \"add\"
is specified, all other arguments are mandatory.");
printoutc(fd, "If \"del\" is specified, only <address> will be
used to search for an existing entry.");
printoutc(fd, "Each virtual ethernet can be associated to more
than one IP addresses. A static route for");
printoutc(fd, "the resulting neighborhood will be added.");
+ printoutc(fd, "Dhcp option allows to ask for a dynamic IP
address.");
printoutc(fd, "");
printoutc(fd, "Examples:");
printoutc(fd, "ifconfig");
printoutc(fd, "ifconfig eth0");
printoutc(fd, "ifconfig eth1 add 10.0.0.1 255.0.0.0");
+ printoutc(fd, "ifconfig eth1 add dhcp");
printoutc(fd, "ifconfig eth1 del 10.0.0.1");
return 0;
} else if (match_input("dhcpd",arg)) {
@@ -199,6 +204,10 @@
printoutc(fd, "ipfilter add src eth1 tos 2 to 172.16.0.0
255.255.0.0 prio 7");
printoutc(fd, "ipfilter del src eth1 tos 2 to 172.16.0.0
255.255.0.0");
return 0;
+ } else if (match_input("arp",arg)) {
+ printoutc(fd, "Syntax:");
+ printoutc(fd, "\tarp");
+ return 0;
} else if (match_input("stats",arg)) {
printoutc(fd, "Syntax:");
printoutc(fd, "\tstats");
@@ -247,7 +256,10 @@
char *txt_address, *txt_netmask;
txt_address = strdup(vder_ntoa(addr->address));
txt_netmask= strdup(vder_ntoa(addr->netmask));
- printoutc(fd, "\taddress: %s netmask: %s", txt_address,
txt_netmask);
+ if (addr->address == (uint32_t)(-1))
+ printoutc(fd, "\tAcquiring one IP address via
DHCP...");
+ else
+ printoutc(fd, "\taddress: %s netmask: %s",
txt_address, txt_netmask);
free(txt_address);
free(txt_netmask);
addr = addr->next;
@@ -358,16 +370,21 @@
not_understood(fd, "");
return EINVAL;
}
- if (!inet_aton(arg, &temp_address) ||
!is_unicast(temp_address.s_addr)) {
+ if (match_input("dhcp", arg)) {
+ temp_address.s_addr = (uint32_t)(-1);
+ pthread_create(&selected->dhcpclient, 0,
dhcp_client_loop, selected);
+ }
+ else if (!inet_aton(arg, &temp_address) ||
!is_unicast(temp_address.s_addr)) {
printoutc(fd, "Invalid address \"%s\"", arg);
return EINVAL;
}
arg = strtok_r(NULL, " ", &nextargs);
- if (!arg && (action == ACTION_ADD)) {
+ if (!arg && (action == ACTION_ADD) && (temp_address.s_addr !=
(uint32_t)(-1))) {
printoutc(fd, "Error: parameter 'netmask' required.");
return EINVAL;
}
- if ((action == ACTION_ADD) && (!inet_aton(arg, &temp_netmask)
|| !is_netmask(temp_netmask.s_addr))) {
+ if ((action == ACTION_ADD) && (temp_address.s_addr !=
(uint32_t)(-1)) &&
+ (!inet_aton(arg, &temp_netmask) ||
!is_netmask(temp_netmask.s_addr))) {
printoutc(fd, "Invalid netmask \"%s\"", arg);
return EINVAL;
}
@@ -974,7 +991,7 @@
return EINVAL;
iface = Router.iflist;
while(iface) {
- printoutc(fd, "eth%d frame sent:%d, frame received:%d",
+ printoutc(fd, "eth%d frames sent:%d, frames received:%d",
iface->interface_id, iface->stats.sent,
iface->stats.recvd);
printoutc(fd, "");
iface = iface->next;
@@ -982,6 +999,42 @@
return 0;
}
+static int arp(int fd, char *args)
+{
+ struct vder_iface *iface;
+ struct rb_node *node;
+ if (strlen(args) > 0)
+ return EINVAL;
+ iface = Router.iflist;
+ while(iface) {
+ node = iface->arp_table.rb_node;
+ while (node) {
+ struct vder_arp_entry *ae = rb_entry(node, struct
vder_arp_entry, rb_node);
+ char *txt_address = strdup(vder_ntoa(ae->ipaddr));
+ printoutc(fd, "%s %02x:%02x:%02x:%02x:%02x:%02x
(eth%d)", txt_address,
+ ae->macaddr[0], ae->macaddr[1], ae->macaddr[2],
ae->macaddr[3], ae->macaddr[4], ae->macaddr[5],
+ iface->interface_id);
+ free(txt_address);
+ node = node->rb_left;
+ }
+ node = iface->arp_table.rb_node;
+ if (node)
+ node = node->rb_right;
+ while (node) {
+ struct vder_arp_entry *ae = rb_entry(node, struct
vder_arp_entry, rb_node);
+ char *txt_address = strdup(vder_ntoa(ae->ipaddr));
+ printoutc(fd, "%s %02x:%02x:%02x:%02x:%02x:%02x
(eth%d)", txt_address,
+ ae->macaddr[0], ae->macaddr[1], ae->macaddr[2],
ae->macaddr[3], ae->macaddr[4], ae->macaddr[5],
+ iface->interface_id);
+ free(txt_address);
+ node = node->rb_right;
+ }
+ iface = iface->next;
+ }
+ return 0;
+}
+
+
#define DEFAULT_LEASE_TIME htonl(0xa8c0)
static int dhcpd(int fd,char *s)
{
@@ -1070,6 +1123,7 @@
} commandlist [] = {
{"help", help, WITHFILE},
{"ifconfig", ifconfig, WITHFILE},
+ {"arp", arp, WITHFILE},
{"route", route, WITHFILE},
{"connect", doconnect, 0},
{"stats", stats, WITHFILE},
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-27
14:45:35 UTC (rev 527)
+++ branches/vde-router/vde-2/src/vde_router/vde_router.h 2011-12-30
10:33:54 UTC (rev 528)
@@ -164,6 +164,7 @@
pthread_t receiver;
pthread_t queue_manager;
pthread_t dhcpd;
+ pthread_t dhcpclient;
int dhcpd_started;
struct {
uint32_t sent;
Modified: branches/vde-router/vde-2/src/vde_router/vder_datalink.c
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_datalink.c 2011-12-27
14:45:35 UTC (rev 527)
+++ branches/vde-router/vde-2/src/vde_router/vder_datalink.c 2011-12-30
10:33:54 UTC (rev 528)
@@ -372,7 +372,8 @@
pthread_mutex_unlock(&Router.global_config_lock);
/* Add static route towards neightbors */
- vder_route_add(address->address, address->netmask, 0U, 1, iface);
+ if (addr != (uint32_t) (-1))
+ vder_route_add(address->address, address->netmask, 0U, 1,
iface);
return 0;
}
@@ -469,7 +470,7 @@
while (iface) {
struct vder_ip4address *cur = iface->address_list;
while(cur) {
- if (cur->address == addr) {
+ if ((cur->address == addr)|| (cur->address ==
(uint32_t)(-1))) {
return 1;
}
cur = cur->next;
Copied: branches/vde-router/vde-2/src/vde_router/vder_dhcp.c (from rev 527,
branches/vde-router/vde-2/src/vde_router/vder_dhcpd.c)
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_dhcp.c
(rev 0)
+++ branches/vde-router/vde-2/src/vde_router/vder_dhcp.c 2011-12-30
10:33:54 UTC (rev 528)
@@ -0,0 +1,468 @@
+#include "vder_udp.h"
+#include "vder_arp.h"
+#include "vder_dhcp.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+static struct vder_dhcp_negotiation *Negotiation_list;
+static struct vder_udp_socket *udpsock;
+static struct vder_dhcpd_settings Settings;
+
+static struct vder_dhcp_negotiation *
+get_negotiation_by_xid(uint32_t xid)
+{
+ struct vder_dhcp_negotiation *cur = Negotiation_list;
+ while (cur) {
+ if (cur->xid == xid)
+ return cur;
+ cur = cur->next;
+ }
+ return NULL;
+}
+
+static uint8_t dhcp_get_next_option(uint8_t *begin, uint8_t *data, int *len,
uint8_t **nextopt)
+{
+ uint8_t *p;
+ uint8_t type;
+ uint8_t opt_len;
+
+ if (!begin)
+ p = *nextopt;
+ else
+ p = begin;
+
+ type = *p;
+ *nextopt = ++p;
+ if ((type == DHCPOPT_END) || (type == DHCPOPT_PAD)) {
+ memset(data, 0, *len);
+ len = 0;
+ return type;
+ }
+ opt_len = *p;
+ p++;
+ if (*len > opt_len)
+ *len = opt_len;
+ memcpy(data, p, *len);
+ *nextopt = p + opt_len;
+ return type;
+}
+
+static int is_options_valid(uint8_t *opt_buffer, int len)
+{
+ uint8_t *p = opt_buffer;
+ while (len > 0) {
+ if (*p == DHCPOPT_END)
+ return 1;
+ else if (*p == DHCPOPT_PAD) {
+ p++;
+ len--;
+ } else {
+ uint8_t opt_len;
+ p++;
+ len--;
+ opt_len = *p;
+ p += opt_len + 1;
+ len -= opt_len;
+ }
+ }
+ return 0;
+}
+
+#define DHCP_DATAGRAM_SIZE 308
+#define OPENDNS (htonl(0xd043dede))
+
+static void dhcpd_make_reply(struct vder_dhcp_negotiation *dn, uint8_t
reply_type)
+{
+
+ uint8_t buf_out[DHCP_DATAGRAM_SIZE] = {0};
+ struct dhcphdr *dh_out = (struct dhcphdr *) buf_out;
+ uint32_t server_address = vder_get_right_localip(Settings.iface,
Settings.pool_next);
+ uint32_t netmask = vder_get_netmask(Settings.iface, server_address);
+ uint32_t bcast = vder_get_broadcast(server_address, netmask);
+ uint32_t dns_server = OPENDNS;
+
+ int sent = 0;
+
+
+ memcpy(dh_out->hwaddr, dn->hwaddr, HLEN_ETHER);
+ dh_out->op = DHCP_OP_REPLY;
+ dh_out->htype = HTYPE_ETHER;
+ dh_out->hlen = HLEN_ETHER;
+ dh_out->xid = dn->xid;
+ dh_out->yiaddr = dn->arp->ipaddr;
+ dh_out->siaddr = server_address;
+ dh_out->dhcp_magic = DHCPD_MAGIC_COOKIE;
+
+ /* Option: msg type, len 1 */
+ dh_out->options[0] = DHCPOPT_MSGTYPE;
+ dh_out->options[1] = 1;
+ dh_out->options[2] = reply_type;
+
+ /* Option: server id, len 4 */
+ dh_out->options[3] = DHCPOPT_SERVERID;
+ dh_out->options[4] = 4;
+ memcpy(dh_out->options + 5, &server_address, 4);
+
+ /* Option: Lease time, len 4 */
+ dh_out->options[9] = DHCPOPT_LEASETIME;
+ dh_out->options[10] = 4;
+ memcpy(dh_out->options + 11, &Settings.lease_time, 4);
+
+ /* Option: Netmask, len 4 */
+ dh_out->options[15] = DHCPOPT_NETMASK;
+ dh_out->options[16] = 4;
+ memcpy(dh_out->options + 17, &netmask, 4);
+
+ /* Option: Router, len 4 */
+ dh_out->options[21] = DHCPOPT_ROUTER;
+ dh_out->options[22] = 4;
+ memcpy(dh_out->options + 23, &server_address, 4);
+
+ /* Option: Broadcast, len 4 */
+ dh_out->options[27] = DHCPOPT_BCAST;
+ dh_out->options[28] = 4;
+ memcpy(dh_out->options + 29, &bcast, 4);
+
+ /* Option: DNS, len 4 */
+ dh_out->options[33] = DHCPOPT_DNS;
+ dh_out->options[34] = 4;
+ memcpy(dh_out->options + 35, &dns_server, 4);
+
+ dh_out->options[40] = DHCPOPT_END;
+
+ sent = vder_udpsocket_sendto(udpsock, buf_out, DHCP_DATAGRAM_SIZE,
dh_out->yiaddr, DHCP_CLIENT_PORT);
+ if (sent < 0) {
+ perror("udp sendto");
+ }
+}
+
+#define dhcpd_make_offer(x) dhcpd_make_reply(x, DHCP_MSG_OFFER)
+#define dhcpd_make_ack(x) dhcpd_make_reply(x, DHCP_MSG_ACK)
+
+#define ip_inrange(x) ((ntohl(x) >= ntohl(Settings.pool_start)) && (ntohl(x)
<= ntohl(Settings.pool_end)))
+
+static void dhcp_recv(uint8_t *buffer, int len)
+{
+ struct dhcphdr *dhdr = (struct dhcphdr *) buffer;
+ struct vder_dhcp_negotiation *dn = get_negotiation_by_xid(dhdr->xid);
+ uint8_t *nextopt, opt_data[20], opt_type;
+ int opt_len = 20;
+
+
+ if (!is_options_valid(dhdr->options, len - sizeof(struct dhcphdr)))
+ return;
+
+
+
+ if (!dn) {
+ dn = malloc(sizeof(struct vder_dhcp_negotiation));
+ memset(dn, 0, sizeof(struct vder_dhcp_negotiation));
+ dn->xid = dhdr->xid;
+ dn->state = DHCPSTATE_DISCOVER;
+ memcpy(dn->hwaddr, dhdr->hwaddr, HLEN_ETHER);
+ dn->next = Negotiation_list;
+ Negotiation_list = dn;
+ dn->arp = vder_arp_get_record_by_macaddr(Settings.iface,
dn->hwaddr);
+ if (!dn->arp) {
+ dn->arp = malloc(sizeof(struct vder_arp_entry));
+ if (!dn->arp)
+ return;
+ memcpy(dn->arp->macaddr, dn->hwaddr, HLEN_ETHER);
+ dn->arp->ipaddr = Settings.pool_next;
+ Settings.pool_next = htonl(ntohl(Settings.pool_next) +
1);
+ vder_add_arp_entry(Settings.iface, dn->arp);
+ }
+ }
+
+ if (!ip_inrange(dn->arp->ipaddr))
+ return;
+
+
+ opt_type = dhcp_get_next_option(dhdr->options, opt_data, &opt_len,
&nextopt);
+ while (opt_type != DHCPOPT_END) {
+ /* parse interesting options here */
+ if (opt_type == DHCPOPT_MSGTYPE) {
+
+ /* server simple state machine */
+ uint8_t msg_type = opt_data[0];
+ if (msg_type == DHCP_MSG_DISCOVER) {
+ dhcpd_make_offer(dn);
+ dn->state = DHCPSTATE_OFFER;
+ return;
+ } else if (msg_type == DHCP_MSG_REQUEST) {
+ dhcpd_make_ack(dn);
+ return;
+ }
+ }
+ opt_len = 20;
+ opt_type = dhcp_get_next_option(NULL, opt_data, &opt_len,
&nextopt);
+ }
+}
+
+
+void *dhcp_server_loop(void *ptr_settings)
+{
+ uint32_t from_ip;
+ uint16_t from_port;
+
+ unsigned char buffer[2000];
+ int len;
+
+ memcpy(&Settings, ptr_settings, sizeof(struct vder_dhcpd_settings));
+ Settings.pool_next = Settings.pool_start;
+ free(ptr_settings);
+
+
+ if(!Settings.iface)
+ return NULL;
+ if (!udpsock)
+ udpsock = vder_udpsocket_open(DHCPD_PORT);
+ if (!udpsock)
+ return NULL;
+
+
+ while(1) {
+ len = vder_udpsocket_recvfrom(udpsock, buffer, 2000, &from_ip,
&from_port, -1);
+ if (len < 0) {
+ perror("udp recv");
+ return NULL;
+ }
+ if ((from_ip == 0) && (from_port == DHCP_CLIENT_PORT)) {
+ dhcp_recv(buffer, len);
+ }
+ }
+}
+
+
+
+struct dhcp_client_cookie
+{
+ uint32_t xid;
+ uint32_t address;
+ uint32_t netmask;
+ uint32_t gateway;
+ uint32_t server_id;
+ uint32_t lease_time;
+ struct vder_udp_socket *socket;
+ struct vder_iface *iface;
+ struct timeval start_time;
+ int attempt;
+ enum dhcp_negotiation_state state;
+};
+
+static int dhclient_recv_offer(struct dhcp_client_cookie *cli, uint8_t *data,
int len)
+{
+ struct dhcphdr *dhdr = (struct dhcphdr *) data;
+ uint8_t *nextopt, opt_data[20], opt_type;
+ int opt_len = 20;
+ uint8_t msg_type = 0xFF;
+
+
+ if (dhdr->xid != cli->xid) {
+ printf("bad xid\n");
+ return 0;
+ }
+
+ if (!is_options_valid(dhdr->options, len - sizeof(struct dhcphdr))) {
+ printf("bad options\n");
+ return 0;
+ }
+
+ cli->address = dhdr->yiaddr;
+
+ opt_type = dhcp_get_next_option(dhdr->options, opt_data, &opt_len,
&nextopt);
+ while (opt_type != DHCPOPT_END) {
+ if (opt_type == DHCPOPT_MSGTYPE)
+ msg_type = opt_data[0];
+ if ((opt_type == DHCPOPT_LEASETIME) && (opt_len == 4))
+ memcpy(&cli->lease_time, opt_data, 4);
+ if ((opt_type == DHCPOPT_ROUTER) && (opt_len == 4))
+ memcpy(&cli->gateway, opt_data, 4);
+ if ((opt_type == DHCPOPT_NETMASK) && (opt_len == 4))
+ memcpy(&cli->netmask, opt_data, 4);
+ if ((opt_type == DHCPOPT_SERVERID) && (opt_len == 4))
+ memcpy(&cli->server_id, opt_data, 4);
+
+ opt_len = 20;
+ opt_type = dhcp_get_next_option(NULL, opt_data, &opt_len,
&nextopt);
+ }
+ if ((msg_type != DHCP_MSG_OFFER) || !cli->lease_time || !cli->netmask
|| !cli->server_id )
+ return 0;
+ return 1;
+}
+
+static int dhclient_recv_ack(struct dhcp_client_cookie *cli, uint8_t *data,
int len)
+{
+ struct dhcphdr *dhdr = (struct dhcphdr *) data;
+ uint8_t *nextopt, opt_data[20], opt_type;
+ int opt_len = 20;
+ uint8_t msg_type = 0xFF;
+
+ if (dhdr->xid != cli->xid)
+ return 0;
+
+ if (!is_options_valid(dhdr->options, len - sizeof(struct dhcphdr)))
+ return 0;
+
+
+ opt_type = dhcp_get_next_option(dhdr->options, opt_data, &opt_len,
&nextopt);
+ while (opt_type != DHCPOPT_END) {
+ if (opt_type == DHCPOPT_MSGTYPE)
+ msg_type = opt_data[0];
+
+ opt_len = 20;
+ opt_type = dhcp_get_next_option(NULL, opt_data, &opt_len,
&nextopt);
+ }
+ if (msg_type != DHCP_MSG_ACK)
+ return 0;
+ return 1;
+}
+
+
+static void dhclient_send(struct dhcp_client_cookie *cli, uint8_t msg_type)
+{
+
+ uint8_t buf_out[DHCP_DATAGRAM_SIZE] = {0};
+ struct dhcphdr *dh_out = (struct dhcphdr *) buf_out;
+ int sent = 0;
+ struct timeval now;
+ int i = 0;
+ gettimeofday(&now, NULL);
+
+ memcpy(dh_out->hwaddr, cli->iface->macaddr, HLEN_ETHER);
+ dh_out->op = DHCP_OP_REQUEST;
+ dh_out->htype = HTYPE_ETHER;
+ dh_out->hlen = HLEN_ETHER;
+ dh_out->xid = cli->xid;
+ dh_out->secs = (msg_type == DHCP_MSG_REQUEST)?0:htons(now.tv_sec -
cli->start_time.tv_sec);
+ dh_out->dhcp_magic = DHCPD_MAGIC_COOKIE;
+
+
+ /* Option: msg type, len 1 */
+ dh_out->options[i++] = DHCPOPT_MSGTYPE;
+ dh_out->options[i++] = 1;
+ dh_out->options[i++] = msg_type;
+
+ if (msg_type == DHCP_MSG_REQUEST) {
+ dh_out->options[i++] = DHCPOPT_REQIP;
+ dh_out->options[i++] = 4;
+ dh_out->options[i++] = (ntohl(cli->address) & 0xFF000000) >> 24;
+ dh_out->options[i++] = (ntohl(cli->address) & 0xFF0000) >> 16;
+ dh_out->options[i++] = (ntohl(cli->address) & 0xFF00) >> 8;
+ dh_out->options[i++] = (ntohl(cli->address) & 0xFF);
+ dh_out->options[i++] = DHCPOPT_SERVERID;
+ dh_out->options[i++] = 4;
+ dh_out->options[i++] = (ntohl(cli->server_id) & 0xFF000000) >>
24;
+ dh_out->options[i++] = (ntohl(cli->server_id) & 0xFF0000) >> 16;
+ dh_out->options[i++] = (ntohl(cli->server_id) & 0xFF00) >> 8;
+ dh_out->options[i++] = (ntohl(cli->server_id) & 0xFF);
+ }
+
+ /* Option: req list, len 4 */
+ dh_out->options[i++] = DHCPOPT_PARMLIST;
+ dh_out->options[i++] = 5;
+ dh_out->options[i++] = DHCPOPT_NETMASK;
+ dh_out->options[i++] = DHCPOPT_BCAST;
+ dh_out->options[i++] = DHCPOPT_TIME;
+ dh_out->options[i++] = DHCPOPT_ROUTER;
+ dh_out->options[i++] = DHCPOPT_HOSTNAME;
+
+ dh_out->options[i] = DHCPOPT_END;
+
+ sent = vder_udpsocket_sendto_broadcast(cli->socket, buf_out,
DHCP_DATAGRAM_SIZE, cli->iface, (uint32_t)(-1), DHCPD_PORT);
+ if (sent < 0) {
+ perror("udp sendto");
+ }
+}
+
+void dhcp_retry(struct dhcp_client_cookie *client)
+{
+ const int MAX_RETRY = 5;
+ if (++client->attempt > MAX_RETRY) {
+ gettimeofday(&client->start_time, NULL);
+ client->attempt = 0;
+ client->xid ^= client->start_time.tv_usec ^
client->start_time.tv_sec;
+ }
+}
+
+void *dhcp_client_loop(void *iface)
+{
+ unsigned char buffer[2000];
+ int len;
+ struct dhcp_client_cookie client;
+ uint16_t from_port;
+ uint32_t from_ip;
+
+ memset(&client, 0, sizeof(client));
+
+ client.iface = (struct vder_iface *) iface;
+ client.state = DHCPSTATE_DISCOVER;
+ client.socket = vder_udpsocket_open(DHCP_CLIENT_PORT);
+ if (!client.socket) {
+ perror("dhcp client socket");
+ return NULL;
+ }
+
+ gettimeofday(&client.start_time, NULL);
+ client.attempt = 0;
+ client.xid = client.start_time.tv_usec ^ client.start_time.tv_sec;
+
+
+ if (!client.socket) {
+ return NULL;
+ }
+
+ while(1) {
+ switch (client.state) {
+ case DHCPSTATE_DISCOVER:
+ dhcp_retry(&client);
+ dhclient_send(&client, DHCP_MSG_DISCOVER);
+ len = vder_udpsocket_recvfrom(client.socket,
buffer, 2000, &from_ip, &from_port, 5000);
+ if (len < 0) {
+ perror("udp recv");
+ return NULL;
+ }
+ if (len > 0) {
+ if (dhclient_recv_offer(&client,
buffer, len)) {
+ client.state =
DHCPSTATE_REQUEST;
+ }
+ }
+ break;
+ case DHCPSTATE_REQUEST:
+ dhclient_send(&client, DHCP_MSG_REQUEST);
+ len = vder_udpsocket_recvfrom(client.socket,
buffer, 2000, &from_ip, &from_port, 10000);
+ if (len < 0) {
+ perror("udp recv");
+ return NULL;
+ }
+ if (len == 0)
+ break;
+ if (dhclient_recv_ack(&client, buffer, len))
+ client.state = DHCPSTATE_ACK;
+ else {
+ if (client.address)
+
vder_iface_address_del(client.iface, client.address);
+ client.state = DHCPSTATE_DISCOVER;
+ client.address = 0;
+ client.netmask = 0;
+ client.gateway = 0;
+ }
+ break;
+ case DHCPSTATE_ACK:
+ vder_iface_address_del(client.iface,
(uint32_t)-1);
+ vder_iface_address_add(client.iface,
client.address, client.netmask);
+ if ((client.gateway != 0) && ((client.gateway &
client.netmask) == (client.address & client.netmask)))
+ vder_route_add(0, 0, client.gateway, 1,
client.iface);
+ sleep(client.lease_time);
+ client.state = DHCPSTATE_REQUEST;
+ break;
+ default:
+ client.address = 0;
+ client.netmask = 0;
+ client.gateway = 0;
+ client.state = DHCPSTATE_DISCOVER;
+ }
+ }
+}
Copied: branches/vde-router/vde-2/src/vde_router/vder_dhcp.h (from rev 527,
branches/vde-router/vde-2/src/vde_router/vder_dhcpd.h)
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_dhcp.h
(rev 0)
+++ branches/vde-router/vde-2/src/vde_router/vder_dhcp.h 2011-12-30
10:33:54 UTC (rev 528)
@@ -0,0 +1,110 @@
+#ifndef __VDER_DHCPD
+#define __VDER_DHCPD
+
+#include "vder_arp.h"
+
+#define DHCPD_PORT (htons(67))
+#define DHCP_CLIENT_PORT (htons(68))
+
+
+#define DHCP_GATEWAY 0x01
+#define DHCP_DNS 0x02
+
+struct vder_dhcpd_settings
+{
+ struct vder_iface *iface;
+ uint32_t my_ip;
+ uint32_t netmask;
+ uint32_t pool_start;
+ uint32_t pool_next;
+ uint32_t pool_end;
+ unsigned long lease_time;
+ uint8_t flags;
+};
+
+#define DHCP_OP_REQUEST 1
+#define DHCP_OP_REPLY 2
+
+#define HTYPE_ETHER 1
+#define HLEN_ETHER 6
+
+#define FLAG_BROADCAST (htons(0xF000))
+
+#define DHCPD_MAGIC_COOKIE (htonl(0x63825363))
+
+/* DHCP OPTIONS, RFC2132 */
+#define DHCPOPT_PAD 0x00
+#define DHCPOPT_NETMASK 0x01
+#define DHCPOPT_TIME 0x02
+#define DHCPOPT_ROUTER 0x03
+#define DHCPOPT_DNS 0x06
+#define DHCPOPT_HOSTNAME 0x0c
+#define DHCPOPT_DOMAINNAME 0x0f
+#define DHCPOPT_MTU 0x1a
+#define DHCPOPT_BCAST 0x1c
+#define DHCPOPT_NETBIOSNS 0x2c
+#define DHCPOPT_NETBIOSSCOPE 0x2f
+
+#define DHCPOPT_REQIP 0x32
+#define DHCPOPT_LEASETIME 0x33
+#define DHCPOPT_MSGTYPE 0x35
+#define DHCPOPT_SERVERID 0x36
+#define DHCPOPT_PARMLIST 0x37
+#define DHCPOPT_RENEWALTIME 0x3a
+#define DHCPOPT_REBINDINGTIME 0x3b
+#define DHCPOPT_DOMAINSEARCH 0x77
+#define DHCPOPT_STATICROUTE 0x79
+#define DHCPOPT_END 0xFF
+
+/* DHCP MESSAGE TYPE */
+#define DHCP_MSG_DISCOVER 1
+#define DHCP_MSG_OFFER 2
+#define DHCP_MSG_REQUEST 3
+#define DHCP_MSG_DECLINE 4
+#define DHCP_MSG_ACK 5
+#define DHCP_MSG_NAK 6
+#define DHCP_MSG_RELEASE 7
+#define DHCP_MSG_INFORM 8
+
+
+struct __attribute__((packed)) dhcphdr
+{
+ uint8_t op;
+ uint8_t htype;
+ uint8_t hlen;
+ uint8_t hops; //zero
+ uint32_t xid; //store this in the request
+ uint16_t secs; // ignore
+ uint16_t flags;
+ uint32_t ciaddr; // client address - if asking for renewal
+ uint32_t yiaddr; // your address (client)
+ uint32_t siaddr; // dhcp offered address
+ uint32_t giaddr; // relay agent, bootp.
+ uint8_t hwaddr[6];
+ uint8_t hwaddr_padding[10];
+ char hostname[64];
+ char bootp_filename[128];
+ uint32_t dhcp_magic;
+ uint8_t options[0];
+};
+
+enum dhcp_negotiation_state {
+ DHCPSTATE_DISCOVER = 0,
+ DHCPSTATE_OFFER,
+ DHCPSTATE_REQUEST,
+ DHCPSTATE_ACK
+};
+
+struct vder_dhcp_negotiation {
+ struct vder_dhcp_negotiation *next;
+ uint32_t xid;
+ uint8_t hwaddr[6];
+ uint32_t assigned_address;
+ enum dhcp_negotiation_state state;
+ struct vder_arp_entry *arp;
+};
+
+void *dhcp_server_loop(void *ptr_iface);
+void *dhcp_client_loop(void *ptr_iface);
+
+#endif
Deleted: branches/vde-router/vde-2/src/vde_router/vder_dhcpd.c
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_dhcpd.c 2011-12-27
14:45:35 UTC (rev 527)
+++ branches/vde-router/vde-2/src/vde_router/vder_dhcpd.c 2011-12-30
10:33:54 UTC (rev 528)
@@ -1,232 +0,0 @@
-#include "vder_udp.h"
-#include "vder_arp.h"
-#include "vder_dhcpd.h"
-#include <stdio.h>
-
-static struct vder_dhcp_negotiation *Negotiation_list;
-static struct vder_udp_socket *udpsock;
-static struct vder_dhcpd_settings Settings;
-
-static struct vder_dhcp_negotiation *
-get_negotiation_by_xid(uint32_t xid)
-{
- struct vder_dhcp_negotiation *cur = Negotiation_list;
- while (cur) {
- if (cur->xid == xid)
- return cur;
- cur = cur->next;
- }
- return NULL;
-}
-
-static uint8_t dhcp_get_next_option(uint8_t *begin, uint8_t *data, int *len,
uint8_t **nextopt)
-{
- uint8_t *p;
- uint8_t type;
- uint8_t opt_len;
-
- if (!begin)
- p = *nextopt;
- else
- p = begin;
-
- type = *p;
- *nextopt = ++p;
- if ((type == DHCPOPT_END) || (type == DHCPOPT_PAD)) {
- memset(data, 0, *len);
- len = 0;
- return type;
- }
- opt_len = *p;
- p++;
- if (*len > opt_len)
- *len = opt_len;
- memcpy(data, p, *len);
- *nextopt = p + opt_len;
- return type;
-}
-
-static int is_options_valid(uint8_t *opt_buffer, int len)
-{
- uint8_t *p = opt_buffer;
- while (len > 0) {
- if (*p == DHCPOPT_END)
- return 1;
- else if (*p == DHCPOPT_PAD) {
- p++;
- len--;
- } else {
- uint8_t opt_len;
- p++;
- len--;
- opt_len = *p;
- p += opt_len + 1;
- len -= opt_len;
- }
- }
- return 0;
-}
-
-#define DHCP_OFFER_SIZE 308
-#define OPENDNS (htonl(0xd043dede))
-
-static void dhcpd_make_reply(struct vder_dhcp_negotiation *dn, uint8_t
reply_type)
-{
-
- uint8_t buf_out[DHCP_OFFER_SIZE] = {0};
- struct dhcphdr *dh_out = (struct dhcphdr *) buf_out;
- uint32_t server_address = vder_get_right_localip(Settings.iface,
Settings.pool_next);
- uint32_t netmask = vder_get_netmask(Settings.iface, server_address);
- uint32_t bcast = vder_get_broadcast(server_address, netmask);
- uint32_t dns_server = OPENDNS;
-
- int sent = 0;
-
-
- memcpy(dh_out->hwaddr, dn->hwaddr, HLEN_ETHER);
- dh_out->op = DHCP_OP_REPLY;
- dh_out->htype = HTYPE_ETHER;
- dh_out->hlen = HLEN_ETHER;
- dh_out->xid = dn->xid;
- dh_out->yiaddr = dn->arp->ipaddr;
- dh_out->siaddr = server_address;
- dh_out->dhcp_magic = DHCPD_MAGIC_COOKIE;
-
- /* Option: msg type, len 1 */
- dh_out->options[0] = DHCPOPT_MSGTYPE;
- dh_out->options[1] = 1;
- dh_out->options[2] = reply_type;
-
- /* Option: server id, len 4 */
- dh_out->options[3] = DHCPOPT_SERVERID;
- dh_out->options[4] = 4;
- memcpy(dh_out->options + 5, &server_address, 4);
-
- /* Option: Lease time, len 4 */
- dh_out->options[9] = DHCPOPT_LEASETIME;
- dh_out->options[10] = 4;
- memcpy(dh_out->options + 11, &Settings.lease_time, 4);
-
- /* Option: Netmask, len 4 */
- dh_out->options[15] = DHCPOPT_NETMASK;
- dh_out->options[16] = 4;
- memcpy(dh_out->options + 17, &netmask, 4);
-
- /* Option: Router, len 4 */
- dh_out->options[21] = DHCPOPT_ROUTER;
- dh_out->options[22] = 4;
- memcpy(dh_out->options + 23, &server_address, 4);
-
- /* Option: Broadcast, len 4 */
- dh_out->options[27] = DHCPOPT_BCAST;
- dh_out->options[28] = 4;
- memcpy(dh_out->options + 29, &bcast, 4);
-
- /* Option: DNS, len 4 */
- dh_out->options[33] = DHCPOPT_DNS;
- dh_out->options[34] = 4;
- memcpy(dh_out->options + 35, &dns_server, 4);
-
- dh_out->options[40] = DHCPOPT_END;
-
- sent = vder_udpsocket_sendto(udpsock, buf_out, DHCP_OFFER_SIZE,
dh_out->yiaddr, DHCP_CLIENT_PORT);
- if (sent < 0) {
- perror("udp sendto");
- }
-}
-
-#define dhcpd_make_offer(x) dhcpd_make_reply(x, DHCP_MSG_OFFER)
-#define dhcpd_make_ack(x) dhcpd_make_reply(x, DHCP_MSG_ACK)
-
-#define ip_inrange(x) ((ntohl(x) >= ntohl(Settings.pool_start)) && (ntohl(x)
<= ntohl(Settings.pool_end)))
-
-static void dhcp_recv(uint8_t *buffer, int len)
-{
- struct dhcphdr *dhdr = (struct dhcphdr *) buffer;
- struct vder_dhcp_negotiation *dn = get_negotiation_by_xid(dhdr->xid);
- uint8_t *nextopt, opt_data[20], opt_type;
- int opt_len = 20;
-
-
- if (!is_options_valid(dhdr->options, len - sizeof(struct dhcphdr)))
- return;
-
-
-
- if (!dn) {
- dn = malloc(sizeof(struct vder_dhcp_negotiation));
- memset(dn, 0, sizeof(struct vder_dhcp_negotiation));
- dn->xid = dhdr->xid;
- dn->state = DHCPSTATE_DISCOVER;
- memcpy(dn->hwaddr, dhdr->hwaddr, HLEN_ETHER);
- dn->next = Negotiation_list;
- Negotiation_list = dn;
- dn->arp = vder_arp_get_record_by_macaddr(Settings.iface,
dn->hwaddr);
- if (!dn->arp) {
- dn->arp = malloc(sizeof(struct vder_arp_entry));
- if (!dn->arp)
- return;
- memcpy(dn->arp->macaddr, dn->hwaddr, HLEN_ETHER);
- dn->arp->ipaddr = Settings.pool_next;
- Settings.pool_next = htonl(ntohl(Settings.pool_next) +
1);
- vder_add_arp_entry(Settings.iface, dn->arp);
- }
- }
-
- if (!ip_inrange(dn->arp->ipaddr))
- return;
-
-
- opt_type = dhcp_get_next_option(dhdr->options, opt_data, &opt_len,
&nextopt);
- while (opt_type != DHCPOPT_END) {
- /* parse interesting options here */
- if (opt_type == DHCPOPT_MSGTYPE) {
-
- /* server simple state machine */
- uint8_t msg_type = opt_data[0];
- if (msg_type == DHCP_MSG_DISCOVER) {
- dhcpd_make_offer(dn);
- dn->state = DHCPSTATE_OFFER;
- return;
- } else if (msg_type == DHCP_MSG_REQUEST) {
- dhcpd_make_ack(dn);
- return;
- }
- }
- opt_len = 20;
- opt_type = dhcp_get_next_option(NULL, opt_data, &opt_len,
&nextopt);
- }
-}
-
-
-void *dhcp_server_loop(void *ptr_settings)
-{
- uint32_t from_ip;
- uint16_t from_port;
-
- unsigned char buffer[2000];
- int len;
-
- memcpy(&Settings, ptr_settings, sizeof(struct vder_dhcpd_settings));
- Settings.pool_next = Settings.pool_start;
- free(ptr_settings);
-
-
- if(!Settings.iface)
- return NULL;
- udpsock = vder_udpsocket_open(DHCPD_PORT);
- if (!udpsock) {
- return NULL;
- }
-
- while(1) {
- len = vder_udpsocket_recvfrom(udpsock, buffer, 2000, &from_ip,
&from_port);
- if (len < 0) {
- perror("udp recv");
- return NULL;
- }
- if ((from_ip == 0) && (from_port == DHCP_CLIENT_PORT)) {
- dhcp_recv(buffer, len);
- }
- }
-}
Deleted: branches/vde-router/vde-2/src/vde_router/vder_dhcpd.h
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_dhcpd.h 2011-12-27
14:45:35 UTC (rev 527)
+++ branches/vde-router/vde-2/src/vde_router/vder_dhcpd.h 2011-12-30
10:33:54 UTC (rev 528)
@@ -1,100 +0,0 @@
-#ifndef __VDER_DHCPD
-#define __VDER_DHCPD
-
-#include "vder_arp.h"
-
-#define DHCPD_PORT (htons(67))
-#define DHCP_CLIENT_PORT (htons(68))
-
-
-#define DHCP_GATEWAY 0x01
-#define DHCP_DNS 0x02
-
-struct vder_dhcpd_settings
-{
- struct vder_iface *iface;
- uint32_t my_ip;
- uint32_t netmask;
- uint32_t pool_start;
- uint32_t pool_next;
- uint32_t pool_end;
- unsigned long lease_time;
- uint8_t flags;
-};
-
-#define DHCP_OP_REQUEST 1
-#define DHCP_OP_REPLY 2
-
-#define HTYPE_ETHER 1
-#define HLEN_ETHER 6
-
-#define FLAG_BROADCAST (htons(0xF000))
-
-#define DHCPD_MAGIC_COOKIE (htonl(0x63825363))
-
-/* DHCP OPTIONS, RFC2132 */
-#define DHCPOPT_PAD 0x00
-#define DHCPOPT_NETMASK 0x01
-#define DHCPOPT_ROUTER 0x03
-#define DHCPOPT_DNS 0x06
-#define DHCPOPT_BCAST 0x1c
-#define DHCPOPT_REQIP 0x32
-#define DHCPOPT_LEASETIME 0x33
-#define DHCPOPT_MSGTYPE 0x35
-#define DHCPOPT_SERVERID 0x36
-#define DHCPOPT_PARMLIST 0x37
-#define DHCPOPT_RENEWALTIME 0x3a
-#define DHCPOPT_REBINDINGTIME 0x3b
-#define DHCPOPT_END 0xFF
-
-/* DHCP MESSAGE TYPE */
-#define DHCP_MSG_DISCOVER 1
-#define DHCP_MSG_OFFER 2
-#define DHCP_MSG_REQUEST 3
-#define DHCP_MSG_DECLINE 4
-#define DHCP_MSG_ACK 5
-#define DHCP_MSG_NAK 6
-#define DHCP_MSG_RELEASE 7
-#define DHCP_MSG_INFORM 8
-
-
-struct __attribute__((packed)) dhcphdr
-{
- uint8_t op;
- uint8_t htype;
- uint8_t hlen;
- uint8_t hops; //zero
- uint32_t xid; //store this in the request
- uint16_t secs; // ignore
- uint16_t flags;
- uint32_t ciaddr; // client address - if asking for renewal
- uint32_t yiaddr; // your address (client)
- uint32_t siaddr; // dhcp offered address
- uint32_t giaddr; // relay agent, bootp.
- uint8_t hwaddr[6];
- uint8_t hwaddr_padding[10];
- char hostname[64];
- char bootp_filename[128];
- uint32_t dhcp_magic;
- uint8_t options[0];
-};
-
-enum dhcp_negotiation_state {
- DHCPSTATE_DISCOVER = 0,
- DHCPSTATE_OFFER,
- DHCPSTATE_REQUEST,
- DHCPSTATE_ACK
-};
-
-struct vder_dhcp_negotiation {
- struct vder_dhcp_negotiation *next;
- uint32_t xid;
- uint8_t hwaddr[6];
- uint32_t assigned_address;
- enum dhcp_negotiation_state state;
- struct vder_arp_entry *arp;
-};
-
-void *dhcp_server_loop(void *ptr_iface);
-
-#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-27
14:45:35 UTC (rev 527)
+++ branches/vde-router/vde-2/src/vde_router/vder_packet.c 2011-12-30
10:33:54 UTC (rev 528)
@@ -77,9 +77,9 @@
int recvd = 0;
int is_broadcast = vder_ipaddress_is_broadcast(iph->daddr);
-
if (!vder_ipaddress_is_local(iph->daddr) && !is_broadcast)
return 0;
+
switch(iph->protocol) {
case PROTO_ICMP:
vder_icmp_recv(vb);
@@ -125,7 +125,28 @@
return vder_sendto(ro->iface, vdb, ae->macaddr);
}
+int vder_packet_broadcast(struct vde_buff *vdb, struct vder_iface *iface,
uint32_t dst_ip, uint8_t protocol)
+{
+ struct iphdr *iph=iphead(vdb);
+ struct vde_ethernet_header *eth = ethhead(vdb);
+ uint8_t bcast_macaddr[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
+ eth->buftype = htons(PTYPE_IP);
+
+ memset(iph,0x45,1);
+ iph->tos = 0;
+ iph->frag_off=htons(0x4000); // Don't fragment.
+ iph->tot_len = htons(vdb->len - sizeof(struct vde_ethernet_header));
+ iph->id = 0;
+ iph->protocol = protocol;
+ iph->ttl = DEFAULT_TTL;
+ iph->daddr = dst_ip;
+ //iph->saddr = vder_get_right_localip(iface, iph->daddr);
+ iph->saddr = 0;
+ iph->check = htons(vder_ip_checksum(iph));
+ return vder_sendto(iface, vdb, bcast_macaddr);
+}
+
void vder_packet_recv(struct vder_iface *vif, int timeout)
{
struct pollfd pfd;
Modified: branches/vde-router/vde-2/src/vde_router/vder_packet.h
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_packet.h 2011-12-27
14:45:35 UTC (rev 527)
+++ branches/vde-router/vde-2/src/vde_router/vder_packet.h 2011-12-30
10:33:54 UTC (rev 528)
@@ -11,6 +11,7 @@
void vder_packet_recv(struct vder_iface *vif, int timeout);
uint16_t net_checksum(void *inbuf, int len);
int vder_packet_send(struct vde_buff *vdb, uint32_t dst_ip, uint8_t protocol);
+int vder_packet_broadcast(struct vde_buff *vdb, struct vder_iface *iface,
uint32_t dst_ip, uint8_t protocol);
char *vder_ntoa(uint32_t addr);
#endif
Modified: branches/vde-router/vde-2/src/vde_router/vder_queue.c
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_queue.c 2011-12-27
14:45:35 UTC (rev 527)
+++ branches/vde-router/vde-2/src/vde_router/vder_queue.c 2011-12-30
10:33:54 UTC (rev 528)
@@ -156,8 +156,6 @@
}
-
-
void qred_setup(struct vder_queue *q, uint32_t min, uint32_t max, double P,
uint32_t limit)
{
pthread_mutex_lock(&q->lock);
Modified: branches/vde-router/vde-2/src/vde_router/vder_udp.c
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_udp.c 2011-12-27 14:45:35 UTC
(rev 527)
+++ branches/vde-router/vde-2/src/vde_router/vder_udp.c 2011-12-30 10:33:54 UTC
(rev 528)
@@ -1,5 +1,6 @@
#include "vder_udp.h"
#include <stdio.h>
+#include <unistd.h>
/* UDP header, rfc 768 */
@@ -17,6 +18,7 @@
int found = 0;
struct vde_buff *copy = NULL;
uint16_t port = transport_dport(buf);
+
while(cur) {
if (cur->port == port) {
if (!found) {
@@ -88,6 +90,7 @@
errno = EINVAL;
return -1;
}
+
ro = vder_get_route(dst);
if (!ro) {
errno = EHOSTUNREACH;
@@ -113,8 +116,39 @@
return len;
}
+int vder_udpsocket_sendto_broadcast(struct vder_udp_socket *sock, void *data,
size_t len,
+ struct vder_iface *iface, uint32_t dst, uint16_t dstport)
+{
+ struct vde_buff *b;
+ struct udphdr *uh;
+ uint8_t *datagram;
+ int bufsize;
+ if (len <= 0) {
+ errno = EINVAL;
+ return -1;
+ }
-int vder_udpsocket_recvfrom(struct vder_udp_socket *sock, void *data, size_t
len, uint32_t *from, uint16_t *fromport)
+ bufsize = sizeof(struct vde_buff) + sizeof(struct vde_ethernet_header)
+ sizeof(struct iphdr) + sizeof(struct udphdr) + len;
+ b = malloc(bufsize);
+ if (!b)
+ return -1;
+ b->len = bufsize - sizeof(struct vde_buff);
+ b->src = NULL;
+ b->priority = PRIO_BESTEFFORT;
+ uh = (struct udphdr *) payload(b);
+ datagram = (uint8_t *)((payload(b) + sizeof(struct udphdr)));
+ memcpy(datagram, data, len);
+
+ uh->sport = sock->port;
+ uh->dport = dstport;
+ uh->len = htons(len);
+ uh->crc = 0;
+ vder_packet_broadcast(b, iface, dst, PROTO_UDP);
+ return len;
+}
+
+
+int vder_udpsocket_recvfrom(struct vder_udp_socket *sock, void *data, size_t
len, uint32_t *from, uint16_t *fromport, int timeout)
{
struct vde_buff *b;
struct udphdr *uh;
@@ -125,6 +159,17 @@
return -1;
}
+ while ((timeout > 0) && (sock->inq.n == 0)) {
+ usleep(10000);
+ timeout -= 10;
+ if (timeout < 0)
+ timeout = 0;
+ }
+
+ if ((timeout == 0) && (sock->inq.n == 0)) {
+ return 0;
+ }
+
do {
b = dequeue(&sock->inq);
} while(!b);
Modified: branches/vde-router/vde-2/src/vde_router/vder_udp.h
===================================================================
--- branches/vde-router/vde-2/src/vde_router/vder_udp.h 2011-12-27 14:45:35 UTC
(rev 527)
+++ branches/vde-router/vde-2/src/vde_router/vder_udp.h 2011-12-30 10:33:54 UTC
(rev 528)
@@ -27,6 +27,8 @@
struct vder_udp_socket *vder_udpsocket_open(uint16_t port);
void vder_udp_close(struct vder_udp_socket *sock);
int vder_udpsocket_sendto(struct vder_udp_socket *sock, void *data, size_t
len, uint32_t dst, uint16_t dstport);
-int vder_udpsocket_recvfrom(struct vder_udp_socket *sock, void *data, size_t
len, uint32_t *from, uint16_t *fromport);
+int vder_udpsocket_sendto_broadcast(struct vder_udp_socket *sock, void *data,
size_t len,
+ struct vder_iface *iface, uint32_t dst, uint16_t dstport);
+int vder_udpsocket_recvfrom(struct vder_udp_socket *sock, void *data, size_t
len, uint32_t *from, uint16_t *fromport, int timeout);
#endif
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Ridiculously easy VDI. With Citrix VDI-in-a-Box, you don't need a complex
infrastructure or vast IT resources to deliver seamless, secure access to
virtual desktops. With this all-in-one solution, easily deploy virtual
desktops for less than the cost of PCs and save 60% on VDI infrastructure
costs. Try it free! http://p.sf.net/sfu/Citrix-VDIinabox
_______________________________________________
vde-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vde-users