Removing IPv4 stack

This commit is contained in:
Simon Duquennoy 2017-06-16 17:02:42 +02:00
parent d61cb46e59
commit 1a0f8ab737
69 changed files with 124 additions and 7608 deletions

View File

@ -66,11 +66,6 @@ MODULES += core/sys core/dev core/lib
# Include IPv6, IPv4, and/or Rime
HAS_STACK = 0
ifeq ($(CONTIKI_WITH_IPV4),1)
HAS_STACK = 1
CFLAGS += -DNETSTACK_CONF_WITH_IPV4=1
MODULES += core/net/ipv4 core/net/ip
endif
# Make IPv6 the default stack
ifeq ($(HAS_STACK),0)

View File

@ -67,11 +67,7 @@
/* direct access into the buffer */
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
#if NETSTACK_CONF_WITH_IPV6
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
#else
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
#endif
/* bitmap for set options */
enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 };

View File

@ -158,14 +158,6 @@
#define UIP_CONF_MAX_CONNECTIONS 8
#endif /* UIP_CONF_MAX_CONNECTIONS */
/* UIP_CONF_TCP_SPLIT enables a performance optimization hack, where
each maximum-sized TCP segment is split into two, to avoid the
performance degradation that is caused by delayed ACKs. */
#ifndef UIP_CONF_TCP_SPLIT
#define UIP_CONF_TCP_SPLIT 0
#endif /* UIP_CONF_TCP_SPLIT */
/* NBR_TABLE_CONF_MAX_NEIGHBORS specifies the maximum number of neighbors
that each node will be able to handle. */
#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS

View File

@ -38,9 +38,6 @@
#include "net/ip/tcpip.h"
#include "net/ip/uip.h"
#include "net/ipv4/uip-fw.h"
#include "net/ipv4/uip-fw-drv.h"
#include "net/ipv4/uip_arp.h"
#include "net/ip/uiplib.h"
#include "net/ip/uip-udp-packet.h"
#include "net/ip/simple-udp.h"

View File

@ -38,7 +38,6 @@
#include "contiki.h"
#include "net/ip/uip.h"
#include "net/ipv4/uip-fw.h"
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#include "dev/slip.h"
@ -166,9 +165,9 @@ slip_poll_handler(uint8_t *outbuf, uint16_t blen)
&& memcmp(&rxbuf[begin], "CLIENT", 6) == 0) {
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
memset(&rxbuf[begin], 0x0, 6);
rxbuf_init();
for(i = 0; i < 13; i++) {
slip_arch_writeb("CLIENTSERVER\300"[i]);
}
@ -178,7 +177,7 @@ slip_poll_handler(uint8_t *outbuf, uint16_t blen)
#endif /* SLIP_CONF_MICROSOFT_CHAT */
#ifdef SLIP_CONF_ANSWER_MAC_REQUEST
else if(rxbuf[begin] == '?') {
else if(rxbuf[begin] == '?') {
/* Used by tapslip6 to request mac for auto configure */
int i, j;
char* hexchar = "0123456789abcdef";
@ -187,9 +186,9 @@ slip_poll_handler(uint8_t *outbuf, uint16_t blen)
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
rxbuf[begin] = 0;
rxbuf[begin + 1] = 0;
rxbuf_init();
linkaddr_t addr = get_mac_addr();
/* this is just a test so far... just to see if it works */
slip_arch_writeb('!');
@ -328,47 +327,13 @@ PROCESS_THREAD(slip_process, ev, data)
while(1) {
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
slip_active = 1;
/* Move packet from rxbuf to buffer provided by uIP. */
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
UIP_BUFSIZE - UIP_LLH_LEN);
#if !NETSTACK_CONF_WITH_IPV6
if(uip_len == 4 && strncmp((char*)&uip_buf[UIP_LLH_LEN], "?IPA", 4) == 0) {
char buf[8];
memcpy(&buf[0], "=IPA", 4);
memcpy(&buf[4], &uip_hostaddr, 4);
if(input_callback) {
input_callback();
}
slip_write(buf, 8);
} else if(uip_len > 0
&& uip_len == (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1])
&& uip_ipchksum() == 0xffff) {
#define IP_DF 0x40
if(BUF->ipid[0] == 0 && BUF->ipid[1] == 0 && BUF->ipoffset[0] & IP_DF) {
static uint16_t ip_id;
uint16_t nid = ip_id++;
BUF->ipid[0] = nid >> 8;
BUF->ipid[1] = nid;
nid = uip_htons(nid);
nid = ~nid; /* negate */
BUF->ipchksum += nid; /* add */
if(BUF->ipchksum < nid) { /* 1-complement overflow? */
BUF->ipchksum++;
}
}
#ifdef SLIP_CONF_TCPIP_INPUT
SLIP_CONF_TCPIP_INPUT();
#else
tcpip_input();
#endif
} else {
uip_clear_buf();
SLIP_STATISTICS(slip_ip_drop++);
}
#else /* NETSTACK_CONF_WITH_IPV6 */
if(uip_len > 0) {
if(input_callback) {
input_callback();
@ -379,7 +344,6 @@ PROCESS_THREAD(slip_process, ev, data)
tcpip_input();
#endif
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
PROCESS_END();

View File

@ -189,11 +189,7 @@ int strncasecmp(const char *s1, const char *s2, size_t n);
#define DNS_TYPE_ANY 255
#define DNS_TYPE_NSEC 47
#if NETSTACK_CONF_WITH_IPV6
#define NATIVE_DNS_TYPE DNS_TYPE_AAAA /* IPv6 */
#else
#define NATIVE_DNS_TYPE DNS_TYPE_A /* IPv4 */
#endif
#define DNS_CLASS_IN 1
#define DNS_CLASS_ANY 255
@ -239,11 +235,7 @@ struct dns_answer {
uint16_t class;
uint16_t ttl[2];
uint16_t len;
#if NETSTACK_CONF_WITH_IPV6
uint8_t ipaddr[16];
#else
uint8_t ipaddr[4];
#endif
};
struct namemap {
@ -307,13 +299,10 @@ enum {
static uint8_t mdns_state;
static const uip_ipaddr_t resolv_mdns_addr =
#if NETSTACK_CONF_WITH_IPV6
{ { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb } };
#include "net/ipv6/uip-ds6.h"
#else /* NETSTACK_CONF_WITH_IPV6 */
{ { 224, 0, 0, 251 } };
#endif /* NETSTACK_CONF_WITH_IPV6 */
static int mdns_needs_host_announce;
PROCESS(mdns_probe_process, "mDNS probe");
@ -498,7 +487,6 @@ start_name_collision_check(clock_time_t after)
static unsigned char *
mdns_write_announce_records(unsigned char *queryptr, uint8_t *count)
{
#if NETSTACK_CONF_WITH_IPV6
uint8_t i;
for(i = 0; i < UIP_DS6_ADDR_NB; ++i) {
@ -534,20 +522,6 @@ mdns_write_announce_records(unsigned char *queryptr, uint8_t *count)
++(*count);
}
}
#else /* NETSTACK_CONF_WITH_IPV6 */
struct dns_answer *ans;
queryptr = encode_name(queryptr, resolv_hostname);
ans = (struct dns_answer *)queryptr;
ans->type = UIP_HTONS(NATIVE_DNS_TYPE);
ans->class = UIP_HTONS(DNS_CLASS_IN | 0x8000);
ans->ttl[0] = 0;
ans->ttl[1] = UIP_HTONS(120);
ans->len = UIP_HTONS(sizeof(uip_ipaddr_t));
uip_gethostaddr((uip_ipaddr_t *) ans->ipaddr);
queryptr = (unsigned char *)ans + sizeof(*ans);
++(*count);
#endif /* NETSTACK_CONF_WITH_IPV6 */
return queryptr;
}
/*---------------------------------------------------------------------------*/
@ -576,17 +550,10 @@ mdns_prep_host_announce_packet(void)
0x00,
0x04,
#if NETSTACK_CONF_WITH_IPV6
0x00,
0x00,
0x00,
0x08,
#else /* NETSTACK_CONF_WITH_IPV6 */
0x40,
0x00,
0x00,
0x00,
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
};
@ -761,7 +728,7 @@ check_entries(void)
uip_udp_packet_sendto(resolv_conn, uip_appdata,
(query - (uint8_t *) uip_appdata),
(const uip_ipaddr_t *)
uip_nameserver_get(namemapptr->server),
uip_nameserver_get(namemapptr->server),
UIP_HTONS(DNS_PORT));
PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
@ -770,7 +737,7 @@ check_entries(void)
#else /* RESOLV_CONF_SUPPORTS_MDNS */
uip_udp_packet_sendto(resolv_conn, uip_appdata,
(query - (uint8_t *) uip_appdata),
uip_nameserver_get(namemapptr->server),
uip_nameserver_get(namemapptr->server),
UIP_HTONS(DNS_PORT));
PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
namemapptr->name);
@ -1067,10 +1034,10 @@ newdata(void)
/* Got to this point there's no answer, try next nameserver if available
since this one doesn't know the answer */
#if RESOLV_CONF_SUPPORTS_MDNS
if(nanswers == 0 && UIP_UDP_BUF->srcport != UIP_HTONS(MDNS_PORT)
if(nanswers == 0 && UIP_UDP_BUF->srcport != UIP_HTONS(MDNS_PORT)
&& hdr->id != 0)
#else
if(nanswers == 0)
if(nanswers == 0)
#endif
{
if(try_next_server(namemapptr)) {
@ -1173,11 +1140,7 @@ PROCESS_THREAD(resolv_process, ev, data)
PRINTF("resolver: Supports MDNS.\n");
uip_udp_bind(resolv_conn, UIP_HTONS(MDNS_PORT));
#if NETSTACK_CONF_WITH_IPV6
uip_ds6_maddr_add(&resolv_mdns_addr);
#else
/* TODO: Is there anything we need to do here for IPv4 multicast? */
#endif
resolv_set_hostname(CONTIKI_CONF_DEFAULT_HOSTNAME);
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
@ -1276,7 +1239,7 @@ resolv_query(const char *name)
register struct namemap *nameptr = 0;
init();
lseq = lseqi = 0;
/* Remove trailing dots, if present. */
@ -1360,12 +1323,8 @@ resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr)
#if UIP_CONF_LOOPBACK_INTERFACE
if(strcmp(name, "localhost")) {
static uip_ipaddr_t loopback =
#if NETSTACK_CONF_WITH_IPV6
{ { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } };
#else /* NETSTACK_CONF_WITH_IPV6 */
{ { 127, 0, 0, 1 } };
#endif /* NETSTACK_CONF_WITH_IPV6 */
if(ipaddr) {
*ipaddr = &loopback;
}
@ -1448,11 +1407,7 @@ resolv_found(char *name, uip_ipaddr_t * ipaddr)
#if RESOLV_CONF_SUPPORTS_MDNS
if(strncasecmp(resolv_hostname, name, strlen(resolv_hostname)) == 0 &&
ipaddr
#if NETSTACK_CONF_WITH_IPV6
&& !uip_ds6_is_my_addr(ipaddr)
#else
&& uip_ipaddr_cmp(&uip_hostaddr, ipaddr) != 0
#endif
) {
uint8_t i;

View File

@ -39,13 +39,10 @@
*/
#include "contiki-net.h"
#include "net/ip/uip-split.h"
#include "net/ip/uip-packetqueue.h"
#if NETSTACK_CONF_WITH_IPV6
#include "net/ipv6/uip-nd6.h"
#include "net/ipv6/uip-ds6.h"
#endif
#if UIP_CONF_IPV6_RPL
#include "net/rpl/rpl.h"
@ -85,7 +82,7 @@ process_event_t tcpip_icmp6_event;
/* Periodic check of active connections. */
static struct etimer periodic;
#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_REASSEMBLY
#if UIP_CONF_IPV6_REASSEMBLY
/* Timer for reassembly. */
extern struct etimer uip_reass_timer;
#endif
@ -111,8 +108,7 @@ enum {
PACKET_INPUT
};
/* Called on IP packet output. */
#if NETSTACK_CONF_WITH_IPV6
static uint8_t (* outputfunc)(const uip_lladdr_t *a);
@ -133,34 +129,11 @@ tcpip_set_outputfunc(uint8_t (*f)(const uip_lladdr_t *))
{
outputfunc = f;
}
#else
static uint8_t (* outputfunc)(void);
uint8_t
tcpip_output(void)
{
if(outputfunc != NULL) {
return outputfunc();
}
UIP_LOG("tcpip_output: Use tcpip_set_outputfunc() to set an output function");
return 0;
}
void
tcpip_set_outputfunc(uint8_t (*f)(void))
{
outputfunc = f;
}
#endif
#if UIP_CONF_IP_FORWARD
unsigned char tcpip_is_forwarding; /* Forwarding right now? */
#endif /* UIP_CONF_IP_FORWARD */
PROCESS(tcpip_process, "TCP/IP stack");
/*---------------------------------------------------------------------------*/
#if UIP_TCP || UIP_CONF_IP_FORWARD
#if UIP_TCP
static void
start_periodic_tcp_timer(void)
{
@ -168,12 +141,12 @@ start_periodic_tcp_timer(void)
etimer_restart(&periodic);
}
}
#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */
#endif /* UIP_TCP */
/*---------------------------------------------------------------------------*/
static void
check_for_tcp_syn(void)
{
#if UIP_TCP || UIP_CONF_IP_FORWARD
#if UIP_TCP
/* This is a hack that is needed to start the periodic TCP timer if
an incoming packet contains a SYN: since uIP does not inform the
application if a SYN arrives, we have no other way of starting
@ -184,36 +157,17 @@ check_for_tcp_syn(void)
(UIP_TCP_BUF->flags & TCP_SYN) == TCP_SYN) {
start_periodic_tcp_timer();
}
#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */
#endif /* UIP_TCP */
}
/*---------------------------------------------------------------------------*/
static void
packet_input(void)
{
if(uip_len > 0) {
#if UIP_CONF_IP_FORWARD
tcpip_is_forwarding = 1;
if(uip_fw_forward() != UIP_FW_LOCAL) {
tcpip_is_forwarding = 0;
return;
}
tcpip_is_forwarding = 0;
#endif /* UIP_CONF_IP_FORWARD */
check_for_tcp_syn();
uip_input();
if(uip_len > 0) {
#if UIP_CONF_TCP_SPLIT
uip_split_output();
#else /* UIP_CONF_TCP_SPLIT */
#if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output();
#else /* NETSTACK_CONF_WITH_IPV6 */
PRINTF("tcpip packet_input output len %d\n", uip_len);
tcpip_output();
#endif /* NETSTACK_CONF_WITH_IPV6 */
#endif /* UIP_CONF_TCP_SPLIT */
}
}
}
@ -324,11 +278,8 @@ udp_broadcast_new(uint16_t port, void *appstate)
uip_ipaddr_t addr;
struct uip_udp_conn *conn;
#if NETSTACK_CONF_WITH_IPV6
uip_create_linklocal_allnodes_mcast(&addr);
#else
uip_ipaddr(&addr, 255,255,255,255);
#endif /* NETSTACK_CONF_WITH_IPV6 */
conn = udp_new(&addr, port, appstate);
if(conn != NULL) {
udp_bind(conn, port);
@ -427,24 +378,12 @@ eventhandler(process_event_t ev, process_data_t data)
connections. */
etimer_restart(&periodic);
uip_periodic(i);
#if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output();
#else
if(uip_len > 0) {
PRINTF("tcpip_output from periodic len %d\n", uip_len);
tcpip_output();
PRINTF("tcpip_output after periodic len %d\n", uip_len);
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
}
#endif /* UIP_TCP */
#if UIP_CONF_IP_FORWARD
uip_fw_periodic();
#endif /* UIP_CONF_IP_FORWARD */
}
#if NETSTACK_CONF_WITH_IPV6
#if UIP_CONF_IPV6_REASSEMBLY
/*
* check the timer for reassembly
@ -476,7 +415,6 @@ eventhandler(process_event_t ev, process_data_t data)
uip_ds6_periodic();
tcpip_ipv6_output();
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
break;
@ -484,14 +422,7 @@ eventhandler(process_event_t ev, process_data_t data)
case TCP_POLL:
if(data != NULL) {
uip_poll_conn(data);
#if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output();
#else /* NETSTACK_CONF_WITH_IPV6 */
if(uip_len > 0) {
PRINTF("tcpip_output from tcp poll len %d\n", uip_len);
tcpip_output();
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
/* Start the periodic polling, if it isn't already active. */
start_periodic_tcp_timer();
}
@ -501,13 +432,7 @@ eventhandler(process_event_t ev, process_data_t data)
case UDP_POLL:
if(data != NULL) {
uip_udp_periodic_conn(data);
#if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output();
#else
if(uip_len > 0) {
tcpip_output();
}
#endif /* UIP_UDP */
}
break;
#endif /* UIP_UDP */
@ -525,7 +450,6 @@ tcpip_input(void)
uip_clear_buf();
}
/*---------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV6
void
tcpip_ipv6_output(void)
{
@ -694,7 +618,7 @@ tcpip_ipv6_output(void)
#else /* UIP_ND6_SEND_NS */
PRINTF("tcpip_ipv6_output: neighbor not in cache\n");
uip_len = 0;
return;
return;
#endif /* UIP_ND6_SEND_NS */
} else {
#if UIP_ND6_SEND_NS
@ -746,7 +670,6 @@ tcpip_ipv6_output(void)
tcpip_output(NULL);
uip_clear_buf();
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
/*---------------------------------------------------------------------------*/
#if UIP_UDP
void
@ -835,7 +758,7 @@ PROCESS_THREAD(tcpip_process, ev, data)
UIP_FALLBACK_INTERFACE.init();
#endif
/* initialize RPL if configured for using RPL */
#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_RPL
#if UIP_CONF_IPV6_RPL
rpl_init();
#endif /* UIP_CONF_IPV6_RPL */

View File

@ -275,7 +275,7 @@ struct uip_udp_conn *udp_broadcast_new(uint16_t port, void *appstate);
CCIF void tcpip_poll_udp(struct uip_udp_conn *conn);
/** @} */
/**
* \name ICMPv6 functions
* @{
@ -340,20 +340,13 @@ CCIF void tcpip_input(void);
* \brief Output packet to layer 2
* The eventual parameter is the MAC address of the destination.
*/
#if NETSTACK_CONF_WITH_IPV6
uint8_t tcpip_output(const uip_lladdr_t *);
void tcpip_set_outputfunc(uint8_t (* f)(const uip_lladdr_t *));
#else
uint8_t tcpip_output(void);
void tcpip_set_outputfunc(uint8_t (* f)(void));
#endif
/**
* \brief This function does address resolution and then calls tcpip_output
*/
#if NETSTACK_CONF_WITH_IPV6
void tcpip_ipv6_output(void);
#endif
/**
* \brief Is forwarding generally enabled?

View File

@ -44,16 +44,15 @@
void
uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
{
#if NETSTACK_CONF_WITH_IPV6
uint16_t a;
unsigned int i;
int f;
#endif /* NETSTACK_CONF_WITH_IPV6 */
if(addr == NULL) {
PRINTA("(NULL IP addr)");
return;
}
#if NETSTACK_CONF_WITH_IPV6
if(ip64_addr_is_ipv4_mapped_addr(addr)) {
/*
* Printing IPv4-mapped addresses is done according to RFC 4291 [1]
@ -85,10 +84,7 @@ uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
}
PRINTA("%x", a);
}
}
}
}
#else /* NETSTACK_CONF_WITH_IPV6 */
PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]);
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
/*---------------------------------------------------------------------------*/

View File

@ -1,158 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include <string.h>
#include "net/ip/uip-split.h"
#include "net/ip/uip.h"
#include "net/ipv4/uip-fw.h"
#include "net/ip/uip_arch.h"
#include "net/ip/tcpip.h"
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#ifdef UIP_SPLIT_CONF_SIZE
#define UIP_SPLIT_SIZE UIP_SPLIT_CONF_SIZE
#else /* UIP_SPLIT_CONF_SIZE */
#define UIP_SPLIT_SIZE UIP_TCP_MSS
#endif /* UIP_SPLIT_CONF_SIZE */
/*-----------------------------------------------------------------------------*/
void
uip_split_output(void)
{
#if UIP_TCP
uint16_t tcplen, len1, len2;
/* We only split TCP segments that are larger than or equal to
UIP_SPLIT_SIZE, which is configurable through
UIP_SPLIT_CONF_SIZE. */
if(BUF->proto == UIP_PROTO_TCP &&
uip_len >= UIP_SPLIT_SIZE + UIP_TCPIP_HLEN) {
tcplen = uip_len - UIP_TCPIP_HLEN;
/* Split the segment in two. If the original packet length was
odd, we make the second packet one byte larger. */
len1 = len2 = tcplen / 2;
if(len1 + len2 < tcplen) {
++len2;
}
/* Create the first packet. This is done by altering the length
field of the IP header and updating the checksums. */
uip_len = len1 + UIP_TCPIP_HLEN;
#if NETSTACK_CONF_WITH_IPV6
/* For IPv6, the IP length field does not include the IPv6 IP header
length. */
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* NETSTACK_CONF_WITH_IPV6 */
BUF->len[0] = uip_len >> 8;
BUF->len[1] = uip_len & 0xff;
#endif /* NETSTACK_CONF_WITH_IPV6 */
/* Recalculate the TCP checksum. */
BUF->tcpchksum = 0;
BUF->tcpchksum = ~(uip_tcpchksum());
#if !NETSTACK_CONF_WITH_IPV6
/* Recalculate the IP checksum. */
BUF->ipchksum = 0;
BUF->ipchksum = ~(uip_ipchksum());
#endif /* NETSTACK_CONF_WITH_IPV6 */
/* Transmit the first packet. */
/* uip_fw_output();*/
#if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output();
#else
tcpip_output();
#endif /* NETSTACK_CONF_WITH_IPV6 */
/* Now, create the second packet. To do this, it is not enough to
just alter the length field, but we must also update the TCP
sequence number and point the uip_appdata to a new place in
memory. This place is detemined by the length of the first
packet (len1). */
uip_len = len2 + UIP_TCPIP_HLEN;
#if NETSTACK_CONF_WITH_IPV6
/* For IPv6, the IP length field does not include the IPv6 IP header
length. */
BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
#else /* NETSTACK_CONF_WITH_IPV6 */
BUF->len[0] = uip_len >> 8;
BUF->len[1] = uip_len & 0xff;
#endif /* NETSTACK_CONF_WITH_IPV6 */
/* uip_appdata += len1;*/
memcpy(uip_appdata, (uint8_t *)uip_appdata + len1, len2);
uip_add32(BUF->seqno, len1);
BUF->seqno[0] = uip_acc32[0];
BUF->seqno[1] = uip_acc32[1];
BUF->seqno[2] = uip_acc32[2];
BUF->seqno[3] = uip_acc32[3];
/* Recalculate the TCP checksum. */
BUF->tcpchksum = 0;
BUF->tcpchksum = ~(uip_tcpchksum());
#if !NETSTACK_CONF_WITH_IPV6
/* Recalculate the IP checksum. */
BUF->ipchksum = 0;
BUF->ipchksum = ~(uip_ipchksum());
#endif /* NETSTACK_CONF_WITH_IPV6 */
/* Transmit the second packet. */
/* uip_fw_output();*/
#if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output();
#else
tcpip_output();
#endif /* NETSTACK_CONF_WITH_IPV6 */
return;
}
#endif /* UIP_TCP */
/* uip_fw_output();*/
#if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output();
#else
tcpip_output();
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
/*-----------------------------------------------------------------------------*/

View File

@ -1,95 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup uipsplit uIP TCP throughput booster hack
* @{
*
* The basic uIP TCP implementation only allows each TCP connection to
* have a single TCP segment in flight at any given time. Because of
* the delayed ACK algorithm employed by most TCP receivers, uIP's
* limit on the amount of in-flight TCP segments seriously reduces the
* maximum achievable throughput for sending data from uIP.
*
* The uip-split module is a hack which tries to remedy this
* situation. By splitting maximum sized outgoing TCP segments into
* two, the delayed ACK algorithm is not invoked at TCP
* receivers. This improves the throughput when sending data from uIP
* by orders of magnitude.
*
* The uip-split module uses the uip-fw module (uIP IP packet
* forwarding) for sending packets. Therefore, the uip-fw module must
* be set up with the appropriate network interfaces for this module
* to work.
*/
/**
* \file
* Module for splitting outbound TCP segments in two to avoid the
* delayed ACK throughput degradation.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef UIP_SPLIT_H_
#define UIP_SPLIT_H_
/**
* Handle outgoing packets.
*
* This function inspects an outgoing packet in the uip_buf buffer and
* sends it out using the uip_fw_output() function. If the packet is a
* full-sized TCP segment it will be split into two segments and
* transmitted separately. This function should be called instead of
* the actual device driver output function, or the uip_fw_output()
* function.
*
* The headers of the outgoing packet is assumed to be in the uip_buf
* buffer and the payload is assumed to be wherever uip_appdata
* points. The length of the outgoing packet is assumed to be in the
* uip_len variable.
*
*/
void uip_split_output(void);
#endif /* UIP_SPLIT_H_ */
/** @} */
/** @} */

View File

@ -53,12 +53,8 @@
#define UIP_H_
/* Header sizes. */
#if NETSTACK_CONF_WITH_IPV6
#define UIP_IPH_LEN 40
#define UIP_FRAGH_LEN 8
#else /* NETSTACK_CONF_WITH_IPV6 */
#define UIP_IPH_LEN 20 /* Size of IP header */
#endif /* NETSTACK_CONF_WITH_IPV6 */
#define UIP_UDPH_LEN 8 /* Size of UDP header */
#define UIP_TCPH_LEN 20 /* Size of TCP header */
@ -1501,7 +1497,18 @@ struct uip_stats {
*/
/*---------------------------------------------------------------------------*/
/**
* The Ethernet header.
*/
struct uip_eth_hdr {
struct uip_eth_addr dest;
struct uip_eth_addr src;
uint16_t type;
};
#define UIP_ETHTYPE_ARP 0x0806
#define UIP_ETHTYPE_IP 0x0800
#define UIP_ETHTYPE_IPV6 0x86dd
/* uint8_t uip_flags:
*
@ -2154,6 +2161,60 @@ CCIF extern uip_lladdr_t uip_lladdr;
#endif /*NETSTACK_CONF_WITH_IPV6*/
/**
* A non-error message that indicates that a packet should be
* processed locally.
*
* \hideinitializer
*/
#define UIP_FW_LOCAL 0
/**
* A non-error message that indicates that something went OK.
*
* \hideinitializer
*/
#define UIP_FW_OK 0
/**
* A non-error message that indicates that a packet was forwarded.
*
* \hideinitializer
*/
#define UIP_FW_FORWARDED 1
/**
* A non-error message that indicates that a zero-length packet
* transmission was attempted, and that no packet was sent.
*
* \hideinitializer
*/
#define UIP_FW_ZEROLEN 2
/**
* An error message that indicates that a packet that was too large
* for the outbound network interface was detected.
*
* \hideinitializer
*/
#define UIP_FW_TOOLARGE 3
/**
* An error message that indicates that no suitable interface could be
* found for an outbound packet.
*
* \hideinitializer
*/
#define UIP_FW_NOROUTE 4
/**
* An error message that indicates that a packet that should be
* forwarded or output was dropped.
*
* \hideinitializer
*/
#define UIP_FW_DROPPED 5
/**
* Calculate the Internet checksum over a buffer.
*

View File

@ -1,145 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Definitions for the micro implementation of the AODV ad hoc routing protocol
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef UAODV_DEF_H_
#define UAODV_DEF_H_
#include "net/ip/uip.h"
#define NUM_PRECURSORS 4
#define UAODV_UDPPORT 654
#if 0
/* AODV routing table entry */
struct uaodv_rtentry {
uip_ipaddr_t dest_addr;
uip_ipaddr_t next_hop;
uip_ipaddr_t precursors[NUM_PRECURSORS];
uint32_t dest_seqno;
uint16_t lifetime;
uint8_t dest_seqno_flag;
uint8_t route_flags;
uint8_t hop_count;
};
#endif
/* Generic AODV message */
struct uaodv_msg {
uint8_t type;
};
/* AODV RREQ message */
#define UAODV_RREQ_TYPE 1
#define UAODV_RREQ_JOIN (1 << 7)
#define UAODV_RREQ_REPAIR (1 << 6)
#define UAODV_RREQ_GRATIOUS (1 << 5)
#define UAODV_RREQ_DESTONLY (1 << 4)
#define UAODV_RREQ_UNKSEQNO (1 << 3)
struct uaodv_msg_rreq {
uint8_t type;
uint8_t flags;
uint8_t reserved;
uint8_t hop_count;
uint32_t rreq_id;
uip_ipaddr_t dest_addr;
uint32_t dest_seqno;
uip_ipaddr_t orig_addr;
uint32_t orig_seqno;
};
/* AODV RREP message */
#define UAODV_RREP_TYPE 2
#define UAODV_RREP_REPAIR (1 << 7)
#define UAODV_RREP_ACK (1 << 6)
struct uaodv_msg_rrep {
uint8_t type;
uint8_t flags;
uint8_t prefix_sz; /* prefix_sz:5 */
uint8_t hop_count;
uip_ipaddr_t dest_addr;
uint32_t dest_seqno;
uip_ipaddr_t orig_addr;
uint32_t lifetime;
};
/* AODV RERR message */
#define UAODV_RERR_TYPE 3
#define UAODV_RERR_NODELETE (1 << 7)
#define UAODV_RERR_UNKNOWN (1 << 6) /* Non standard extension /bg. */
struct uaodv_msg_rerr {
uint8_t type;
uint8_t flags;
uint8_t reserved;
uint8_t dest_count;
struct {
uip_ipaddr_t addr;
uint32_t seqno;
} unreach[1];
};
/* AODV RREP-ACK message */
#define UAODV_RREP_ACK_TYPE 4
struct uaodv_msg_rrep_ack {
uint8_t type;
uint8_t reserved;
};
#define RREP_HELLO_INTERVAL_EXT 1 /* Per RFC 3561. */
#define RREQ_BAD_HOP_EXT 101 /* Non standard extension /bg */
struct uaodv_extension {
uint8_t type;
uint8_t length;
/* uint8_t value[length]; */
};
struct uaodv_bad_hop_ext {
uint8_t type;
uint8_t length;
uint8_t unused1, unused2;
uip_ipaddr_t addrs[1];
};
#endif /* UAODV_DEF_H_ */

View File

@ -1,146 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Routing tables for the micro implementation of the AODV ad hoc routing protocol
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "net/ipv4/uaodv-rt.h"
#include "contiki-net.h"
#ifndef UAODV_NUM_RT_ENTRIES
#define UAODV_NUM_RT_ENTRIES 8
#endif
/*
* LRU (with respect to insertion time) list of route entries.
*/
LIST(route_table);
MEMB(route_mem, struct uaodv_rt_entry, UAODV_NUM_RT_ENTRIES);
/*---------------------------------------------------------------------------*/
void
uaodv_rt_init(void)
{
list_init(route_table);
memb_init(&route_mem);
}
/*---------------------------------------------------------------------------*/
struct uaodv_rt_entry *
uaodv_rt_add(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop,
unsigned hop_count, const uint32_t *seqno)
{
struct uaodv_rt_entry *e;
/* Avoid inserting duplicate entries. */
e = uaodv_rt_lookup_any(dest);
if(e != NULL) {
list_remove(route_table, e);
} else {
/* Allocate a new entry or reuse the oldest. */
e = memb_alloc(&route_mem);
if(e == NULL) {
e = list_chop(route_table); /* Remove oldest entry. */
}
}
uip_ipaddr_copy(&e->dest, dest);
uip_ipaddr_copy(&e->nexthop, nexthop);
e->hop_count = hop_count;
e->hseqno = uip_ntohl(*seqno);
e->is_bad = 0;
/* New entry goes first. */
list_push(route_table, e);
return e;
}
/*---------------------------------------------------------------------------*/
struct uaodv_rt_entry *
uaodv_rt_lookup_any(uip_ipaddr_t *dest)
{
struct uaodv_rt_entry *e;
for(e = list_head(route_table); e != NULL; e = e->next) {
if(uip_ipaddr_cmp(dest, &e->dest)) {
return e;
}
}
return NULL;
}
struct uaodv_rt_entry *
uaodv_rt_lookup(uip_ipaddr_t *dest)
{
struct uaodv_rt_entry *e;
e = uaodv_rt_lookup_any(dest);
if(e != NULL && e->is_bad)
return NULL;
return e;
}
/*---------------------------------------------------------------------------*/
#if 0
void
uaodv_rt_remove(struct uaodv_rt_entry *e)
{
list_remove(route_table, e);
memb_free(&route_mem, e);
}
#endif
void
uaodv_rt_lru(struct uaodv_rt_entry *e)
{
if(e != list_head(route_table)) {
list_remove(route_table, e);
list_push(route_table, e);
}
}
/*---------------------------------------------------------------------------*/
void
uaodv_rt_flush_all(void)
{
struct uaodv_rt_entry *e;
while (1) {
e = list_pop(route_table);
if(e != NULL)
memb_free(&route_mem, e);
else
break;
}
}

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Routing tables for the micro implementation of the AODV ad hoc routing protocol
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef UAODV_RT_H_
#define UAODV_RT_H_
#include "contiki-net.h"
struct uaodv_rt_entry {
struct uaodv_rt_entry *next;
uip_ipaddr_t dest;
uip_ipaddr_t nexthop;
uint32_t hseqno; /* In host byte order! */
uint8_t hop_count;
uint8_t is_bad; /* Only one bit is used. */
};
struct uaodv_rt_entry *
uaodv_rt_add(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop,
unsigned hop_count, const uint32_t *seqno);
struct uaodv_rt_entry *uaodv_rt_lookup_any(uip_ipaddr_t *dest);
struct uaodv_rt_entry *uaodv_rt_lookup(uip_ipaddr_t *dest);
void uaodv_rt_remove(struct uaodv_rt_entry *e);
void uaodv_rt_lru(struct uaodv_rt_entry *e);
void uaodv_rt_flush_all(void);
#endif /* UAODV_RT_H_ */

View File

@ -1,616 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Micro implementation of the AODV ad hoc routing protocol
* \author
* Adam Dunkels <adam@sics.se>
*/
#include <stdio.h>
#include <stdarg.h>
#include "contiki.h"
#include "net/ipv4/uaodv-def.h"
#include "net/ipv4/uaodv-rt.h"
#define NDEBUG
#include "lib/assert.h"
#ifdef CC2420_RADIO
#include "cc2420.h"
#define RSSI_THRESHOLD -39 /* accept -39 ... xx */
#endif
/* This implementation never expires routes!!! */
#define MY_ROUTE_TIMEOUT 0x7fffffff /* Should be 0xffffffff! */
#define MY_NET_DIAMETER 20
PROCESS(uaodv_process, "uAODV");
static struct uip_udp_conn *bcastconn, *unicastconn;
/* Compare sequence numbers as per RFC 3561. */
#define SCMP32(a, b) ((int32_t)((a) - (b)))
static CC_INLINE uint32_t
last_known_seqno(uip_ipaddr_t *host)
{
struct uaodv_rt_entry *route = uaodv_rt_lookup_any(host);
if(route != NULL)
return uip_htonl(route->hseqno);
return 0;
}
static uint32_t rreq_id, my_hseqno; /* In host byte order! */
#define NFWCACHE 16
static struct {
uip_ipaddr_t orig;
uint32_t id;
} fwcache[NFWCACHE];
static CC_INLINE int
fwc_lookup(const uip_ipaddr_t *orig, const uint32_t *id)
{
unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
return fwcache[n].id == *id && uip_ipaddr_cmp(&fwcache[n].orig, orig);
}
static CC_INLINE void
fwc_add(const uip_ipaddr_t *orig, const uint32_t *id)
{
unsigned n = (orig->u8[2] + orig->u8[3]) % NFWCACHE;
fwcache[n].id = *id;
uip_ipaddr_copy(&fwcache[n].orig, orig);
}
#ifdef NDEBUG
#define PRINTF(...) do {} while (0)
#define print_debug(...) do{}while(0)
#else
#define PRINTF(...) printf(__VA_ARGS__)
#ifdef __GNUC__
static void
print_debug(const char *fmt, ...) __attribute__((format(printf, 1, 2)));
#endif /* __GNUC__ */
static void
print_debug(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
printf("%d.%d.%d.%d: ", uip_ipaddr_to_quad(&uip_hostaddr));
vprintf(fmt, ap);
va_end(ap);
return;
}
#endif
#define BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
#define uip_udp_sender() (&BUF->srcipaddr)
/*---------------------------------------------------------------------------*/
static void
sendto(const uip_ipaddr_t *dest, const void *buf, int len)
{
/* XXX: this is a HACK! We're updating the uIP UDP connection
"unicastconn" so that the destination address is the next-hop,
and we're patching the "uip_udp_conn" variable so that it points
the this connection instead. THIS IS NOT A NICE WAY TO DO THIS,
but it is currently nicer than the alternative (requesting a new
poll, and remembering the state, etc.). */
uip_ipaddr_copy(&unicastconn->ripaddr, dest);
uip_udp_conn = unicastconn;
uip_udp_packet_send(unicastconn, buf, len);
}
/*---------------------------------------------------------------------------*/
#ifdef AODV_BAD_HOP_EXTENSION
static unsigned
add_rreq_extensions(void *_p)
{
struct uaodv_bad_hop_ext *p = _p;
uip_ipaddr_t *a = p->addrs;
unsigned i, n;
#define SCALE_RETRANS_THRESHOLD (3*4)
cc2420_check_remote(0xffff); /* Age table. */
n = 0;
for (i = 0; i < NNEIGBOURS; i++) {
if (neigbours[i].nretrans >= SCALE_RETRANS_THRESHOLD
&& neigbours[i].mac != 0xffff) {
a->u16[0] = uip_hostaddr.u16[0];
a->u16[1] = neigbours[i].mac;
n++;
if(n == 15)
break; /* Avoid buffer overrun */
print_debug("BAD HOP %d.%d.%d.%d\t%d\n",
uip_ipaddr_to_quad(a), neigbours[i].nretrans);
}
}
if(n == 0)
return 0;
p->type = RREQ_BAD_HOP_EXT;
p->length = 2 + 4*n; /* Two unused bytes + addresses */
return 2 + p->length; /* Type + len + extension data */
}
#else
#define add_rreq_extensions(p) 0 /* Don't add anything */
#endif
static void
send_rreq(uip_ipaddr_t *addr)
{
struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata;
int len;
print_debug("send RREQ for %d.%d.%d.%d\n", uip_ipaddr_to_quad(addr));
rm->type = UAODV_RREQ_TYPE;
rm->dest_seqno = last_known_seqno(addr);
if(rm->dest_seqno == 0)
rm->flags = UAODV_RREQ_UNKSEQNO;
else
rm->flags = 0;
rm->reserved = 0;
rm->hop_count = 0;
rm->rreq_id = uip_htonl(rreq_id++);
uip_ipaddr_copy(&rm->dest_addr, addr);
uip_gethostaddr(&rm->orig_addr);
my_hseqno++; /* Always */
rm->orig_seqno = uip_htonl(my_hseqno);
bcastconn->ttl = MY_NET_DIAMETER;
len = sizeof(struct uaodv_msg_rreq);
len += add_rreq_extensions(rm + 1);
uip_udp_packet_send(bcastconn, rm, len);
}
/*---------------------------------------------------------------------------*/
static void
send_rrep(uip_ipaddr_t *dest, uip_ipaddr_t *nexthop, uip_ipaddr_t *orig,
uint32_t *seqno, unsigned hop_count)
{
struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata;
print_debug("send RREP orig=%d.%d.%d.%d hops=%d\n",
uip_ipaddr_to_quad(orig), hop_count);
rm->type = UAODV_RREP_TYPE;
rm->flags = 0;
rm->prefix_sz = 0; /* I.e a /32 route. */
rm->hop_count = hop_count;
uip_ipaddr_copy(&rm->orig_addr, orig);
rm->dest_seqno = *seqno;
uip_ipaddr_copy(&rm->dest_addr, dest);
rm->lifetime = UIP_HTONL(MY_ROUTE_TIMEOUT);
sendto(nexthop, rm, sizeof(struct uaodv_msg_rrep));
}
/*---------------------------------------------------------------------------*/
static void
send_rerr(uip_ipaddr_t *addr, uint32_t *seqno)
{
struct uaodv_msg_rerr *rm = (struct uaodv_msg_rerr *)uip_appdata;
print_debug("send RERR for %d.%d.%d.%d\n", uip_ipaddr_to_quad(addr));
rm->type = UAODV_RERR_TYPE;
rm->reserved = 0;
rm->dest_count = 1;
uip_ipaddr_copy(&rm->unreach[0].addr, addr);
rm->unreach[0].seqno = *seqno;
if(*seqno == 0)
rm->flags = UAODV_RERR_UNKNOWN;
else
rm->flags = 0;
uip_udp_packet_send(bcastconn, rm, sizeof(struct uaodv_msg_rerr));
}
/*---------------------------------------------------------------------------*/
static void
handle_incoming_rreq(void)
{
struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata;
uip_ipaddr_t dest_addr, orig_addr;
struct uaodv_rt_entry *rt, *fw = NULL;
print_debug("RREQ %d.%d.%d.%d -> %d.%d.%d.%d ttl=%u"
" orig=%d.%d.%d.%d seq=%lu hops=%u dest=%d.%d.%d.%d seq=%lu\n",
uip_ipaddr_to_quad(&BUF->srcipaddr),
uip_ipaddr_to_quad(&BUF->destipaddr),
BUF->ttl,
uip_ipaddr_to_quad(&rm->orig_addr), uip_ntohl(rm->orig_seqno),
rm->hop_count,
uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno));
if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) {
return; /* RREQ looped back! */
}
#ifdef CC2420_RADIO
{
int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
if(ret == REMOTE_YES) {
print_debug("RREQ drop is remote\n");
return;
} else if (ret == REMOTE_NO) {
/* Is neigbour, accept it. */
} else if(cc2420_last_rssi < RSSI_THRESHOLD) {
print_debug("RREQ drop %d %d\n", cc2420_last_rssi,
cc2420_last_correlation);
return;
}
}
#endif
#ifdef AODV_BAD_HOP_EXTENSION
if(uip_len > (sizeof(*rm) + 2)) {
struct uaodv_bad_hop_ext *ext = (void *)(uip_appdata + sizeof(*rm));
uint8_t *end = uip_appdata + uip_len;
for(;
(uint8_t *)ext < end;
ext = (void *)((uint8_t *)ext + ext->length + 2)) {
uint8_t *eend = (uint8_t *)ext + ext->length;
if(eend > end)
eend = end;
if(ext->type == RREQ_BAD_HOP_EXT) {
uip_ipaddr_t *a;
for(a = ext->addrs; (uint8_t *)a < eend; a++) {
if(uip_ipaddr_cmp(a, &uip_hostaddr)) {
print_debug("BAD_HOP drop\n");
return;
}
}
}
}
}
#endif /* AODV_BAD_HOP_EXTENSION */
/* New reverse route? */
rt = uaodv_rt_lookup(&rm->orig_addr);
if(rt == NULL
|| (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) > 0) /* New route. */
|| (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) == 0
&& rm->hop_count < rt->hop_count)) { /* Better route. */
print_debug("Inserting1\n");
rt = uaodv_rt_add(&rm->orig_addr, uip_udp_sender(),
rm->hop_count, &rm->orig_seqno);
}
/* Check if it is for our address or a fresh route. */
if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)
|| rm->flags & UAODV_RREQ_DESTONLY) {
fw = NULL;
} else {
fw = uaodv_rt_lookup(&rm->dest_addr);
if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
&& fw != NULL
&& SCMP32(fw->hseqno, uip_ntohl(rm->dest_seqno)) <= 0) {
fw = NULL;
}
}
if (fw != NULL) {
uint32_t net_seqno;
print_debug("RREQ for known route\n");
uip_ipaddr_copy(&dest_addr, &rm->dest_addr);
uip_ipaddr_copy(&orig_addr, &rm->orig_addr);
net_seqno = uip_htonl(fw->hseqno);
send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno,
fw->hop_count + 1);
} else if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)) {
uint32_t net_seqno;
print_debug("RREQ for our address\n");
uip_ipaddr_copy(&dest_addr, &rm->dest_addr);
uip_ipaddr_copy(&orig_addr, &rm->orig_addr);
my_hseqno++;
if(!(rm->flags & UAODV_RREQ_UNKSEQNO)
&& SCMP32(my_hseqno, uip_ntohl(rm->dest_seqno)) < 0) {
print_debug("New my_hseqno %lu\n", my_hseqno); /* We have rebooted. */
my_hseqno = uip_ntohl(rm->dest_seqno) + 1;
}
net_seqno = uip_htonl(my_hseqno);
send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, 0);
} else if(BUF->ttl > 1) {
int len;
/* Have we seen this RREQ before? */
if(fwc_lookup(&rm->orig_addr, &rm->rreq_id)) {
print_debug("RREQ cached, not fwd\n");
return;
}
fwc_add(&rm->orig_addr, &rm->rreq_id);
print_debug("RREQ fwd\n");
rm->hop_count++;
bcastconn->ttl = BUF->ttl - 1;
len = sizeof(struct uaodv_msg_rreq);
len += add_rreq_extensions(rm + 1);
uip_udp_packet_send(bcastconn, rm, len);
}
}
/*---------------------------------------------------------------------------*/
static void
handle_incoming_rrep(void)
{
struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata;
struct uaodv_rt_entry *rt;
/* Useless HELLO message? */
if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
#ifdef AODV_RESPOND_TO_HELLOS
uint32_t net_seqno;
#ifdef CC2420_RADIO
int ret = cc2420_check_remote(uip_udp_sender()->u16[1]);
if(ret == REMOTE_YES) {
print_debug("HELLO drop is remote\n");
return;
} else if (ret == REMOTE_NO) {
/* Is neigbour, accept it. */
} else if(cc2420_last_rssi < RSSI_THRESHOLD) {
print_debug("HELLO drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation);
return;
}
#endif
/* Sometimes it helps to send a non-requested RREP in response! */
net_seqno = uip_htonl(my_hseqno);
send_rrep(&uip_hostaddr, &BUF->srcipaddr, &BUF->srcipaddr, &net_seqno, 0);
#endif
return;
}
print_debug("RREP %d.%d.%d.%d -> %d.%d.%d.%d"
" dest=%d.%d.%d.%d seq=%lu hops=%u orig=%d.%d.%d.%d\n",
uip_ipaddr_to_quad(&BUF->srcipaddr),
uip_ipaddr_to_quad(&BUF->destipaddr),
uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno),
rm->hop_count,
uip_ipaddr_to_quad(&rm->orig_addr));
rt = uaodv_rt_lookup(&rm->dest_addr);
/* New forward route? */
if(rt == NULL || (SCMP32(uip_ntohl(rm->dest_seqno), rt->hseqno) > 0)) {
print_debug("Inserting3\n");
rt = uaodv_rt_add(&rm->dest_addr, uip_udp_sender(),
rm->hop_count, &rm->dest_seqno);
#ifdef CC2420_RADIO
/* This link is ok since he is unicasting back to us! */
cc2420_recv_ok(uip_udp_sender());
print_debug("RREP recv ok %d %d\n",
cc2420_last_rssi, cc2420_last_correlation);
#endif
} else {
print_debug("Not inserting\n");
}
/* Forward RREP towards originator? */
if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) {
print_debug("ROUTE FOUND\n");
if(rm->flags & UAODV_RREP_ACK) {
struct uaodv_msg_rrep_ack *ack = (void *)uip_appdata;
ack->type = UAODV_RREP_ACK_TYPE;
ack->reserved = 0;
sendto(uip_udp_sender(), ack, sizeof(*ack));
}
} else {
rt = uaodv_rt_lookup(&rm->orig_addr);
if(rt == NULL) {
print_debug("RREP received, but no route back to originator... :-( \n");
return;
}
if(rm->flags & UAODV_RREP_ACK) {
print_debug("RREP with ACK request (ignored)!\n");
/* Don't want any RREP-ACKs in return! */
rm->flags &= ~UAODV_RREP_ACK;
}
rm->hop_count++;
print_debug("Fwd RREP to %d.%d.%d.%d\n", uip_ipaddr_to_quad(&rt->nexthop));
sendto(&rt->nexthop, rm, sizeof(struct uaodv_msg_rrep));
}
}
/*---------------------------------------------------------------------------*/
static void
handle_incoming_rerr(void)
{
struct uaodv_msg_rerr *rm = (struct uaodv_msg_rerr *)uip_appdata;
struct uaodv_rt_entry *rt;
print_debug("RERR %d.%d.%d.%d -> %d.%d.%d.%d"
" unreach=%d.%d.%d.%d seq=%lu\n",
uip_ipaddr_to_quad(&BUF->srcipaddr),
uip_ipaddr_to_quad(&BUF->destipaddr),
uip_ipaddr_to_quad((uip_ipaddr_t *)&rm->unreach[0]),
uip_ntohl(rm->unreach[0].seqno));
if(uip_ipaddr_cmp(&rm->unreach[0].addr, &uip_hostaddr))
return;
rt = uaodv_rt_lookup_any(&rm->unreach[0].addr);
if(rt != NULL && uip_ipaddr_cmp(&rt->nexthop, uip_udp_sender())) {
if((rm->flags & UAODV_RERR_UNKNOWN) || rm->unreach[0].seqno == 0
|| SCMP32(rt->hseqno, uip_ntohl(rm->unreach[0].seqno)) <= 0) {
rt->is_bad = 1;
if(rm->flags & UAODV_RERR_UNKNOWN) {
rm->flags &= ~UAODV_RERR_UNKNOWN;
rm->unreach[0].seqno = uip_htonl(rt->hseqno);
}
print_debug("RERR rebroadcast\n");
uip_udp_packet_send(bcastconn, rm, sizeof(struct uaodv_msg_rerr));
}
}
}
/*---------------------------------------------------------------------------*/
static void
handle_incoming_packet(void)
{
struct uaodv_msg *m = (struct uaodv_msg *)uip_appdata;
/* print_debug("New UDP data, AODV packet type %d\n", m->type);*/
switch(m->type) {
case UAODV_RREQ_TYPE:
handle_incoming_rreq();
break;
case UAODV_RREP_TYPE:
handle_incoming_rrep();
break;
case UAODV_RERR_TYPE:
handle_incoming_rerr();
break;
}
}
/*---------------------------------------------------------------------------*/
static enum {
COMMAND_NONE,
COMMAND_SEND_RREQ,
COMMAND_SEND_RERR,
} command;
static uip_ipaddr_t bad_dest;
static uint32_t bad_seqno; /* In network byte order! */
void
uaodv_bad_dest(uip_ipaddr_t *dest)
{
struct uaodv_rt_entry *rt = uaodv_rt_lookup_any(dest);
if(rt == NULL)
bad_seqno = 0; /* Or flag this in RERR? */
else {
rt->is_bad = 1;
bad_seqno = uip_htonl(rt->hseqno);
}
uip_ipaddr_copy(&bad_dest, dest);
command = COMMAND_SEND_RERR;
process_post(&uaodv_process, PROCESS_EVENT_MSG, NULL);
}
static uip_ipaddr_t rreq_addr;
static struct timer next_time;
struct uaodv_rt_entry *
uaodv_request_route_to(uip_ipaddr_t *host)
{
struct uaodv_rt_entry *route = uaodv_rt_lookup(host);
if(route != NULL) {
uaodv_rt_lru(route);
return route;
}
/*
* Broadcast protocols must be rate-limited!
*/
if(!timer_expired(&next_time)) {
return NULL;
}
if(command != COMMAND_NONE) {
return NULL;
}
uip_ipaddr_copy(&rreq_addr, host);
command = COMMAND_SEND_RREQ;
process_post(&uaodv_process, PROCESS_EVENT_MSG, NULL);
timer_set(&next_time, CLOCK_SECOND/8); /* Max 10/s per RFC3561. */
return NULL;
}
PROCESS_THREAD(uaodv_process, ev, data)
{
PROCESS_EXITHANDLER(goto exit);
PROCESS_BEGIN();
printf("uaodv_process starting %lu\n", (unsigned long) my_hseqno);
bcastconn = udp_broadcast_new(UIP_HTONS(UAODV_UDPPORT), NULL);
unicastconn = udp_broadcast_new(UIP_HTONS(UAODV_UDPPORT), NULL);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == tcpip_event) {
if(uip_newdata()) {
handle_incoming_packet();
continue;
}
if(uip_poll()) {
if(command == COMMAND_SEND_RREQ) {
if(uaodv_rt_lookup(&rreq_addr) == NULL)
send_rreq(&rreq_addr);
} else if (command == COMMAND_SEND_RERR) {
send_rerr(&bad_dest, &bad_seqno);
}
command = COMMAND_NONE;
continue;
}
}
if(ev == PROCESS_EVENT_MSG) {
tcpip_poll_udp(bcastconn);
}
}
exit:
command = COMMAND_NONE;
uaodv_rt_flush_all();
uip_udp_remove(bcastconn);
bcastconn = NULL;
uip_udp_remove(unicastconn);
unicastconn = NULL;
printf("uaodv_process exiting\n");
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View File

@ -1,51 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* A brief description of what this file is.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef UAODV_H_
#define UAODV_H_
#include "contiki.h"
#include "uaodv-rt.h"
PROCESS_NAME(uaodv_process);
struct uaodv_rt_entry * uaodv_request_route_to(uip_ipaddr_t *host);
void uaodv_bad_dest(uip_ipaddr_t *);
#endif /* UAODV_H_ */

View File

@ -1,54 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "net/ipv4/uip-fw.h"
#if !NETSTACK_CONF_WITH_IPV6
PROCESS(uip_fw_process, "IP forwarding");
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(uip_fw_process, ev, data)
{
PROCESS_BEGIN();
tcpip_set_outputfunc(uip_fw_output);
PROCESS_WAIT_UNTIL(ev == PROCESS_EVENT_EXIT);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
#endif /* NETSTACK_CONF_WITH_IPV6 */

View File

@ -1,42 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#ifndef UIP_FW_DRV_H_
#define UIP_FW_DRV_H_
#include "contiki.h"
#include "net/ipv4/uip-fw.h"
PROCESS_NAME(uip_fw_process);
#endif /* UIP_FW_DRV_H_ */

View File

@ -1,536 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup uipfw uIP packet forwarding
* @{
*
*/
/**
* \file
* uIP packet forwarding.
* \author Adam Dunkels <adam@sics.se>
*
* This file implements a number of simple functions which do packet
* forwarding over multiple network interfaces with uIP.
*
*/
#include <string.h>
#include "contiki-conf.h"
#include "net/ip/uip.h"
#include "net/ip/uip_arch.h"
#include "net/ipv4/uip-fw.h"
#ifdef AODV_COMPLIANCE
#include "net/ipv4/uaodv-def.h"
#endif
/*
* The list of registered network interfaces.
*/
static struct uip_fw_netif *netifs = NULL;
/*
* A pointer to the default network interface.
*/
static struct uip_fw_netif *defaultnetif = NULL;
struct tcpip_hdr {
/* IP header. */
uint8_t vhl,
tos;
uint16_t len,
ipid,
ipoffset;
uint8_t ttl,
proto;
uint16_t ipchksum;
uip_ipaddr_t srcipaddr, destipaddr;
/* TCP header. */
uint16_t srcport,
destport;
uint8_t seqno[4],
ackno[4],
tcpoffset,
flags,
wnd[2];
uint16_t tcpchksum;
uint8_t urgp[2];
uint8_t optdata[4];
};
struct icmpip_hdr {
/* IP header. */
uint8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
uint16_t ipchksum;
uip_ipaddr_t srcipaddr, destipaddr;
/* ICMP (echo) header. */
uint8_t type, icode;
uint16_t icmpchksum;
uint16_t id, seqno;
uint8_t payload[1];
};
/* ICMP ECHO. */
#define ICMP_ECHO 8
/* ICMP TIME-EXCEEDED. */
#define ICMP_TE 11
/*
* Pointer to the TCP/IP headers of the packet in the uip_buf buffer.
*/
#define BUF ((struct tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
/*
* Pointer to the ICMP/IP headers of the packet in the uip_buf buffer.
*/
#define ICMPBUF ((struct icmpip_hdr *)&uip_buf[UIP_LLH_LEN])
/*
* Certain fields of an IP packet that are used for identifying
* duplicate packets.
*/
struct fwcache_entry {
uint16_t timer;
uip_ipaddr_t srcipaddr;
uip_ipaddr_t destipaddr;
uint16_t ipid;
uint8_t proto;
uint8_t unused;
#if notdef
uint16_t payload[2];
#endif
#if UIP_REASSEMBLY > 0
uint16_t len, offset;
#endif
};
/*
* The number of packets to remember when looking for duplicates.
*/
#ifdef UIP_CONF_FWCACHE_SIZE
#define FWCACHE_SIZE UIP_CONF_FWCACHE_SIZE
#else
#define FWCACHE_SIZE 2
#endif
/*
* A cache of packet header fields which are used for
* identifying duplicate packets.
*/
static struct fwcache_entry fwcache[FWCACHE_SIZE];
/**
* \internal
* The time that a packet cache is active.
*/
#define FW_TIME 20
/*------------------------------------------------------------------------------*/
/**
* Initialize the uIP packet forwarding module.
*/
/*------------------------------------------------------------------------------*/
void
uip_fw_init(void)
{
struct uip_fw_netif *t;
defaultnetif = NULL;
while(netifs != NULL) {
t = netifs;
netifs = netifs->next;
t->next = NULL;
}
}
/*------------------------------------------------------------------------------*/
/**
* \internal
* Check if an IP address is within the network defined by an IP
* address and a netmask.
*
* \param ipaddr The IP address to be checked.
* \param netipaddr The IP address of the network.
* \param netmask The netmask of the network.
*
* \return Non-zero if IP address is in network, zero otherwise.
*/
/*------------------------------------------------------------------------------*/
static unsigned char
ipaddr_maskcmp(uip_ipaddr_t *ipaddr,
uip_ipaddr_t *netipaddr,
uip_ipaddr_t *netmask)
{
return (ipaddr->u16[0] & netmask->u16[0]) == (netipaddr->u16[0] & netmask->u16[0]) &&
(ipaddr->u16[1] & netmask->u16[1]) == (netipaddr->u16[1] & netmask->u16[1]);
}
/*------------------------------------------------------------------------------*/
/**
* \internal
* Send out an ICMP TIME-EXCEEDED message.
*
* This function replaces the packet in the uip_buf buffer with the
* ICMP packet.
*/
/*------------------------------------------------------------------------------*/
static void
time_exceeded(void)
{
/* We don't send out ICMP errors for ICMP messages (unless they are pings). */
if(ICMPBUF->proto == UIP_PROTO_ICMP &&
ICMPBUF->type != ICMP_ECHO) {
uip_clear_buf();
return;
}
/* Copy fields from packet header into payload of this ICMP packet. */
memcpy(&(ICMPBUF->payload[0]), ICMPBUF, UIP_IPH_LEN + 8);
/* Set the ICMP type and code. */
ICMPBUF->type = ICMP_TE;
ICMPBUF->icode = 0;
/* Calculate the ICMP checksum. */
ICMPBUF->icmpchksum = 0;
ICMPBUF->icmpchksum = ~uip_chksum((uint16_t *)&(ICMPBUF->type), 36);
/* Set the IP destination address to be the source address of the
original packet. */
uip_ipaddr_copy(&BUF->destipaddr, &BUF->srcipaddr);
/* Set our IP address as the source address. */
uip_ipaddr_copy(&BUF->srcipaddr, &uip_hostaddr);
/* The size of the ICMP time exceeded packet is 36 + the size of the
IP header (20) = 56. */
uip_len = 56;
ICMPBUF->len[0] = 0;
ICMPBUF->len[1] = (uint8_t)uip_len;
/* Fill in the other fields in the IP header. */
ICMPBUF->vhl = 0x45;
ICMPBUF->tos = 0;
ICMPBUF->ipoffset[0] = ICMPBUF->ipoffset[1] = 0;
ICMPBUF->ttl = UIP_TTL;
ICMPBUF->proto = UIP_PROTO_ICMP;
/* Calculate IP checksum. */
ICMPBUF->ipchksum = 0;
ICMPBUF->ipchksum = ~(uip_ipchksum());
}
/*------------------------------------------------------------------------------*/
/**
* \internal
* Register a packet in the forwarding cache so that it won't be
* forwarded again.
*/
/*------------------------------------------------------------------------------*/
static void
fwcache_register(void)
{
struct fwcache_entry *fw;
int i, oldest;
oldest = FW_TIME;
fw = NULL;
/* Find the oldest entry in the cache. */
for(i = 0; i < FWCACHE_SIZE; ++i) {
if(fwcache[i].timer == 0) {
fw = &fwcache[i];
break;
} else if(fwcache[i].timer <= oldest) {
fw = &fwcache[i];
oldest = fwcache[i].timer;
}
}
fw->timer = FW_TIME;
fw->ipid = BUF->ipid;
uip_ipaddr_copy(&fw->srcipaddr, &BUF->srcipaddr);
uip_ipaddr_copy(&fw->destipaddr, &BUF->destipaddr);
fw->proto = BUF->proto;
#if notdef
fw->payload[0] = BUF->srcport;
fw->payload[1] = BUF->destport;
#endif
#if UIP_REASSEMBLY > 0
fw->len = BUF->len;
fw->offset = BUF->ipoffset;
#endif
}
/*------------------------------------------------------------------------------*/
/**
* \internal
* Find a network interface for the IP packet in uip_buf.
*/
/*------------------------------------------------------------------------------*/
static struct uip_fw_netif *
find_netif(void)
{
struct uip_fw_netif *netif;
/* Walk through every network interface to check for a match. */
for(netif = netifs; netif != NULL; netif = netif->next) {
if(ipaddr_maskcmp(&BUF->destipaddr, &netif->ipaddr,
&netif->netmask)) {
/* If there was a match, we break the loop. */
return netif;
}
}
/* If no matching netif was found, we use default netif. */
return defaultnetif;
}
/*------------------------------------------------------------------------------*/
/**
* Output an IP packet on the correct network interface.
*
* The IP packet should be present in the uip_buf buffer and its
* length in the global uip_len variable.
*
* \retval UIP_FW_ZEROLEN Indicates that a zero-length packet
* transmission was attempted and that no packet was sent.
*
* \retval UIP_FW_NOROUTE No suitable network interface could be found
* for the outbound packet, and the packet was not sent.
*
* \return The return value from the actual network interface output
* function is passed unmodified as a return value.
*/
/*------------------------------------------------------------------------------*/
uint8_t
uip_fw_output(void)
{
struct uip_fw_netif *netif;
#if UIP_BROADCAST
const struct uip_udpip_hdr *udp = (void *)BUF;
#endif /* UIP_BROADCAST */
if(uip_len == 0) {
return UIP_FW_ZEROLEN;
}
fwcache_register();
#if UIP_BROADCAST
/* Link local broadcasts go out on all interfaces. */
if(uip_ipaddr_cmp(&udp->destipaddr, &uip_broadcast_addr)) {
if(defaultnetif != NULL) {
defaultnetif->output();
}
for(netif = netifs; netif != NULL; netif = netif->next) {
netif->output();
}
return UIP_FW_OK;
}
#endif /* UIP_BROADCAST */
netif = find_netif();
/* printf("uip_fw_output: netif %p ->output %p len %d\n", netif,
netif->output,
uip_len);*/
if(netif == NULL) {
return UIP_FW_NOROUTE;
}
/* If we now have found a suitable network interface, we call its
output function to send out the packet. */
return netif->output();
}
/*------------------------------------------------------------------------------*/
/**
* Forward an IP packet in the uip_buf buffer.
*
*
*
* \return UIP_FW_FORWARDED if the packet was forwarded, UIP_FW_LOCAL if
* the packet should be processed locally.
*/
/*------------------------------------------------------------------------------*/
uint8_t
uip_fw_forward(void)
{
struct fwcache_entry *fw;
/* First check if the packet is destined for ourselves and return 0
to indicate that the packet should be processed locally. */
if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_hostaddr)) {
return UIP_FW_LOCAL;
}
#ifdef AODV_COMPLIANCE
#define udp ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
if(udp->proto == UIP_PROTO_UDP && udp->destport == UIP_HTONS(UAODV_UDPPORT)) {
return UIP_FW_LOCAL;
}
#endif
/* If we use ping IP address configuration, and our IP address is
not yet configured, we should intercept all ICMP echo packets. */
#if UIP_PINGADDRCONF
if(uip_ipaddr_cmp(&uip_hostaddr, &uip_all_zeroes_addr) &&
BUF->proto == UIP_PROTO_ICMP &&
ICMPBUF->type == ICMP_ECHO) {
return UIP_FW_LOCAL;
}
#endif /* UIP_PINGADDRCONF */
/* Check if the packet is in the forwarding cache already, and if so
we drop it. */
for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
if(fw->timer != 0 &&
#if UIP_REASSEMBLY > 0
fw->len == BUF->len &&
fw->offset == BUF->ipoffset &&
#endif
fw->ipid == BUF->ipid &&
uip_ipaddr_cmp(&fw->srcipaddr, &BUF->srcipaddr) &&
uip_ipaddr_cmp(&fw->destipaddr, &BUF->destipaddr) &&
#if notdef
fw->payload[0] == BUF->srcport &&
fw->payload[1] == BUF->destport &&
#endif
fw->proto == BUF->proto) {
/* Drop packet. */
return UIP_FW_FORWARDED;
}
}
/* If the TTL reaches zero we produce an ICMP time exceeded message
in the uip_buf buffer and forward that packet back to the sender
of the packet. */
if(BUF->ttl <= 1) {
/* No time exceeded for broadcasts and multicasts! */
if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
return UIP_FW_LOCAL;
}
time_exceeded();
}
/* Decrement the TTL (time-to-live) value in the IP header */
BUF->ttl = BUF->ttl - 1;
/* Update the IP checksum. */
if(BUF->ipchksum >= UIP_HTONS(0xffff - 0x0100)) {
BUF->ipchksum = BUF->ipchksum + UIP_HTONS(0x0100) + 1;
} else {
BUF->ipchksum = BUF->ipchksum + UIP_HTONS(0x0100);
}
if(uip_len > 0) {
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN];
uip_fw_output();
}
#if UIP_BROADCAST
if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) {
return UIP_FW_LOCAL;
}
#endif /* UIP_BROADCAST */
/* Return non-zero to indicate that the packet was forwarded and that no
other processing should be made. */
return UIP_FW_FORWARDED;
}
/*------------------------------------------------------------------------------*/
/**
* Register a network interface with the forwarding module.
*
* \param netif A pointer to the network interface that is to be
* registered.
*/
/*------------------------------------------------------------------------------*/
void
uip_fw_register(struct uip_fw_netif *netif)
{
netif->next = netifs;
netifs = netif;
}
/*------------------------------------------------------------------------------*/
/**
* Register a default network interface.
*
* All packets that don't go out on any of the other interfaces will
* be routed to the default interface.
*
* \param netif A pointer to the network interface that is to be
* registered.
*/
/*------------------------------------------------------------------------------*/
void
uip_fw_default(struct uip_fw_netif *netif)
{
defaultnetif = netif;
}
/*------------------------------------------------------------------------------*/
/**
* Perform periodic processing.
*/
/*------------------------------------------------------------------------------*/
void
uip_fw_periodic(void)
{
struct fwcache_entry *fw;
for(fw = fwcache; fw < &fwcache[FWCACHE_SIZE]; ++fw) {
if(fw->timer > 0) {
--fw->timer;
}
}
}
/*------------------------------------------------------------------------------*/
/** @} */
/** @} */

View File

@ -1,176 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/**
* \file
* uIP packet forwarding header file.
* \author Adam Dunkels <adam@sics.se>
*/
/**
* \addtogroup uipfw
* @{
*/
#ifndef UIP_FW_H_
#define UIP_FW_H_
#include "net/ip/uip.h"
/**
* Representation of a uIP network interface.
*/
struct uip_fw_netif {
struct uip_fw_netif *next; /**< Pointer to the next interface when
linked in a list. */
uip_ipaddr_t ipaddr; /**< The IP address of this interface. */
uip_ipaddr_t netmask; /**< The netmask of the interface. */
uint8_t (* output)(void);
/**< A pointer to the function that
sends a packet. */
};
/**
* Instantiating macro for a uIP network interface.
*
* Example:
\code
struct uip_fw_netif slipnetif =
{UIP_FW_NETIF(192,168,76,1, 255,255,255,0, slip_output)};
\endcode
* \param ip1,ip2,ip3,ip4 The IP address of the network interface.
*
* \param nm1,nm2,nm3,nm4 The netmask of the network interface.
*
* \param outputfunc A pointer to the output function of the network interface.
*
* \hideinitializer
*/
#define UIP_FW_NETIF(ip1,ip2,ip3,ip4, nm1,nm2,nm3,nm4, outputfunc) \
NULL, \
{ {ip1, ip2, ip3, ip4} }, \
{ {nm1, nm2, nm3, nm4} }, \
outputfunc
/**
* Set the IP address of a network interface.
*
* \param netif A pointer to the uip_fw_netif structure for the network interface.
*
* \param addr A pointer to an IP address.
*
* \hideinitializer
*/
#define uip_fw_setipaddr(netif, addr) \
do { (netif)->ipaddr[0] = ((uint16_t *)(addr))[0]; \
(netif)->ipaddr[1] = ((uint16_t *)(addr))[1]; } while(0)
/**
* Set the netmask of a network interface.
*
* \param netif A pointer to the uip_fw_netif structure for the network interface.
*
* \param addr A pointer to an IP address representing the netmask.
*
* \hideinitializer
*/
#define uip_fw_setnetmask(netif, addr) \
do { (netif)->netmask[0] = ((uint16_t *)(addr))[0]; \
(netif)->netmask[1] = ((uint16_t *)(addr))[1]; } while(0)
void uip_fw_init(void);
uint8_t uip_fw_forward(void);
uint8_t uip_fw_output(void);
void uip_fw_register(struct uip_fw_netif *netif);
void uip_fw_default(struct uip_fw_netif *netif);
void uip_fw_periodic(void);
/**
* A non-error message that indicates that a packet should be
* processed locally.
*
* \hideinitializer
*/
#define UIP_FW_LOCAL 0
/**
* A non-error message that indicates that something went OK.
*
* \hideinitializer
*/
#define UIP_FW_OK 0
/**
* A non-error message that indicates that a packet was forwarded.
*
* \hideinitializer
*/
#define UIP_FW_FORWARDED 1
/**
* A non-error message that indicates that a zero-length packet
* transmission was attempted, and that no packet was sent.
*
* \hideinitializer
*/
#define UIP_FW_ZEROLEN 2
/**
* An error message that indicates that a packet that was too large
* for the outbound network interface was detected.
*
* \hideinitializer
*/
#define UIP_FW_TOOLARGE 3
/**
* An error message that indicates that no suitable interface could be
* found for an outbound packet.
*
* \hideinitializer
*/
#define UIP_FW_NOROUTE 4
/**
* An error message that indicates that a packet that should be
* forwarded or output was dropped.
*
* \hideinitializer
*/
#define UIP_FW_DROPPED 5
#endif /* UIP_FW_H_ */
/** @} */

View File

@ -1,158 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Database of link-local neighbors, used by IPv6 code and
* to be used by a future ARP code rewrite.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include "net/ipv4/uip-neighbor.h"
#include <string.h>
#include <stdio.h>
#define MAX_TIME 128
#ifdef UIP_NEIGHBOR_CONF_ENTRIES
#define ENTRIES UIP_NEIGHBOR_CONF_ENTRIES
#else /* UIP_NEIGHBOR_CONF_ENTRIES */
#define ENTRIES 8
#endif /* UIP_NEIGHBOR_CONF_ENTRIES */
struct neighbor_entry {
uip_ipaddr_t ipaddr;
struct uip_neighbor_addr addr;
uint8_t time;
};
static struct neighbor_entry entries[ENTRIES];
/*---------------------------------------------------------------------------*/
void
uip_neighbor_init(void)
{
int i;
for(i = 0; i < ENTRIES; ++i) {
entries[i].time = MAX_TIME;
}
}
/*---------------------------------------------------------------------------*/
void
uip_neighbor_periodic(void)
{
int i;
for(i = 0; i < ENTRIES; ++i) {
if(entries[i].time < MAX_TIME) {
entries[i].time++;
}
}
}
/*---------------------------------------------------------------------------*/
void
uip_neighbor_add(uip_ipaddr_t *ipaddr, struct uip_neighbor_addr *addr)
{
int i, oldest;
uint8_t oldest_time;
/* printf("Adding neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
addr->addr.addr[0], addr->addr.addr[1], addr->addr.addr[2], addr->addr.addr[3],
addr->addr.addr[4], addr->addr.addr[5]);*/
/* Find the first unused entry or the oldest used entry. */
oldest_time = 0;
oldest = 0;
for(i = 0; i < ENTRIES; ++i) {
if(entries[i].time == MAX_TIME) {
oldest = i;
break;
}
if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) {
oldest = i;
break;
}
if(entries[i].time > oldest_time) {
oldest = i;
oldest_time = entries[i].time;
}
}
/* Use the oldest or first free entry (either pointed to by the
"oldest" variable). */
entries[oldest].time = 0;
uip_ipaddr_copy(&entries[oldest].ipaddr, ipaddr);
memcpy(&entries[oldest].addr, addr, sizeof(struct uip_neighbor_addr));
}
/*---------------------------------------------------------------------------*/
static struct neighbor_entry *
find_entry(uip_ipaddr_t *ipaddr)
{
int i;
for(i = 0; i < ENTRIES; ++i) {
if(uip_ipaddr_cmp(&entries[i].ipaddr, ipaddr)) {
return &entries[i];
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
uip_neighbor_update(uip_ipaddr_t *ipaddr)
{
struct neighbor_entry *e;
e = find_entry(ipaddr);
if(e != NULL) {
e->time = 0;
}
}
/*---------------------------------------------------------------------------*/
struct uip_neighbor_addr *
uip_neighbor_lookup(uip_ipaddr_t *ipaddr)
{
struct neighbor_entry *e;
e = find_entry(ipaddr);
if(e != NULL) {
/* printf("Lookup neighbor with link address %02x:%02x:%02x:%02x:%02x:%02x\n",
e->addr.addr.addr[0], e->addr.addr.addr[1], e->addr.addr.addr[2], e->addr.addr.addr[3],
e->addr.addr.addr[4], e->addr.addr.addr[5]);*/
return &e->addr;
}
return NULL;
}
/*---------------------------------------------------------------------------*/

View File

@ -1,60 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Header file for database of link-local neighbors, used by
* IPv6 code and to be used by future ARP code.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef UIP_NEIGHBOR_H_
#define UIP_NEIGHBOR_H_
#include "net/ip/uip.h"
struct uip_neighbor_addr {
#if UIP_NEIGHBOR_CONF_ADDRTYPE
UIP_NEIGHBOR_CONF_ADDRTYPE addr;
#else
struct uip_eth_addr addr;
#endif
};
void uip_neighbor_init(void);
void uip_neighbor_add(uip_ipaddr_t *ipaddr, struct uip_neighbor_addr *addr);
void uip_neighbor_update(uip_ipaddr_t *ipaddr);
struct uip_neighbor_addr *uip_neighbor_lookup(uip_ipaddr_t *ipaddr);
void uip_neighbor_periodic(void);
#endif /* UIP-NEIGHBOR_H_ */

View File

@ -1,292 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Code for tunnelling uIP packets over the Rime mesh routing module
* \author
* Adam Dunkels <adam@sics.se>
*/
#include <stdio.h>
#include "net/rime/rime.h"
#include "net/ipv4/uip-fw.h"
#include "net/ipv4/uip-over-mesh.h"
#define ROUTE_TRICKLE_INTERVAL CLOCK_SECOND * 32
#define ROUTE_DISCOVERY_INTERVAL CLOCK_SECOND * 4
#define ROUTE_TIMEOUT CLOCK_SECOND * 4
static struct queuebuf *queued_packet;
static linkaddr_t queued_receiver;
/* Connection for route discovery: */
static struct route_discovery_conn route_discovery;
/* Connection for sending data packets to the next hop node: */
static struct unicast_conn dataconn;
/* Connection for sending gateway announcement message to the entire
network: */
static struct trickle_conn gateway_announce_conn;
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
static struct uip_fw_netif *gw_netif;
static linkaddr_t gateway;
static uip_ipaddr_t netaddr, netmask;
/*---------------------------------------------------------------------------*/
static void
recv_data(struct unicast_conn *c, const linkaddr_t *from)
{
struct route_entry *e;
linkaddr_t source;
uip_len = packetbuf_copyto(&uip_buf[UIP_LLH_LEN]);
source.u8[0] = BUF->srcipaddr.u8[2];
source.u8[1] = BUF->srcipaddr.u8[3];
e = route_lookup(&source);
if(e == NULL) {
route_add(&source, from, 10, 0);
} else {
route_refresh(e);
}
/* If we received data via a gateway, we refresh the gateway route.
* Note: we refresh OUR gateway route, although we are not sure it forwarded the data. */
if(!uip_ipaddr_maskcmp(&BUF->srcipaddr, &netaddr, &netmask)) {
e = route_lookup(&gateway);
if(e != NULL) {
route_refresh(e);
}
}
PRINTF("uip-over-mesh: %d.%d: recv_data with len %d\n",
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1], uip_len);
tcpip_input();
}
/*---------------------------------------------------------------------------*/
static void
send_data(linkaddr_t *next)
{
PRINTF("uip-over-mesh: %d.%d: send_data with len %d\n",
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],
packetbuf_totlen());
unicast_send(&dataconn, next);
}
/*---------------------------------------------------------------------------*/
static void
new_route(struct route_discovery_conn *c, const linkaddr_t *to)
{
struct route_entry *rt;
if(queued_packet) {
PRINTF("uip-over-mesh: new route, sending queued packet\n");
queuebuf_to_packetbuf(queued_packet);
queuebuf_free(queued_packet);
queued_packet = NULL;
rt = route_lookup(&queued_receiver);
if(rt) {
route_decay(rt);
send_data(&queued_receiver);
}
}
}
/*---------------------------------------------------------------------------*/
static void
timedout(struct route_discovery_conn *c)
{
PRINTF("uip-over-mesh: packet timed out\n");
if(queued_packet) {
PRINTF("uip-over-mesh: freeing queued packet\n");
queuebuf_free(queued_packet);
queued_packet = NULL;
}
}
/*---------------------------------------------------------------------------*/
static const struct unicast_callbacks data_callbacks = { recv_data };
static const struct route_discovery_callbacks rdc = { new_route, timedout };
/*---------------------------------------------------------------------------*/
struct gateway_msg {
linkaddr_t gateway;
};
static uint8_t is_gateway;
static void
gateway_announce_recv(struct trickle_conn *c)
{
struct gateway_msg *msg;
msg = packetbuf_dataptr();
PRINTF("%d.%d: gateway message: %d.%d\n",
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],
msg->gateway.u8[0], msg->gateway.u8[1]);
if(!is_gateway) {
uip_over_mesh_set_gateway(&msg->gateway);
}
}
/*---------------------------------------------------------------------------*/
void
uip_over_mesh_make_announced_gateway(void)
{
struct gateway_msg msg;
/* Make this node the gateway node, unless it already is the
gateway. */
if(!is_gateway) {
PRINTF("%d.%d: making myself the gateway\n",
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
uip_over_mesh_set_gateway(&linkaddr_node_addr);
linkaddr_copy(&(msg.gateway), &linkaddr_node_addr);
packetbuf_copyfrom(&msg, sizeof(struct gateway_msg));
trickle_send(&gateway_announce_conn);
is_gateway = 1;
}
}
const static struct trickle_callbacks trickle_call = {gateway_announce_recv};
/*---------------------------------------------------------------------------*/
void
uip_over_mesh_init(uint16_t channels)
{
PRINTF("Our address is %d.%d (%d.%d.%d.%d)\n",
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1],
uip_hostaddr.u8[0], uip_hostaddr.u8[1],
uip_hostaddr.u8[2], uip_hostaddr.u8[3]);
unicast_open(&dataconn, channels, &data_callbacks);
route_discovery_open(&route_discovery, ROUTE_DISCOVERY_INTERVAL,
channels + 1, &rdc);
trickle_open(&gateway_announce_conn, ROUTE_TRICKLE_INTERVAL, channels + 3,
&trickle_call);
route_init();
/* Set lifetime to 30 seconds for non-refreshed routes. */
route_set_lifetime(30);
}
/*---------------------------------------------------------------------------*/
uint8_t
uip_over_mesh_send(void)
{
linkaddr_t receiver;
struct route_entry *rt;
/* This function is called by the uip-fw module to send out an IP
packet. We try to send the IP packet to the next hop route, or we
queue the packet and send out a route request for the final
receiver of the packet. */
/* Packets destined to this network is sent using mesh, whereas
packets destined to a network outside this network is sent towards
the gateway node. */
if(uip_ipaddr_maskcmp(&BUF->destipaddr, &netaddr, &netmask)) {
receiver.u8[0] = BUF->destipaddr.u8[2];
receiver.u8[1] = BUF->destipaddr.u8[3];
} else {
if(linkaddr_cmp(&gateway, &linkaddr_node_addr)) {
PRINTF("uip_over_mesh_send: I am gateway, packet to %d.%d.%d.%d to local interface\n",
uip_ipaddr_to_quad(&BUF->destipaddr));
if(gw_netif != NULL) {
return gw_netif->output();
}
return UIP_FW_DROPPED;
} else if(linkaddr_cmp(&gateway, &linkaddr_null)) {
PRINTF("uip_over_mesh_send: No gateway setup, dropping packet\n");
return UIP_FW_OK;
} else {
PRINTF("uip_over_mesh_send: forwarding packet to %d.%d.%d.%d towards gateway %d.%d\n",
uip_ipaddr_to_quad(&BUF->destipaddr),
gateway.u8[0], gateway.u8[1]);
linkaddr_copy(&receiver, &gateway);
}
}
PRINTF("uIP over mesh send to %d.%d with len %d\n",
receiver.u8[0], receiver.u8[1],
uip_len);
packetbuf_copyfrom(&uip_buf[UIP_LLH_LEN], uip_len);
rt = route_lookup(&receiver);
if(rt == NULL) {
PRINTF("uIP over mesh no route to %d.%d\n", receiver.u8[0], receiver.u8[1]);
if(queued_packet == NULL) {
queued_packet = queuebuf_new_from_packetbuf();
linkaddr_copy(&queued_receiver, &receiver);
route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT);
} else if(!linkaddr_cmp(&queued_receiver, &receiver)) {
route_discovery_discover(&route_discovery, &receiver, ROUTE_TIMEOUT);
}
} else {
route_decay(rt);
send_data(&rt->nexthop);
}
return UIP_FW_OK;
}
/*---------------------------------------------------------------------------*/
void
uip_over_mesh_set_gateway_netif(struct uip_fw_netif *n)
{
gw_netif = n;
}
/*---------------------------------------------------------------------------*/
void
uip_over_mesh_set_gateway(linkaddr_t *gw)
{
linkaddr_copy(&gateway, gw);
}
/*---------------------------------------------------------------------------*/
void
uip_over_mesh_set_net(uip_ipaddr_t *addr, uip_ipaddr_t *mask)
{
uip_ipaddr_copy(&netaddr, addr);
uip_ipaddr_copy(&netmask, mask);
}
/*---------------------------------------------------------------------------*/

View File

@ -1,55 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Header file for tunnelling uIP over Rime mesh
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef UIP_OVER_MESH_H_
#define UIP_OVER_MESH_H_
#include "net/ip/uip.h"
#include "net/ipv4/uip-fw.h"
void uip_over_mesh_init(uint16_t channels);
uint8_t uip_over_mesh_send(void);
void uip_over_mesh_set_gateway_netif(struct uip_fw_netif *netif);
void uip_over_mesh_set_gateway(linkaddr_t *gw);
void uip_over_mesh_set_net(uip_ipaddr_t *addr, uip_ipaddr_t *mask);
void uip_over_mesh_make_announced_gateway(void);
#endif /* UIP-OVER-MESH_H_ */

File diff suppressed because it is too large Load Diff

View File

@ -1,440 +0,0 @@
/*
* Copyright (c) 2001-2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
*
*/
/**
* \file
* Implementation of the ARP Address Resolution Protocol.
* \author Adam Dunkels <adam@dunkels.com>
*
*/
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup uiparp uIP Address Resolution Protocol
* @{
*
* The Address Resolution Protocol ARP is used for mapping between IP
* addresses and link level addresses such as the Ethernet MAC
* addresses. ARP uses broadcast queries to ask for the link level
* address of a known IP address and the host which is configured with
* the IP address for which the query was meant, will respond with its
* link level address.
*
* \note This ARP implementation only supports Ethernet.
*/
#include "net/ipv4/uip_arp.h"
#include <string.h>
struct arp_hdr {
struct uip_eth_hdr ethhdr;
uint16_t hwtype;
uint16_t protocol;
uint8_t hwlen;
uint8_t protolen;
uint16_t opcode;
struct uip_eth_addr shwaddr;
uip_ipaddr_t sipaddr;
struct uip_eth_addr dhwaddr;
uip_ipaddr_t dipaddr;
};
struct ethip_hdr {
struct uip_eth_hdr ethhdr;
/* IP header. */
uint8_t vhl,
tos,
len[2],
ipid[2],
ipoffset[2],
ttl,
proto;
uint16_t ipchksum;
uip_ipaddr_t srcipaddr, destipaddr;
};
#define ARP_REQUEST 1
#define ARP_REPLY 2
#define ARP_HWTYPE_ETH 1
struct arp_entry {
uip_ipaddr_t ipaddr;
struct uip_eth_addr ethaddr;
uint8_t time;
};
static const struct uip_eth_addr broadcast_ethaddr =
{{0xff,0xff,0xff,0xff,0xff,0xff}};
static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
static uip_ipaddr_t ipaddr;
static uint8_t i, c;
static uint8_t arptime;
static uint8_t tmpage;
#define BUF ((struct arp_hdr *)&uip_buf[0])
#define IPBUF ((struct ethip_hdr *)&uip_buf[0])
#define DEBUG 0
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#else
#define PRINTF(...)
#endif
/*-----------------------------------------------------------------------------------*/
/**
* Initialize the ARP module.
*
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_init(void)
{
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
memset(&arp_table[i].ipaddr, 0, 4);
}
}
/*-----------------------------------------------------------------------------------*/
/**
* Periodic ARP processing function.
*
* This function performs periodic timer processing in the ARP module
* and should be called at regular intervals. The recommended interval
* is 10 seconds between the calls.
*
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_timer(void)
{
struct arp_entry *tabptr;
++arptime;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr) &&
arptime - tabptr->time >= UIP_ARP_MAXAGE) {
memset(&tabptr->ipaddr, 0, 4);
}
}
}
/*-----------------------------------------------------------------------------------*/
static void
uip_arp_update(uip_ipaddr_t *ipaddr, struct uip_eth_addr *ethaddr)
{
register struct arp_entry *tabptr = arp_table;
/* Walk through the ARP mapping table and try to find an entry to
update. If none is found, the IP -> MAC address mapping is
inserted in the ARP table. */
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
/* Only check those entries that are actually in use. */
if(!uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {
/* Check if the source IP address of the incoming packet matches
the IP address in this ARP table entry. */
if(uip_ipaddr_cmp(ipaddr, &tabptr->ipaddr)) {
/* An old entry found, update this and return. */
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
return;
}
}
tabptr++;
}
/* If we get here, no existing ARP table entry was found, so we
create one. */
/* First, we try to find an unused entry in the ARP table. */
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(uip_ipaddr_cmp(&tabptr->ipaddr, &uip_all_zeroes_addr)) {
break;
}
}
/* If no unused entry is found, we try to find the oldest entry and
throw it away. */
if(i == UIP_ARPTAB_SIZE) {
tmpage = 0;
c = 0;
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
tabptr = &arp_table[i];
if(arptime - tabptr->time > tmpage) {
tmpage = arptime - tabptr->time;
c = i;
}
}
i = c;
tabptr = &arp_table[i];
}
/* Now, i is the ARP table entry which we will fill with the new
information. */
uip_ipaddr_copy(&tabptr->ipaddr, ipaddr);
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
tabptr->time = arptime;
}
/*-----------------------------------------------------------------------------------*/
/**
* ARP processing for incoming IP packets
*
* This function should be called by the device driver when an IP
* packet has been received. The function will check if the address is
* in the ARP cache, and if so the ARP cache entry will be
* refreshed. If no ARP cache entry was found, a new one is created.
*
* This function expects an IP packet with a prepended Ethernet header
* in the uip_buf[] buffer, and the length of the packet in the global
* variable uip_len.
*/
/*-----------------------------------------------------------------------------------*/
#if 0
void
uip_arp_ipin(void)
{
uip_len -= sizeof(struct uip_eth_hdr);
/* Only insert/update an entry if the source IP address of the
incoming IP packet comes from a host on the local network. */
if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
(uip_hostaddr[0] & uip_netmask[0])) {
return;
}
if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
(uip_hostaddr[1] & uip_netmask[1])) {
return;
}
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
return;
}
#endif /* 0 */
/*-----------------------------------------------------------------------------------*/
/**
* ARP processing for incoming ARP packets.
*
* This function should be called by the device driver when an ARP
* packet has been received. The function will act differently
* depending on the ARP packet type: if it is a reply for a request
* that we previously sent out, the ARP cache will be filled in with
* the values from the ARP reply. If the incoming ARP packet is an ARP
* request for our IP address, an ARP reply packet is created and put
* into the uip_buf[] buffer.
*
* When the function returns, the value of the global variable uip_len
* indicates whether the device driver should send out a packet or
* not. If uip_len is zero, no packet should be sent. If uip_len is
* non-zero, it contains the length of the outbound packet that is
* present in the uip_buf[] buffer.
*
* This function expects an ARP packet with a prepended Ethernet
* header in the uip_buf[] buffer, and the length of the packet in the
* global variable uip_len.
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_arpin(void)
{
if(uip_len < sizeof(struct arp_hdr)) {
uip_clear_buf();
return;
}
uip_clear_buf();
switch(BUF->opcode) {
case UIP_HTONS(ARP_REQUEST):
/* ARP request. If it asked for our address, we send out a
reply. */
/* if(BUF->dipaddr[0] == uip_hostaddr[0] &&
BUF->dipaddr[1] == uip_hostaddr[1]) {*/
PRINTF("uip_arp_arpin: request for %d.%d.%d.%d (we are %d.%d.%d.%d)\n",
BUF->dipaddr.u8[0], BUF->dipaddr.u8[1],
BUF->dipaddr.u8[2], BUF->dipaddr.u8[3],
uip_hostaddr.u8[0], uip_hostaddr.u8[1],
uip_hostaddr.u8[2], uip_hostaddr.u8[3]);
if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) {
/* First, we register the one who made the request in our ARP
table, since it is likely that we will do more communication
with this host in the future. */
uip_arp_update(&BUF->sipaddr, &BUF->shwaddr);
BUF->opcode = UIP_HTONS(ARP_REPLY);
memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_lladdr.addr, 6);
memcpy(BUF->ethhdr.src.addr, uip_lladdr.addr, 6);
memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
uip_ipaddr_copy(&BUF->dipaddr, &BUF->sipaddr);
uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr);
BUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP);
uip_len = sizeof(struct arp_hdr);
}
break;
case UIP_HTONS(ARP_REPLY):
/* ARP reply. We insert or update the ARP table if it was meant
for us. */
if(uip_ipaddr_cmp(&BUF->dipaddr, &uip_hostaddr)) {
uip_arp_update(&BUF->sipaddr, &BUF->shwaddr);
}
break;
}
return;
}
/*-----------------------------------------------------------------------------------*/
/**
* Prepend Ethernet header to an outbound IP packet and see if we need
* to send out an ARP request.
*
* This function should be called before sending out an IP packet. The
* function checks the destination IP address of the IP packet to see
* what Ethernet MAC address that should be used as a destination MAC
* address on the Ethernet.
*
* If the destination IP address is in the local network (determined
* by logical ANDing of netmask and our IP address), the function
* checks the ARP cache to see if an entry for the destination IP
* address is found. If so, an Ethernet header is prepended and the
* function returns. If no ARP cache entry is found for the
* destination IP address, the packet in the uip_buf[] is replaced by
* an ARP request packet for the IP address. The IP packet is dropped
* and it is assumed that they higher level protocols (e.g., TCP)
* eventually will retransmit the dropped packet.
*
* If the destination IP address is not on the local network, the IP
* address of the default router is used instead.
*
* When the function returns, a packet is present in the uip_buf[]
* buffer, and the length of the packet is in the global variable
* uip_len.
*/
/*-----------------------------------------------------------------------------------*/
void
uip_arp_out(void)
{
struct arp_entry *tabptr = arp_table;
/* Find the destination IP address in the ARP table and construct
the Ethernet header. If the destination IP addres isn't on the
local network, we use the default router's IP address instead.
If not ARP table entry is found, we overwrite the original IP
packet with an ARP request for the IP address. */
/* First check if destination is a local broadcast. */
if(uip_ipaddr_cmp(&IPBUF->destipaddr, &uip_broadcast_addr)) {
memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
} else if(IPBUF->destipaddr.u8[0] == 224) {
/* Multicast. */
IPBUF->ethhdr.dest.addr[0] = 0x01;
IPBUF->ethhdr.dest.addr[1] = 0x00;
IPBUF->ethhdr.dest.addr[2] = 0x5e;
IPBUF->ethhdr.dest.addr[3] = IPBUF->destipaddr.u8[1];
IPBUF->ethhdr.dest.addr[4] = IPBUF->destipaddr.u8[2];
IPBUF->ethhdr.dest.addr[5] = IPBUF->destipaddr.u8[3];
} else {
/* Check if the destination address is on the local network. */
if(!uip_ipaddr_maskcmp(&IPBUF->destipaddr, &uip_hostaddr, &uip_netmask)) {
/* Destination address was not on the local network, so we need to
use the default router's IP address instead of the destination
address when determining the MAC address. */
uip_ipaddr_copy(&ipaddr, &uip_draddr);
} else {
/* Else, we use the destination IP address. */
uip_ipaddr_copy(&ipaddr, &IPBUF->destipaddr);
}
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
if(uip_ipaddr_cmp(&ipaddr, &tabptr->ipaddr)) {
break;
}
tabptr++;
}
if(i == UIP_ARPTAB_SIZE) {
/* The destination address was not in our ARP table, so we
overwrite the IP packet with an ARP request. */
memset(BUF->ethhdr.dest.addr, 0xff, 6);
memset(BUF->dhwaddr.addr, 0x00, 6);
memcpy(BUF->ethhdr.src.addr, uip_lladdr.addr, 6);
memcpy(BUF->shwaddr.addr, uip_lladdr.addr, 6);
uip_ipaddr_copy(&BUF->dipaddr, &ipaddr);
uip_ipaddr_copy(&BUF->sipaddr, &uip_hostaddr);
BUF->opcode = UIP_HTONS(ARP_REQUEST); /* ARP request. */
BUF->hwtype = UIP_HTONS(ARP_HWTYPE_ETH);
BUF->protocol = UIP_HTONS(UIP_ETHTYPE_IP);
BUF->hwlen = 6;
BUF->protolen = 4;
BUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP);
uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
uip_len = sizeof(struct arp_hdr);
return;
}
/* Build an ethernet header. */
memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
}
memcpy(IPBUF->ethhdr.src.addr, uip_lladdr.addr, 6);
IPBUF->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_IP);
uip_len += sizeof(struct uip_eth_hdr);
}
/*-----------------------------------------------------------------------------------*/
/** @} */
/** @} */

View File

@ -1,142 +0,0 @@
/*
* Copyright (c) 2001-2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
*
*/
/**
* \file
* Macros and definitions for the ARP module.
* \author Adam Dunkels <adam@dunkels.com>
*/
/**
* \addtogroup uip
* @{
*/
/**
* \addtogroup uiparp
* @{
*/
#ifndef UIP_ARP_H_
#define UIP_ARP_H_
#include "net/ip/uip.h"
/**
* The Ethernet header.
*/
struct uip_eth_hdr {
struct uip_eth_addr dest;
struct uip_eth_addr src;
uint16_t type;
};
#define UIP_ETHTYPE_ARP 0x0806
#define UIP_ETHTYPE_IP 0x0800
#define UIP_ETHTYPE_IPV6 0x86dd
/* The uip_arp_init() function must be called before any of the other
ARP functions. */
void uip_arp_init(void);
/* The uip_arp_ipin() function should be called whenever an IP packet
arrives from the Ethernet. This function refreshes the ARP table or
inserts a new mapping if none exists. The function assumes that an
IP packet with an Ethernet header is present in the uip_buf buffer
and that the length of the packet is in the uip_len variable. */
/*void uip_arp_ipin(void);*/
#define uip_arp_ipin()
/* The uip_arp_arpin() should be called when an ARP packet is received
by the Ethernet driver. This function also assumes that the
Ethernet frame is present in the uip_buf buffer. When the
uip_arp_arpin() function returns, the contents of the uip_buf
buffer should be sent out on the Ethernet if the uip_len variable
is > 0. */
void uip_arp_arpin(void);
/* The uip_arp_out() function should be called when an IP packet
should be sent out on the Ethernet. This function creates an
Ethernet header before the IP header in the uip_buf buffer. The
Ethernet header will have the correct Ethernet MAC destination
address filled in if an ARP table entry for the destination IP
address (or the IP address of the default router) is present. If no
such table entry is found, the IP packet is overwritten with an ARP
request and we rely on TCP to retransmit the packet that was
overwritten. In any case, the uip_len variable holds the length of
the Ethernet frame that should be transmitted. */
void uip_arp_out(void);
/* The uip_arp_timer() function should be called every ten seconds. It
is responsible for flushing old entries in the ARP table. */
void uip_arp_timer(void);
/** @} */
/**
* \addtogroup uipconffunc
* @{
*/
/**
* Specifiy the Ethernet MAC address.
*
* The ARP code needs to know the MAC address of the Ethernet card in
* order to be able to respond to ARP queries and to generate working
* Ethernet headers.
*
* \note This macro only specifies the Ethernet MAC address to the ARP
* code. It cannot be used to change the MAC address of the Ethernet
* card.
*
* \param eaddr A pointer to a struct uip_eth_addr containing the
* Ethernet MAC address of the Ethernet card.
*
* \hideinitializer
*/
#define uip_setethaddr(eaddr) do {uip_lladdr.addr[0] = eaddr.addr[0]; \
uip_lladdr.addr[1] = eaddr.addr[1];\
uip_lladdr.addr[2] = eaddr.addr[2];\
uip_lladdr.addr[3] = eaddr.addr[3];\
uip_lladdr.addr[4] = eaddr.addr[4];\
uip_lladdr.addr[5] = eaddr.addr[5];} while(0)
/** @} */
#endif /* UIP_ARP_H_ */
/** @} */

View File

@ -21,7 +21,7 @@ low as a few hundred bytes.
uIP can be found at the uIP web page: http://www.sics.se/~adam/uip/
\sa \ref tcpip
\sa \ref tcpip
\sa \ref uip6 and sicslowpan
\sa \ref uipopt "uIP Compile-time configuration options"
\sa \ref uipconffunc "uIP Run-time configuration functions"
@ -30,7 +30,7 @@ uIP can be found at the uIP web page: http://www.sics.se/~adam/uip/
\ref uipdrivervars "uIP variables used by device drivers"
\sa \ref uipappfunc "uIP functions called from application programs"
(see below) and the \ref psock "protosockets API" and their underlying
\ref pt "protothreads"
\ref pt "protothreads"
\section uIPIntroduction Introduction
@ -97,7 +97,7 @@ The formal requirements for the protocols in the TCP/IP stack is
specified in a number of RFC documents published by the Internet
Engineering Task Force, IETF. Each of the protocols in the stack is
defined in one more RFC documents and RFC1122 collects
all requirements and updates the previous RFCs.
all requirements and updates the previous RFCs.
The RFC1122 requirements can be divided into two categories; those
that deal with the host to host communication and those that deal with
@ -327,7 +327,7 @@ to inspect the uip_conn->lport (the local TCP port number) to decide
which service the connection should provide. For instance, an
application might decide to act as an HTTP server if the value of
uip_conn->lport is equal to 80 and act as a TELNET server if the value
is 23.
is 23.
\subsubsection recvdata Receiving Data
@ -442,7 +442,7 @@ the next time the connection is polled by uIP. The uip_connect()
function returns
a pointer to the uip_conn structure for the new
connection. If there are no free connection slots, the function
returns NULL.
returns NULL.
The function uip_ipaddr() may be used to pack an IP address into the
two element 16-bit array used by uIP to represent IP addresses.
@ -451,14 +451,14 @@ Two examples of usage are shown below. The first example shows how to
open a connection to TCP port 8080 of the remote end of the current
connection. If there are not enough TCP connection slots to allow a
new connection to be opened, the uip_connect() function returns NULL
and the current connection is aborted by uip_abort().
and the current connection is aborted by uip_abort().
\code
void connect_example1_app(void) {
if(uip_connect(uip_conn->ripaddr, HTONS(8080)) == NULL) {
uip_abort();
}
}
}
\endcode
The second example shows how to open a new connection to a specific IP
@ -512,7 +512,7 @@ application function was called because data was lost in the network
and has to be retransmitted, it also sends an "ok". Note that this
example actually shows a complete uIP application. It is not required
for an application to deal with all types of events such as
uip_connected() or uip_timedout().
uip_connected() or uip_timedout().
\subsection example2 A More Advanced Application
@ -573,12 +573,12 @@ void example2_app(void) {
struct example2_state *s;
s = (struct example2_state *)uip_conn->appstate;
if(uip_connected()) {
s->state = WELCOME_SENT;
uip_send("Welcome!\n", 9);
return;
}
}
if(uip_acked() && s->state == WELCOME_SENT) {
s->state = WELCOME_ACKED;
@ -618,7 +618,7 @@ how the two examples above can be combined into one application.
\code
void example3_init(void) {
example1_init();
example2_init();
example2_init();
}
void example3_app(void) {
@ -708,7 +708,7 @@ void example5_init(void) {
void example5_app(void) {
struct example5_state *s;
s = (struct example5_state)uip_conn->appstate;
if(uip_connected()) {
switch(uip_conn->lport) {
case HTONS(80):
@ -721,7 +721,7 @@ void example5_app(void) {
break;
}
uip_send(s->dataptr, s->dataleft);
return;
return;
}
if(uip_acked()) {
@ -731,7 +731,7 @@ void example5_app(void) {
}
s->dataptr += uip_conn->len;
s->dataleft -= uip_conn->len;
uip_send(s->dataptr, s->dataleft);
uip_send(s->dataptr, s->dataleft);
}
}
\endcode
@ -741,7 +741,7 @@ sent and the size of the data that is left to send. When a remote host
connects to the application, the local port number is used to
determine which file to send. The first chunk of data is sent using
uip_send(). uIP makes sure that no more than MSS bytes of data is
actually sent, even though s->dataleft may be larger than the MSS.
actually sent, even though s->dataleft may be larger than the MSS.
The application is driven by incoming acknowledgments. When data has
been acknowledged, new data can be sent. If there is no more data to
@ -847,7 +847,7 @@ static void newdata(void) {
static void acked(void) {
struct example6_state *s = (struct example6_state *)uip_conn->appstate;
s->textlen -= uip_conn->len;
s->textptr += uip_conn->len;
if(s->textlen == 0) {
@ -879,7 +879,7 @@ message. The "state" variable can be either "STATE_WAITING", meaning
that the application is waiting for data to arrive from the network,
"STATE_HELLO", in which the application is sending the "Hello" part of
the message, or "STATE_WORLD", in which the application is sending the
"world!" message.
"world!" message.
The application does not handle errors or connection closing events,
and therefore the aborted(), timedout() and closed() functions are
@ -1171,7 +1171,7 @@ algorithm disabled at the receiver, the maximum throughput would be
It should be noted, however, that since small systems running uIP are
not very likely to have large amounts of data to send, the delayed
acknowledgmen t throughput degradation of uIP need not be very
acknowledgment throughput degradation of uIP need not be very
severe. Small amounts of data sent by such a system will not span more
than a single TCP segment, and would therefore not be affected by the
throughput degradation anyway.
@ -1179,13 +1179,9 @@ throughput degradation anyway.
The maximum throughput when uIP acts as a receiver is not affected by
the delayed acknowledgment throughput degradation.
\note The \ref uipsplit module implements a hack that overcomes the
problems with the delayed acknowledgment throughput degradation.
@{
*/
/** @} */
/** @} */

View File

@ -1,122 +0,0 @@
#include "descriptors.h"
#include <cdc-acm/cdc.h>
#include <contiki-conf.h>
#include <usb-arch.h>
const struct usb_st_device_descriptor device_descriptor =
{
sizeof(struct usb_st_device_descriptor),
DEVICE,
0x0210,
CDC,
0,
0,
CTRL_EP_SIZE,
0xffff,
0xffff,
0x0010,
2,
1,
3,
1
};
const struct configuration_st {
struct usb_st_configuration_descriptor configuration;
struct usb_st_interface_descriptor comm;
struct usb_cdc_header_func_descriptor header;
struct usb_cdc_union_func_descriptor union_descr;
struct usb_cdc_ethernet_func_descriptor ethernet;
#if 1
struct usb_st_endpoint_descriptor ep_notification;
#endif
struct usb_st_interface_descriptor data;
struct usb_st_endpoint_descriptor ep_in;
struct usb_st_endpoint_descriptor ep_out;
} BYTE_ALIGNED configuration_block =
{
/* Configuration */
{
sizeof(configuration_block.configuration),
CONFIGURATION,
sizeof(configuration_block),
2,
1,
0,
0x80,
50
},
{
sizeof(configuration_block.comm),
INTERFACE,
0,
0,
1,
CDC,
ETHERNET_NETWORKING_CONTROL_MODEL,
0,
0
},
{
sizeof(configuration_block.header),
CS_INTERFACE,
CDC_FUNC_DESCR_HEADER,
0x0110
},
{
sizeof(configuration_block.union_descr),
CS_INTERFACE,
CDC_FUNC_DESCR_UNION,
0, /* Master */
{1} /* Slave */
},
{
sizeof(configuration_block.ethernet),
CS_INTERFACE,
CDC_FUNC_DESCR_ETHERNET,
4,
0, /* No statistics */
UIP_CONF_BUFFER_SIZE - UIP_CONF_LLH_LEN + 14,
0, /* No multicast filters */
0 /* No wake-up filters */
},
{
sizeof(configuration_block.ep_notification),
ENDPOINT,
0x83,
0x03,
8,
100
},
{
sizeof(configuration_block.data),
INTERFACE,
1,
0,
2,
CDC_DATA,
0,
TRANSPARENT_PROTOCOL,
0
},
{
sizeof(configuration_block.ep_in),
ENDPOINT,
0x81,
0x02,
64,
0
},
{
sizeof(configuration_block.ep_out),
ENDPOINT,
0x02,
0x02,
64,
0
}
};
const struct usb_st_configuration_descriptor const *configuration_head =
(struct usb_st_configuration_descriptor const*)&configuration_block;

View File

@ -1,43 +0,0 @@
#include "string-descriptors.h"
static const struct {
struct usb_st_string_descriptor base;
Uint16 chars[18];
} string_descriptor_1_en= {{40, 3, {'U'}}, {
'S', 'B', ' ', 'p', 's', 'e', 'u', 'd', 'o', ' ', 'e', 't', 'h', 'e', 'r', 'n', 'e', 't'}};
static const struct {
struct usb_st_string_descriptor base;
Uint16 chars[8];
} string_descriptor_2_all= {{20, 3, {'F'}}, {
'l', 'u', 'f', 'f', 'w', 'a', 'r', 'e'}};
static const struct {
struct usb_st_string_descriptor base;
Uint16 chars[2];
} string_descriptor_3_all= {{8, 3, {'0'}}, {
'.', '1'}};
static const struct {
struct usb_st_string_descriptor base;
Uint16 chars[11];
} string_descriptor_4_all= {{26, 3, {'0'}}, {
'2', '0', '0', '0', '0', '0', '0', '0', '0', '0', '1'}};
static const struct usb_st_string_descriptor * string_table_en[] =
{
&string_descriptor_1_en.base,
&string_descriptor_2_all.base,
&string_descriptor_3_all.base,
&string_descriptor_4_all.base,
};
static const struct {
struct usb_st_language_descriptor base;
Uint16 langs[0];
} language_descriptor =
{
{4, 3, {0x0409}},
{}};
static const struct {
struct usb_st_string_languages base;
struct usb_st_string_language_map map[0];
} string_languages_full={{1, 4, &language_descriptor.base,
{{0x0409, string_table_en}}}, {
}
};
const struct usb_st_string_languages * const string_languages = &string_languages_full.base;

View File

@ -1,170 +0,0 @@
#include <cdc-eth.h>
#include <usb-api.h>
#include <uip_arp.h>
#include <stdio.h>
#include <string.h>
#include <net/ipv4/uip-fw.h>
#define DATA_IN 0x81
#define DATA_OUT 0x02
#define INTERRUPT_IN 0x83
struct uip_eth_addr default_uip_ethaddr = {{0x02,0x00,0x00,0x00,0x00,0x02}};
static unsigned int
handle_cdc_eth_requests()
{
return 0;
}
static const struct USBRequestHandler cdc_eth_request_handler =
{
0x21, 0x7f,
0x00, 0x00,
handle_cdc_eth_requests
};
static struct USBRequestHandlerHook cdc_eth_request_hook =
{
NULL,
&cdc_eth_request_handler
};
static USBBuffer recv_buffer;
static uint8_t recv_data[UIP_BUFSIZE];
static USBBuffer xmit_buffer[3];
static uint8_t xmit_data[UIP_BUFSIZE];
static void
init_recv_buffer()
{
recv_buffer.next = NULL;
recv_buffer.data = recv_data;
recv_buffer.left = UIP_BUFSIZE;
recv_buffer.flags = USB_BUFFER_SHORT_END | USB_BUFFER_NOTIFY;
}
uint8_t
usbeth_send(void)
{
if ((xmit_buffer[0].flags & USB_BUFFER_SUBMITTED)) return UIP_FW_DROPPED;
uip_arp_out();
memcpy(xmit_data, uip_buf, uip_len);
xmit_buffer[0].next = NULL;
xmit_buffer[0].left = uip_len;
xmit_buffer[0].flags = USB_BUFFER_NOTIFY | USB_BUFFER_SHORT_END;
xmit_buffer[0].data = xmit_data;
/* printf("usbeth_send: %d\n", uip_len); */
usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
return UIP_FW_OK;
}
static struct uip_fw_netif usbethif =
{UIP_FW_NETIF(172,16,0,1, 255,255,255,255, usbeth_send)};
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
PROCESS(usb_eth_process, "USB ethernet");
PROCESS_THREAD(usb_eth_process, ev , data)
{
PROCESS_BEGIN();
usb_register_request_handler(&cdc_eth_request_hook);
usb_setup();
usb_set_ep_event_process(DATA_OUT, process_current);
usb_set_global_event_process(process_current);
uip_fw_default(&usbethif);
uip_setethaddr(default_uip_ethaddr);
uip_arp_init();
while(1) {
PROCESS_WAIT_EVENT();
if (ev == PROCESS_EVENT_EXIT) break;
if (ev == PROCESS_EVENT_POLL) {
unsigned int events = usb_get_global_events();
if (events) {
if (events & USB_EVENT_CONFIG) {
if (usb_get_current_configuration() != 0) {
printf("Configured\n");
usb_setup_bulk_endpoint(DATA_IN);
usb_setup_bulk_endpoint(DATA_OUT);
usb_setup_interrupt_endpoint(INTERRUPT_IN);
init_recv_buffer();
usb_submit_recv_buffer(DATA_OUT, &recv_buffer);
#if 0
{
static const uint8_t foo[4] = {0x12,0x34,0x56,0x78};
xmit_buffer[0].next = NULL;
xmit_buffer[0].left = sizeof(foo);
xmit_buffer[0].flags = USB_BUFFER_SHORT_END;
xmit_buffer[0].data = &foo;
usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
}
#endif
} else {
usb_disable_endpoint(DATA_IN);
usb_disable_endpoint(DATA_OUT);
usb_disable_endpoint(INTERRUPT_IN);
}
}
}
events = usb_get_ep_events(DATA_OUT);
if (events & USB_EP_EVENT_NOTIFICATION) {
uip_len = sizeof(recv_data) - recv_buffer.left;
/* printf("Received: %d bytes\n", uip_len); */
memcpy(uip_buf, recv_data, uip_len);
#if NETSTACK_CONF_WITH_IPV6
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
uip_neighbor_add(&IPBUF->srcipaddr, &BUF->src);
tcpip_input();
} else
#endif /* NETSTACK_CONF_WITH_IPV6 */
if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) {
uip_len -= sizeof(struct uip_eth_hdr);
tcpip_input();
} else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) {
uip_arp_arpin();
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if (uip_len > 0) {
memcpy(xmit_data, uip_buf, uip_len);
xmit_buffer[0].next = NULL;
xmit_buffer[0].data = xmit_data;
xmit_buffer[0].left = uip_len;
xmit_buffer[0].flags = USB_BUFFER_SHORT_END;
usb_submit_xmit_buffer(DATA_IN, &xmit_buffer[0]);
/* printf("Sent: %d bytes\n", uip_len); */
}
}
init_recv_buffer();
usb_submit_recv_buffer(DATA_OUT, &recv_buffer);
}
}
}
PROCESS_END();
}
void
usb_cdc_eth_setup()
{
process_start(&usb_eth_process, NULL);
}
void
usb_cdc_eth_set_ifaddr(uip_ipaddr_t *addr)
{
usbethif.ipaddr = *addr;
}
void
dummy(uip_ipaddr_t *addr1, uip_ipaddr_t *addr2)
{
*addr1 = *addr2;
}

View File

@ -1,13 +0,0 @@
#ifndef CDC_ETH_H_NUI0ULFC7C__
#define CDC_ETH_H_NUI0ULFC7C__
#include <net/ip/uip.h>
/* Should be called before usb_cdc_eth_setup */
void
usb_cdc_eth_set_ifaddr(uip_ipaddr_t *addr);
void
usb_cdc_eth_setup();
#endif /* CDC_ETH_H_NUI0ULFC7C__ */

View File

@ -1,450 +0,0 @@
/* Adapted by Simon Berg from net/dhcpc.c */
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#include <stdio.h>
#include <string.h>
#include <uip_arp.h>
#include "contiki.h"
#include "contiki-net.h"
#include "dhcps.h"
struct dhcp_msg {
uint8_t op, htype, hlen, hops;
uint8_t xid[4];
uint16_t secs, flags;
uint8_t ciaddr[4];
uint8_t yiaddr[4];
uint8_t siaddr[4];
uint8_t giaddr[4];
uint8_t chaddr[16];
#ifndef UIP_CONF_DHCP_LIGHT
uint8_t sname[64];
uint8_t file[128];
#endif
uint8_t options[312];
} CC_BYTE_ALIGNED;
#define BOOTP_BROADCAST 0x8000
#define DHCP_REQUEST 1
#define DHCP_REPLY 2
#define DHCP_HTYPE_ETHERNET 1
#define DHCP_HLEN_ETHERNET 6
#define DHCP_MSG_LEN 236
#define DHCPS_SERVER_PORT 67
#define DHCPS_CLIENT_PORT 68
#define DHCPDISCOVER 1
#define DHCPOFFER 2
#define DHCPREQUEST 3
#define DHCPDECLINE 4
#define DHCPACK 5
#define DHCPNAK 6
#define DHCPRELEASE 7
#define DHCPINFORM 8
#define DHCP_OPTION_SUBNET_MASK 1
#define DHCP_OPTION_ROUTER 3
#define DHCP_OPTION_DNS_SERVER 6
#define DHCP_OPTION_REQ_IPADDR 50
#define DHCP_OPTION_LEASE_TIME 51
#define DHCP_OPTION_MSG_TYPE 53
#define DHCP_OPTION_SERVER_ID 54
#define DHCP_OPTION_REQ_LIST 55
#define DHCP_OPTION_END 255
#define LEASE_FLAGS_ALLOCATED 0x01 /* Lease with an allocated address*/
#define LEASE_FLAGS_VALID 0x02 /* Contains a valid but
possibly outdated lease */
static const struct dhcps_config *config;
static uint8_t *
find_option(uint8_t option)
{
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
uint8_t *optptr = &m->options[4];
uint8_t *end = (uint8_t*)uip_appdata + uip_datalen();
while(optptr < end && *optptr != DHCP_OPTION_END) {
if(*optptr == option) {
return optptr;
}
optptr += optptr[1] + 2;
}
return NULL;
}
static const uint8_t magic_cookie[4] = {99, 130, 83, 99};
static int
check_cookie(void)
{
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
return memcmp(m->options, magic_cookie, 4) == 0;
}
/* Finds any valid lease for a given MAC address */
static struct dhcps_client_lease *
lookup_lease_mac(const uint8_t *chaddr, uint8_t hlen)
{
struct dhcps_client_lease *lease = config->leases;
struct dhcps_client_lease *end = config->leases + config->num_leases;
while(lease != end) {
if (lease->flags & LEASE_FLAGS_VALID
&& memcmp(lease->chaddr, chaddr, hlen) == 0) {
return lease;
}
lease++;
}
return NULL;
}
static struct dhcps_client_lease *
lookup_lease_ip(const uip_ipaddr_t *ip)
{
struct dhcps_client_lease *lease = config->leases;
struct dhcps_client_lease *end = config->leases + config->num_leases;
while(lease != end) {
if (uip_ipaddr_cmp(&lease->ipaddr, ip)) {
return lease;
}
lease++;
}
return NULL;
}
static struct dhcps_client_lease *
find_free_lease(void)
{
struct dhcps_client_lease *found = NULL;
struct dhcps_client_lease *lease = config->leases;
struct dhcps_client_lease *end = config->leases + config->num_leases;
while(lease != end) {
if (!(lease->flags & LEASE_FLAGS_VALID)) return lease;
if (!(lease->flags & LEASE_FLAGS_ALLOCATED)) found = lease;
lease++;
}
return found;
}
struct dhcps_client_lease *
init_lease(struct dhcps_client_lease *lease,
const uint8_t *chaddr, uint8_t hlen)
{
if (lease) {
memcpy(lease->chaddr, chaddr, hlen);
lease->flags = LEASE_FLAGS_VALID;
}
return lease;
}
static struct dhcps_client_lease *
choose_address()
{
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
struct dhcps_client_lease *lease;
lease = lookup_lease_mac(m->chaddr, m->hlen);
if (lease) {
return lease;
}
{
uint8_t *opt;
opt = find_option(DHCP_OPTION_REQ_IPADDR);
if (opt && (lease = lookup_lease_ip((uip_ipaddr_t*)&opt[2]))
&& !(lease->flags & LEASE_FLAGS_ALLOCATED)) {
return init_lease(lease, m->chaddr,m->hlen);
}
}
lease = find_free_lease();
if (lease) {
return init_lease(lease, m->chaddr,m->hlen);
}
return NULL;
}
static struct dhcps_client_lease *
allocate_address()
{
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
struct dhcps_client_lease *lease;
lease = lookup_lease_mac(m->chaddr, m->hlen);
if (!lease) {
uint8_t *opt;
opt = find_option(DHCP_OPTION_REQ_IPADDR);
if (!(opt && (lease = lookup_lease_ip((uip_ipaddr_t*)&opt[2]))
&& !(lease->flags & LEASE_FLAGS_ALLOCATED))) {
return NULL;
}
}
lease->lease_end = clock_seconds()+config->default_lease_time;
lease->flags |= LEASE_FLAGS_ALLOCATED;
return lease;
}
static struct dhcps_client_lease *
release_address()
{
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
struct dhcps_client_lease *lease;
lease = lookup_lease_mac(m->chaddr, m->hlen);
if (!lease) {
return NULL;
}
lease->flags &= ~LEASE_FLAGS_ALLOCATED;
return lease;
}
/*---------------------------------------------------------------------------*/
static uint8_t *
add_msg_type(uint8_t *optptr, uint8_t type)
{
*optptr++ = DHCP_OPTION_MSG_TYPE;
*optptr++ = 1;
*optptr++ = type;
return optptr;
}
/*---------------------------------------------------------------------------*/
static uint8_t *
add_server_id(uint8_t *optptr)
{
*optptr++ = DHCP_OPTION_SERVER_ID;
*optptr++ = 4;
memcpy(optptr, &uip_hostaddr, 4);
return optptr + 4;
}
/*---------------------------------------------------------------------------*/
static uint8_t *
add_lease_time(uint8_t *optptr)
{
uint32_t lt;
*optptr++ = DHCP_OPTION_LEASE_TIME;
*optptr++ = 4;
lt = UIP_HTONL(config->default_lease_time);
memcpy(optptr, &lt, 4);
return optptr + 4;
}
/*---------------------------------------------------------------------------*/
static uint8_t *
add_end(uint8_t *optptr)
{
*optptr++ = DHCP_OPTION_END;
return optptr;
}
static uint8_t *
add_config(uint8_t *optptr)
{
if (config->flags & DHCP_CONF_NETMASK) {
*optptr++ = DHCP_OPTION_SUBNET_MASK;
*optptr++ = 4;
memcpy(optptr, &config->netmask, 4);
optptr += 4;
}
if (config->flags & DHCP_CONF_DNSADDR) {
*optptr++ = DHCP_OPTION_DNS_SERVER;
*optptr++ = 4;
memcpy(optptr, &config->dnsaddr, 4);
optptr += 4;
}
if (config->flags & DHCP_CONF_DEFAULT_ROUTER) {
*optptr++ = DHCP_OPTION_ROUTER;
*optptr++ = 4;
memcpy(optptr, &config->default_router, 4);
optptr += 4;
}
return optptr;
}
static void
create_msg(CC_REGISTER_ARG struct dhcp_msg *m)
{
m->op = DHCP_REPLY;
/* m->htype = DHCP_HTYPE_ETHERNET; */
/* m->hlen = DHCP_HLEN_ETHERNET; */
/* memcpy(m->chaddr, &uip_lladdr,DHCP_HLEN_ETHERNET); */
m->hops = 0;
m->secs = 0;
memcpy(m->siaddr, &uip_hostaddr, 4);
m->sname[0] = '\0';
m->file[0] = '\0';
memcpy(m->options, magic_cookie, sizeof(magic_cookie));
}
static uip_ipaddr_t any_addr;
static uip_ipaddr_t bcast_addr;
/*---------------------------------------------------------------------------*/
static void
send_offer(struct uip_udp_conn *conn, struct dhcps_client_lease *lease)
{
uint8_t *end;
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
create_msg(m);
memcpy(&m->yiaddr, &lease->ipaddr,4);
end = add_msg_type(&m->options[4], DHCPOFFER);
end = add_server_id(end);
end = add_lease_time(end);
end = add_config(end);
end = add_end(end);
uip_ipaddr_copy(&conn->ripaddr, &bcast_addr);
uip_send(uip_appdata, (int)(end - (uint8_t *)uip_appdata));
}
static void
send_ack(struct uip_udp_conn *conn, struct dhcps_client_lease *lease)
{
uint8_t *end;
uip_ipaddr_t ciaddr;
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
create_msg(m);
memcpy(&m->yiaddr, &lease->ipaddr,4);
end = add_msg_type(&m->options[4], DHCPACK);
end = add_server_id(end);
end = add_lease_time(end);
end = add_config(end);
end = add_end(end);
memcpy(&ciaddr, &lease->ipaddr,4);
uip_ipaddr_copy(&conn->ripaddr, &bcast_addr);
uip_send(uip_appdata, (int)(end - (uint8_t *)uip_appdata));
printf("ACK\n");
}
static void
send_nack(struct uip_udp_conn *conn)
{
uint8_t *end;
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
create_msg(m);
memset(&m->yiaddr, 0, 4);
end = add_msg_type(&m->options[4], DHCPNAK);
end = add_server_id(end);
end = add_end(end);
uip_ipaddr_copy(&conn->ripaddr, &bcast_addr);
uip_send(uip_appdata, (int)(end - (uint8_t *)uip_appdata));
printf("NACK\n");
}
/*---------------------------------------------------------------------------*/
PROCESS(dhcp_server_process, "DHCP server");
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(dhcp_server_process, ev , data)
{
static struct uip_udp_conn *conn;
static struct uip_udp_conn *send_conn;
static struct dhcps_client_lease *lease;
PROCESS_BEGIN();
printf("DHCP server starting\n");
uip_ipaddr(&any_addr, 0,0,0,0);
uip_ipaddr(&bcast_addr, 255,255,255,255);
conn = udp_new(&any_addr, UIP_HTONS(DHCPS_CLIENT_PORT), NULL);
if (!conn) goto exit;
send_conn = udp_new(&bcast_addr, UIP_HTONS(DHCPS_CLIENT_PORT), NULL);
if (!send_conn) goto exit;
uip_udp_bind(conn, UIP_HTONS(DHCPS_SERVER_PORT));
uip_udp_bind(send_conn, UIP_HTONS(DHCPS_SERVER_PORT));
while(1) {
PROCESS_WAIT_EVENT();
if(ev == tcpip_event) {
if (uip_newdata()) {
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
struct uip_udpip_hdr *header = (struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN];
if (m->op == DHCP_REQUEST && check_cookie() && m->hlen <= MAX_HLEN) {
uint8_t *opt = find_option(DHCP_OPTION_MSG_TYPE);
if (opt) {
uint8_t mtype = opt[2];
if (opt[2] == DHCPDISCOVER) {
printf("Discover\n");
lease = choose_address();
if (lease) {
lease->lease_end = clock_seconds()+config->default_lease_time;
tcpip_poll_udp(send_conn);
PROCESS_WAIT_EVENT_UNTIL(uip_poll());
send_offer(conn,lease);
}
} else {
uint8_t *opt = find_option(DHCP_OPTION_SERVER_ID);
if (!opt || uip_ipaddr_cmp((uip_ipaddr_t*)&opt[2], &uip_hostaddr)) {
if (mtype == DHCPREQUEST) {
printf("Request\n");
lease = allocate_address();
tcpip_poll_udp(send_conn);
PROCESS_WAIT_EVENT_UNTIL(uip_poll());
if (!lease) {
send_nack(send_conn);
} else {
send_ack(send_conn,lease);
}
} else if (mtype == DHCPRELEASE) {
printf("Release\n");
release_address();
} else if (mtype == DHCPDECLINE) {
printf("Decline\n");
} else if (mtype == DHCPINFORM) {
printf("Inform\n");
}
}
}
}
}
}
} else if (uip_poll()) {
}
}
exit:
printf("DHCP server exiting\n");
PROCESS_END();
}
void
dhcps_init(const struct dhcps_config *conf)
{
config = conf;
process_start(&dhcp_server_process,NULL);
}

View File

@ -1,47 +0,0 @@
#ifndef DHCPS_H_6M2XYUGNTK__
#define DHCPS_H_6M2XYUGNTK__
#include "contiki-net.h"
#include <stdint.h>
#define MAX_HLEN 6
struct dhcps_client_lease
{
uint8_t chaddr[MAX_HLEN];
uip_ipaddr_t ipaddr;
unsigned long lease_end;
uint8_t flags;
};
struct dhcps_config
{
unsigned long default_lease_time;
uip_ipaddr_t netmask;
uip_ipaddr_t dnsaddr;
uip_ipaddr_t default_router;
struct dhcps_client_lease *leases;
uint8_t flags;
uint8_t num_leases;
};
#define DHCP_CONF_NETMASK 0x01
#define DHCP_CONF_DNSADDR 0x02
#define DHCP_CONF_DEFAULT_ROUTER 0x04
#define DHCP_INIT_LEASE(addr0, addr1, addr2, addr3) \
{{0},{addr0, addr1, addr2, addr3},0,0}
/**
* Start the DHCP server
*
* This function starts th DHCP server with the given configuration.
* The flags field determines which options are actually sent to the
* client
*
* \param conf Pointer to a configuration struct. The configuration is
* not copied and should remain constant while the server is running.
* The leases pointed to by the configuration must be in writable memory.
**/
void dhcps_init(const struct dhcps_config *conf);
#endif /* DHCPS_H_6M2XYUGNTK__ */

View File

@ -1,6 +1,5 @@
#include "dev/uart0.h"
#if !NETSTACK_CONF_WITH_IPV4
/* In case of IPv4: putchar() is defined by the SLIP driver */
int
putchar(int c)
@ -8,4 +7,3 @@ putchar(int c)
uart0_writeb((char)c);
return c;
}
#endif /* ! NETSTACK_CONF_WITH_IPV4 */

View File

@ -1,6 +1,5 @@
#include "dev/uart1.h"
#if !NETSTACK_CONF_WITH_IPV4
/* In case of IPv4: putchar() is defined by the SLIP driver */
int
putchar(int c)
@ -8,4 +7,3 @@ putchar(int c)
uart1_writeb((char)c);
return c;
}
#endif /* ! NETSTACK_CONF_WITH_IPV4 */

View File

@ -132,9 +132,6 @@ uart0_writeb(unsigned char c)
#endif /* TX_WITH_INTERRUPT */
}
/*---------------------------------------------------------------------------*/
#if !NETSTACK_CONF_WITH_IPV4 /* If NETSTACK_CONF_WITH_IPV4 is defined, putchar() is defined by the SLIP driver */
#endif /* ! NETSTACK_CONF_WITH_IPV4 */
/*---------------------------------------------------------------------------*/
/**
* Initalize the RS232 port.
*

View File

@ -97,9 +97,6 @@ uart1_writeb(unsigned char c)
#endif /* TX_WITH_INTERRUPT */
}
/*---------------------------------------------------------------------------*/
#if ! NETSTACK_CONF_WITH_IPV4 /* If NETSTACK_CONF_WITH_IPV4 is defined, putchar() is defined by the SLIP driver */
#endif /* ! NETSTACK_CONF_WITH_IPV4 */
/*---------------------------------------------------------------------------*/
/**
* Initalize the RS232 port.
*
@ -116,7 +113,7 @@ uart1_init(unsigned long ubr)
UCA0CTL1 &= ~UCSWRST; /* Initialize USCI state machine */
transmitting = 0;
}
/*---------------------------------------------------------------------------*/
ISR(USCIAB1RX, uart1_rx_interrupt)
@ -149,7 +146,7 @@ ISR(USCIAB1TX, uart1_tx_interrupt)
UCA0TXBUF = ringbuf_get(&txbuf);
}
}
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
}
#endif /* TX_WITH_INTERRUPT */

View File

@ -41,42 +41,6 @@ slip_arch_writeb(unsigned char c)
{
uart0_writeb(c);
}
/*---------------------------------------------------------------------------*/
/*
* The serial line is used to transfer IP packets using slip. To make
* it possible to send debug output over the same line we send debug
* output as slip frames (i.e delimeted by SLIP_END).
*
*/
/*---------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV4
int
putchar(int c)
{
#define SLIP_END 0300
static char debug_frame = 0;
if (!debug_frame) { /* Start of debug output */
slip_arch_writeb(SLIP_END);
slip_arch_writeb('\r'); /* Type debug line == '\r' */
debug_frame = 1;
}
slip_arch_writeb((char)c);
/*
* Line buffered output, a newline marks the end of debug output and
* implicitly flushes debug output.
*/
if (c == '\n') {
slip_arch_writeb(SLIP_END);
debug_frame = 0;
}
return c;
}
#endif /* NETSTACK_CONF_WITH_IPV4 */
/*---------------------------------------------------------------------------*/
/**
* Initalize the RS232 port and the SLIP driver.
*

View File

@ -42,41 +42,6 @@ slip_arch_writeb(unsigned char c)
uart1_writeb(c);
}
/*---------------------------------------------------------------------------*/
/*
* The serial line is used to transfer IP packets using slip. To make
* it possible to send debug output over the same line we send debug
* output as slip frames (i.e delimeted by SLIP_END).
*
*/
/*---------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV4
int
putchar(int c)
{
#define SLIP_END 0300
static char debug_frame = 0;
if (!debug_frame) { /* Start of debug output */
slip_arch_writeb(SLIP_END);
slip_arch_writeb('\r'); /* Type debug line == '\r' */
debug_frame = 1;
}
slip_arch_writeb((char)c);
/*
* Line buffered output, a newline marks the end of debug output and
* implicitly flushes debug output.
*/
if (c == '\n') {
slip_arch_writeb(SLIP_END);
debug_frame = 0;
}
return c;
}
#endif /* NETSTACK_CONF_WITH_IPV4 */
/*---------------------------------------------------------------------------*/
/**
* Initalize the RS232 port and the SLIP driver.
*

View File

@ -53,7 +53,7 @@ uint8_t
tapdev_output(void)
{
uip_arp_out();
tapdev_send();
tapdev_send();
return 0;
}
#endif
@ -81,7 +81,7 @@ pollhandler(void)
if(uip_len > 0) {
tapdev_send();
}
#endif
#endif
} else {
uip_clear_buf();
}

View File

@ -31,7 +31,6 @@
*/
#include "contiki-net.h"
#include "net/ipv4/uip-neighbor.h"
#include "net/wpcap.h"
#include "net/wpcap-drv.h"
@ -69,7 +68,7 @@ uint8_t
wpcap_output(void)
{
uip_arp_out();
wpcap_send();
wpcap_send();
return 0;
}
@ -121,7 +120,7 @@ pollhandler(void)
// memcpy(uip_buf, uip_buf+14, uip_len);
memcpy(&uip_buf[UIP_LLH_LEN], uip_buf+14, uip_len); //LLH_LEN is zero for native border router to slip radio
// CopyMemory(uip_buf, uip_buf+14, uip_len);
//{int i;printf("\n0000 ");for (i=0;i<uip_len;i++) printf("%02x ",*(char*)(uip_buf+i));printf("\n");}
//{int i;printf("\n0000 ");for (i=0;i<uip_len;i++) printf("%02x ",*(char*)(uip_buf+i));printf("\n");}
tcpip_input();
} else
goto bail;

View File

@ -385,7 +385,6 @@ typedef uint32_t rtimer_clock_t;
#endif
#define UIP_CONF_ND6_SEND_RA 0
#define UIP_CONF_IP_FORWARD 0
#define RPL_CONF_STATS 0
#define UIP_CONF_ND6_REACHABLE_TIME 600000
@ -427,20 +426,6 @@ typedef uint32_t rtimer_clock_t;
}
#endif
#ifndef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 8
#endif
/*---------------------------------------------------------------------------*/
#else /* NETSTACK_CONF_WITH_IPV6 */
/* Network setup for non-IPv6 (rime). */
#define UIP_CONF_IP_FORWARD 1
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_CONF_BUFFER_SIZE 108
#endif
#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0
#ifndef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 8
#endif

View File

@ -79,11 +79,6 @@ MODULES += core/net core/net/mac core/net/mac/framer core/net/ip64-addr \
## Copied from Makefile.include, since Cooja overrides CFLAGS et al
HAS_STACK = 0
ifeq ($(CONTIKI_WITH_IPV4),1)
HAS_STACK = 1
CFLAGS += -DNETSTACK_CONF_WITH_IPV4=1
endif
ifeq ($(CONTIKI_WITH_RIME),1)
HAS_STACK = 1
CFLAGS += -DNETSTACK_CONF_WITH_RIME=1

View File

@ -49,12 +49,6 @@
#define w_memcpy memcpy
#if NETSTACK_CONF_WITH_IPV4
#if NETSTACK_CONF_WITH_IPV6
#error NETSTACK_CONF_WITH_IPV4 && NETSTACK_CONF_WITH_IPV6: Bad configuration
#endif /* NETSTACK_CONF_WITH_IPV6 */
#endif /* NETSTACK_CONF_WITH_IPV4 */
#ifdef NETSTACK_CONF_H
/* These header overrides the below default configuration */
@ -75,16 +69,6 @@
/* Radio setup */
#define NETSTACK_CONF_RADIO cooja_radio_driver
#else /* NETSTACK_CONF_WITH_IPV6 */
#if NETSTACK_CONF_WITH_IPV4
/* Network setup for IPv4 */
#define NETSTACK_CONF_NETWORK uip_driver
#define NETSTACK_CONF_RADIO cooja_radio_driver
#define UIP_CONF_IP_FORWARD 1
#endif /* NETSTACK_CONF_WITH_IPV4 */
#endif /* NETSTACK_CONF_WITH_IPV6 */
#endif /* NETSTACK_CONF_H */
@ -138,8 +122,7 @@
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
#define UIP_CONF_IPV6_CHECKS 1
#define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_IP_FORWARD 0
#define UIP_CONF_NETIF_MAX_ADDRESSES
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06
#ifndef SICSLOWPAN_CONF_FRAG
@ -203,8 +186,6 @@ typedef uint64_t rtimer_clock_t;
#define UIP_CONF_PINGADDRCONF 0
#define UIP_CONF_LOGGING 0
#define UIP_CONF_TCP_SPLIT 0
#if NETSTACK_CONF_WITH_IPV6
#endif /* NETSTACK_CONF_WITH_IPV6 */

View File

@ -76,25 +76,6 @@
#define Java_org_contikios_cooja_corecomm_CLASSNAME_tick COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_tick)
#define Java_org_contikios_cooja_corecomm_CLASSNAME_setReferenceAddress COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setReferenceAddress)
#ifndef NETSTACK_CONF_WITH_IPV4
#define NETSTACK_CONF_WITH_IPV4 0
#endif
#if NETSTACK_CONF_WITH_IPV4
#include "dev/rs232.h"
#include "dev/slip.h"
#include "net/ip/uip.h"
#include "net/ipv4/uip-fw.h"
#include "net/uip-fw-drv.h"
#include "net/ipv4/uip-over-mesh.h"
static struct uip_fw_netif slipif =
{UIP_FW_NETIF(0,0,0,0, 255,255,255,255, slip_send)};
static struct uip_fw_netif meshif =
{UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
#define UIP_OVER_MESH_CHANNEL 8
static uint8_t is_gateway;
#endif /* NETSTACK_CONF_WITH_IPV4 */
#ifndef NETSTACK_CONF_WITH_IPV6
#define NETSTACK_CONF_WITH_IPV6 0
#endif
@ -137,22 +118,6 @@ long referenceVar;
static struct cooja_mt_thread rtimer_thread;
static struct cooja_mt_thread process_run_thread;
/*---------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV4
static void
set_gateway(void)
{
if(!is_gateway) {
printf("%d.%d: making myself the IP network gateway.\n\n",
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
uip_ipaddr_to_quad(&uip_hostaddr));
uip_over_mesh_set_gateway(&linkaddr_node_addr);
uip_over_mesh_make_announced_gateway();
is_gateway = 1;
}
}
#endif /* NETSTACK_CONF_WITH_IPV4 */
/*---------------------------------------------------------------------------*/
static void
print_processes(struct process * const processes[])
@ -243,35 +208,6 @@ contiki_init()
printf("%s/%s\n",
NETSTACK_NETWORK.name, NETSTACK_MAC.name);
#if NETSTACK_CONF_WITH_IPV4
/* IPv4 CONFIGURATION */
{
uip_ipaddr_t hostaddr, netmask;
process_start(&tcpip_process, NULL);
process_start(&uip_fw_process, NULL);
process_start(&slip_process, NULL);
slip_set_input_callback(set_gateway);
uip_init();
uip_fw_init();
uip_ipaddr(&hostaddr, 172,16,linkaddr_node_addr.u8[0],linkaddr_node_addr.u8[1]);
uip_ipaddr(&netmask, 255,255,0,0);
uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
uip_sethostaddr(&hostaddr);
uip_setnetmask(&netmask);
uip_over_mesh_set_net(&hostaddr, &netmask);
uip_over_mesh_set_gateway_netif(&slipif);
uip_fw_default(&meshif);
uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
rs232_set_input(slip_input_byte);
printf("IPv4 address: %d.%d.%d.%d\n", uip_ipaddr_to_quad(&hostaddr));
}
#endif /* NETSTACK_CONF_WITH_IPV4 */
#if NETSTACK_CONF_WITH_IPV6
/* IPv6 CONFIGURATION */
{

View File

@ -44,13 +44,6 @@ char simIP[16];
#endif /* NETSTACK_CONF_WITH_IPV6 */
#if NETSTACK_CONF_WITH_IPV4
char simIPChanged;
char simIP[4];
#endif /* NETSTACK_CONF_WITH_IPV4 */
/*-----------------------------------------------------------------------------------*/
static void
doInterfaceActionsBeforeTick(void)
@ -60,20 +53,6 @@ doInterfaceActionsBeforeTick(void)
/* check if IPv6 address should change */
#endif /* NETSTACK_CONF_WITH_IPV6 */
#if NETSTACK_CONF_WITH_IPV4
/* check if IPv4 address should change */
/*
if (simIPChanged) {
uip_ipaddr_t hostaddr;
uip_ipaddr(&hostaddr, simIP[0], simIP[1], simIP[2], simIP[3]);
uip_sethostaddr(&hostaddr);
simIPChanged = 0;
}
*/
#endif /* NETSTACK_CONF_WITH_IPV4 */
}
/*-----------------------------------------------------------------------------------*/
static void

View File

@ -1,418 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#include "radio-uip-uaodv.h"
#include "net/ip/uip.h"
#include "net/uaodv.h"
#include "net/ipv4/uaodv-rt.h"
#include "net/ipv4/uaodv-def.h"
#include "lib/crc16.h"
#include "list.h"
#include <string.h>
#include <stdio.h>
/* Packet buffer size and retransmission settings */
#define MAX_BUFFERED_PACKETS 10
#define MAX_RETRANSMISSIONS_RREP 16
#define MAX_RETRANSMISSIONS_UNICAST 16
/* Forward packet (header) */
#define FWD_ID "fWd:"
#define FWD_ID_LENGTH 4
#define FWD_NEXT_IP FWD_ID_LENGTH
#define FWD_PACKET_LENGTH (FWD_NEXT_IP + 4)
/* Acknowledgement packet */
#define ACK_ID "aCk"
#define ACK_ID_LENGTH 3
#define ACK_CRC ACK_ID_LENGTH
#define ACK_PACKET_LENGTH (ACK_ID_LENGTH + 2)
#define ACK_TIMEOUT (CLOCK_SECOND / 50) * (random_rand() % 100)
enum {
EVENT_SEND_ACK
};
struct buf_packet {
struct buf_packet *next;
uint8_t data[UIP_BUFSIZE];
int len;
uint8_t resends;
uint8_t acked;
uint8_t want_ack;
uint16_t crc;
uip_ipaddr_t finaldest;
struct etimer etimer;
};
LIST(buf_packet_list);
MEMB(buf_packet_mem, struct buf_packet, MAX_BUFFERED_PACKETS);
PROCESS(radio_uip_process, "radio uIP uAODV process");
static const struct radio_driver *radio;
/*---------------------------------------------------------------------------*/
static void receiver(const struct radio_driver *d);
uint8_t radio_uip_uaodv_send(void);
void radio_uip_uaodv_init(const struct radio_driver *d);
int radio_uip_handle_ack(uint8_t *buf, int len);
uint16_t radio_uip_calc_crc(uint8_t *buf, int len);
int radio_uip_buffer_outgoing_packet(uint8_t *buf, int len, uip_ipaddr_t *dest, int max_sends);
int radio_uip_is_ack(uint8_t *buf, int len);
int radio_uip_uaodv_add_header(uint8_t *buf, int len, uip_ipaddr_t *addr);
int radio_uip_uaodv_remove_header(uint8_t *buf, int len);
void radio_uip_uaodv_change_header(uint8_t *buf, int len, uip_ipaddr_t *addr);
int radio_uip_uaodv_header_exists(uint8_t *buf, int len);
int radio_uip_uaodv_is_broadcast(uip_ipaddr_t *addr);
int radio_uip_uaodv_fwd_is_broadcast(uint8_t *buf, int len);
int radio_uip_uaodv_fwd_is_me(uint8_t *buf, int len);
int radio_uip_uaodv_dest_is_me(uint8_t *buf, int len);
int radio_uip_uaodv_dest_port(uint8_t *buf, int len);
/*---------------------------------------------------------------------------*/
/* Main process - handles (re)transmissions and acks */
PROCESS_THREAD(radio_uip_process, ev, data)
{
struct buf_packet *packet;
PROCESS_BEGIN();
while(1) {
PROCESS_YIELD();
if(ev == EVENT_SEND_ACK) {
/* Prepare and send ack for given 16-bit CRC */
uint8_t ackPacket[ACK_PACKET_LENGTH];
memcpy(ackPacket, ACK_ID, ACK_ID_LENGTH);
ackPacket[ACK_CRC] = ((uint16_t) data >> 8);
ackPacket[ACK_CRC+1] = ((uint16_t) data & 0xff);
radio->send(ackPacket, ACK_PACKET_LENGTH);
} else if(ev == PROCESS_EVENT_TIMER) {
/* Locate which packet acknowledgement timed out */
for(packet = list_head(buf_packet_list);
packet != NULL;
packet = packet->next) {
if (etimer_expired(&packet->etimer)) {
if (packet->acked) {
/* Already acked packet, remove silently */
list_remove(buf_packet_list, packet);
memb_free(&buf_packet_mem, packet);
} else if (packet->resends > 0) {
/* Resend packet */
packet->resends--;
etimer_set(&packet->etimer, ACK_TIMEOUT);
radio->send(packet->data, packet->len);
} else {
/* Packet was resent maximum number of times */
/* If an ack was expected, flag destination to bad */
if (packet->want_ack && !uip_ipaddr_cmp(&packet->finaldest, &uip_broadcast_addr)) {
uaodv_bad_dest(&packet->finaldest);
}
list_remove(buf_packet_list, packet);
memb_free(&buf_packet_mem, packet);
}
}
}
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
static void
receiver(const struct radio_driver *d)
{
uip_len = d->read(&uip_buf[UIP_LLH_LEN], UIP_BUFSIZE - UIP_LLH_LEN);
if (uip_len <= 0) {
return;
}
/* Detect and handle acknowledgements */
if (radio_uip_is_ack(&uip_buf[UIP_LLH_LEN], uip_len)) {
radio_uip_handle_ack(&uip_buf[UIP_LLH_LEN], uip_len);
return;
}
/* If no uAODV header, receive as usual */
if (!radio_uip_uaodv_header_exists(&uip_buf[UIP_LLH_LEN], uip_len)) {
tcpip_input();
return;
}
/* Drop packet unless we are the uAODV forwarder */
if (!radio_uip_uaodv_fwd_is_me(&uip_buf[UIP_LLH_LEN], uip_len)) {
return;
}
{
/* Send ack as soon as possible */
uint16_t crc;
crc = radio_uip_calc_crc(&uip_buf[UIP_LLH_LEN], uip_len);
process_post(&radio_uip_process, EVENT_SEND_ACK, (void*) (uint32_t) crc);
}
/* Strip header and receive packet */
uip_len = radio_uip_uaodv_remove_header(&uip_buf[UIP_LLH_LEN], uip_len);
tcpip_input();
}
/*---------------------------------------------------------------------------*/
uint8_t
radio_uip_uaodv_send(void)
{
struct uaodv_rt_entry *route;
/* Transmit broadcast packets without header */
if (radio_uip_uaodv_is_broadcast(&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr)) {
return radio_uip_buffer_outgoing_packet(&uip_buf[UIP_LLH_LEN], uip_len, (void*) &uip_broadcast_addr, 1);
}
/* Transmit uAODV packets with headers but without using route table */
if (((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->proto == UIP_PROTO_UDP
&& radio_uip_uaodv_dest_port(&uip_buf[UIP_LLH_LEN], uip_len) == UIP_HTONS(UAODV_UDPPORT)) {
uip_ipaddr_t nexthop;
memcpy(&nexthop, &((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr, 4);
uip_len = radio_uip_uaodv_add_header(
&uip_buf[UIP_LLH_LEN],
uip_len,
&nexthop
);
/* Buffer packet for persistent transmission */
return radio_uip_buffer_outgoing_packet(
&uip_buf[UIP_LLH_LEN],
uip_len,
&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN + FWD_PACKET_LENGTH])->destipaddr,
MAX_RETRANSMISSIONS_RREP);
}
/* Fetch already prepared uAODV route */
route = uaodv_rt_lookup_any((&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr));
if (route == NULL || route->is_bad) {
/* If we are forwarding, notify origin of this bad route */
if (tcpip_is_forwarding) {
uaodv_bad_dest((&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->destipaddr));
}
return UIP_FW_DROPPED;
}
/* Add header and buffer packet for persistent transmission */
uip_len = radio_uip_uaodv_add_header(&uip_buf[UIP_LLH_LEN], uip_len, uip_ds6_route_nexthop(route)); /* TODO Correct? */
return radio_uip_buffer_outgoing_packet(
&uip_buf[UIP_LLH_LEN],
uip_len,
&route->dest,
MAX_RETRANSMISSIONS_UNICAST);
}
/*---------------------------------------------------------------------------*/
void
radio_uip_uaodv_init(const struct radio_driver *d)
{
/* Prepare buffers and start main process */
memb_init(&buf_packet_mem);
list_init(buf_packet_list);
process_start(&radio_uip_process, NULL);
radio = d;
radio->set_receive_function(receiver);
radio->on();
}
/*---------------------------------------------------------------------------*/
uint16_t
radio_uip_calc_crc(uint8_t *buf, int len)
{
uint16_t crcacc = 0xffff;
int counter;
/* TODO Not effective */
for (counter = 0; counter < len; counter++) {
crcacc = crc16_add(buf[counter], crcacc);
}
return crcacc;
}
/*---------------------------------------------------------------------------*/
int
radio_uip_buffer_outgoing_packet(uint8_t *buf, int len, uip_ipaddr_t *dest, int max_sends)
{
struct buf_packet *packet;
uint16_t crc;
/* Calculate packet's unique CRC */
crc = radio_uip_calc_crc(&uip_buf[UIP_LLH_LEN], uip_len);
/* Check if this packet is already being transmitted */
for(packet = list_head(buf_packet_list);
packet != NULL;
packet = packet->next) {
if (packet->crc == crc) {
return UIP_FW_DROPPED;
}
}
/* Allocate storage memory */
packet = (struct buf_packet *)memb_alloc(&buf_packet_mem);
if (packet == NULL) {
return UIP_FW_DROPPED;
}
/* Prepare packet buffer */
memcpy(packet->data, buf, len);
packet->len = len;
packet->resends = max_sends;
packet->acked = 0;
if (packet->resends > 1)
packet->want_ack = 1;
else
packet->want_ack = 0;
memcpy(&packet->finaldest, dest, 4);
packet->crc = crc;
/* Set first transmission to as soon as possible */
PROCESS_CONTEXT_BEGIN(&radio_uip_process);
etimer_set(&packet->etimer, 0);
PROCESS_CONTEXT_END(&radio_uip_process);
/* Add to buffered packets list */
list_add(buf_packet_list, packet);
return UIP_FW_OK;
}
/*---------------------------------------------------------------------------*/
int
radio_uip_is_ack(uint8_t *buf, int len)
{
if (len != ACK_PACKET_LENGTH)
return 0;
return memcmp(buf, ACK_ID, ACK_ID_LENGTH) == 0;
}
/*---------------------------------------------------------------------------*/
int
radio_uip_handle_ack(uint8_t *buf, int len)
{
struct buf_packet *packet;
uint16_t ackCRC;
ackCRC = (uint16_t) (buf[ACK_CRC] << 8) + (uint16_t) (0xff&buf[ACK_CRC+1]);
/* Locate which packet was acknowledged */
for(packet = list_head(buf_packet_list);
packet != NULL;
packet = packet->next) {
if (packet->crc == ackCRC) {
/* Signal packet has been acknowledged */
packet->acked = 1;
return 0;
}
}
return 1;
}
/*---------------------------------------------------------------------------*/
int
radio_uip_uaodv_add_header(uint8_t *buf, int len, uip_ipaddr_t *addr)
{
uint8_t tempbuf[len];
memcpy(tempbuf, buf, len);
memcpy(&buf[FWD_PACKET_LENGTH], tempbuf, len);
memcpy(buf, FWD_ID, FWD_ID_LENGTH);
memcpy(&buf[FWD_NEXT_IP], (char*)addr, 4);
return FWD_PACKET_LENGTH + len;
}
/*---------------------------------------------------------------------------*/
int
radio_uip_uaodv_remove_header(uint8_t *buf, int len)
{
uint8_t tempbuf[len];
memcpy(tempbuf, &buf[FWD_PACKET_LENGTH], len);
memcpy(buf, tempbuf, len);
return len - FWD_PACKET_LENGTH;
}
/*---------------------------------------------------------------------------*/
void
radio_uip_uaodv_change_header(uint8_t *buf, int len, uip_ipaddr_t *addr)
{
memcpy(&buf[FWD_NEXT_IP], addr, 4);
}
/*---------------------------------------------------------------------------*/
int
radio_uip_uaodv_header_exists(uint8_t *buf, int len)
{
return !memcmp(buf, FWD_ID, FWD_ID_LENGTH);
}
/*---------------------------------------------------------------------------*/
int
radio_uip_uaodv_is_broadcast(uip_ipaddr_t *addr)
{
return uip_ipaddr_cmp(addr, &uip_broadcast_addr);
}
/*---------------------------------------------------------------------------*/
int
radio_uip_uaodv_fwd_is_broadcast(uint8_t *buf, int len)
{
return radio_uip_uaodv_is_broadcast((uip_ipaddr_t*) &buf[FWD_NEXT_IP]);
}
/*---------------------------------------------------------------------------*/
int
radio_uip_uaodv_fwd_is_me(uint8_t *buf, int len)
{
return !memcmp(&buf[FWD_NEXT_IP], &uip_hostaddr, 4);
}
/*---------------------------------------------------------------------------*/
int
radio_uip_uaodv_dest_is_me(uint8_t *buf, int len)
{
return !memcmp((&((struct uip_udpip_hdr *)buf)->destipaddr), &uip_hostaddr, 4);
}
/*---------------------------------------------------------------------------*/
int
radio_uip_uaodv_dest_port(uint8_t *buf, int len)
{
if (len < sizeof(struct uip_udpip_hdr))
return -1;
return (int) ((struct uip_udpip_hdr *)buf)->destport;
}
/*---------------------------------------------------------------------------*/

View File

@ -1,45 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#ifndef RADIO_UIP_UAODV_H_
#define RADIO_UIP_UAODV_H_
#include "contiki.h"
#include "dev/radio.h"
void
radio_uip_uaodv_init(const struct radio_driver *d);
uint8_t
radio_uip_uaodv_send(void);
#endif /* RADIO_UIP_UAODV_H_ */

View File

@ -36,14 +36,6 @@
#define IMPLEMENT_PRINTF 1
#if NETSTACK_CONF_WITH_IPV4
/* uIP packets via SLIP */
#include "uip.h"
#define MAX_LOG_LENGTH (2*UIP_BUFSIZE)
#else /* NETSTACK_CONF_WITH_IPV4 */
#define MAX_LOG_LENGTH 1024
#endif /* NETSTACK_CONF_WITH_IPV4 */
#if MAX_LOG_LENGTH < 1024
#undef MAX_LOG_LENGTH
#define MAX_LOG_LENGTH 1024

View File

@ -1,96 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <stdlib.h>
#include "net/ip/uip.h"
#include "dev/button-sensor.h"
#include "dev/leds.h"
#include "net/uaodv.h"
#include "net/ipv4/uaodv-rt.h"
#include <stdio.h>
#define COOJA_PORT 1234
PROCESS(test_uaodv_process, "uIP uAODV test process");
AUTOSTART_PROCESSES(&uaodv_process, &test_uaodv_process);
static struct uip_udp_conn *out_conn;
static struct uip_udp_conn *in_conn;
/*---------------------------------------------------------------------*/
PROCESS_THREAD(test_uaodv_process, ev, data)
{
static uip_ipaddr_t addr;
PROCESS_BEGIN();
printf("uIP uAODV test process started\n");
uip_ipaddr(&addr, 0,0,0,0);
in_conn = udp_new(&addr, UIP_HTONS(0), NULL);
uip_udp_bind(in_conn, UIP_HTONS(COOJA_PORT));
uip_ipaddr(&addr, 10,10,10,4);
out_conn = udp_new(&addr, UIP_HTONS(COOJA_PORT), NULL);
button_sensor.configure(SENSORS_ACTIVE, 1);
while(1) {
PROCESS_WAIT_EVENT();
if(ev == sensors_event && data == &button_sensor) {
struct uaodv_rt_entry *route;
uip_ipaddr(&addr, 10,10,10,4);
route = uaodv_rt_lookup_any(&addr);
if (route == NULL || route->is_bad) {
printf("%d.%d.%d.%d: lookup %d.%d.%d.%d\n", uip_ipaddr_to_quad(&uip_hostaddr), uip_ipaddr_to_quad(&addr));
uaodv_request_route_to(&addr);
} else {
printf("%d.%d.%d.%d: send to %d.%d.%d.%d\n", uip_ipaddr_to_quad(&uip_hostaddr), uip_ipaddr_to_quad(&addr));
tcpip_poll_udp(out_conn);
PROCESS_WAIT_UNTIL(ev == tcpip_event && uip_poll());
uip_send("cooyah COOJA", 12);
}
}
if(ev == tcpip_event && uip_newdata()) {
((char*) uip_appdata)[uip_datalen()] = 0;
printf("data received from %d.%d.%d.%d: %s\n",
uip_ipaddr_to_quad(&((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])->srcipaddr),
(char *)uip_appdata);
leds_toggle(LEDS_ALL);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------*/

View File

@ -1,112 +0,0 @@
/*
* Copyright (C) 2015, Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include "contiki-net.h"
#include "net/ipv4/uip-neighbor.h"
#include "net/eth-proc.h"
#include "eth.h"
#define BUF ((struct uip_eth_hdr *)&uip_buf[0])
#define IPBUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
PROCESS(eth_process, "Ethernet");
/*---------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV6
static uint8_t
output(const uip_lladdr_t *dest_mac)
{
if (dest_mac == NULL) {
/* broadcast packet */
memset(&BUF->dest, 0xFF, UIP_LLH_LEN);
} else {
memcpy(&BUF->dest, dest_mac, UIP_LLH_LEN);
}
memcpy(&BUF->src, uip_lladdr.addr, UIP_LLH_LEN);
quarkX1000_eth_send();
return 0;
}
#else
static uint8_t
output(void)
{
uip_arp_out();
quarkX1000_eth_send();
return 0;
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
/*---------------------------------------------------------------------------*/
static void
pollhandler(void)
{
process_poll(&eth_process);
quarkX1000_eth_poll(&uip_len);
if(uip_len > 0) {
#if NETSTACK_CONF_WITH_IPV6
if(BUF->type == uip_htons(UIP_ETHTYPE_IPV6)) {
tcpip_input();
}
#else
if(BUF->type == uip_htons(UIP_ETHTYPE_IP)) {
uip_len -= sizeof(struct uip_eth_hdr);
tcpip_input();
} else if(BUF->type == uip_htons(UIP_ETHTYPE_ARP)) {
uip_arp_arpin();
/* If the above function invocation resulted in data that
should be sent out on the network, the global variable
uip_len is set to a value > 0. */
if(uip_len > 0) {
quarkX1000_eth_send();
}
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(eth_process, ev, data)
{
PROCESS_POLLHANDLER(pollhandler());
PROCESS_BEGIN();
tcpip_set_outputfunc(output);
process_poll(&eth_process);
PROCESS_WAIT_UNTIL(ev == PROCESS_EVENT_EXIT);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View File

@ -1,38 +0,0 @@
/*
* Copyright (C) 2015, Intel Corporation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef PLATFORM_GALILEO_NET_ETH_PROC_H_
#define PLATFORM_GALILEO_NET_ETH_PROC_H_
#include "contiki.h"
PROCESS_NAME(eth_process);
#endif /* PLATFORM_GALILEO_NET_ETH_PROC_H_ */

View File

@ -62,12 +62,12 @@
#define PROCESS_CONF_NUMEVENTS 8
#define PROCESS_CONF_STATS 1
#if !defined NETSTACK_CONF_WITH_IPV6 && !defined NETSTACK_CONF_WITH_IPV4
#if !defined NETSTACK_CONF_WITH_IPV6
#define NETSTACK_CONF_WITH_IPV6 1
#endif /* NETSTACK_CONF_ not defined */
/* Network setup for IP */
#if NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6
#if NETSTACK_CONF_WITH_IPV6
#define LINKADDR_CONF_SIZE 8
@ -88,7 +88,7 @@
#define QUEUEBUF_CONF_NUM 16
#endif /* QUEUEBUF_CONF_NUM */
#endif /* NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6 */
#endif /* NETSTACK_CONF_WITH_IPV6 */
/* Network setup for IPv6 */
#if NETSTACK_CONF_WITH_IPV6
@ -130,7 +130,6 @@
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_ND6_MAX_PREFIXES 3
#define UIP_CONF_ND6_MAX_DEFROUTERS 2
#define UIP_CONF_IP_FORWARD 0
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_CONF_BUFFER_SIZE 1280
#endif
@ -166,8 +165,6 @@
#define UIP_CONF_LOGGING 0
#define LOG_CONF_ENABLED 0
#define UIP_CONF_TCP_SPLIT 0
#define UIP_CONF_BYTE_ORDER UIP_BIG_ENDIAN
#define UIP_CONF_LOGGING 0

View File

@ -92,24 +92,6 @@ unsigned char node_mac[8];
* marks the end of the stack taking into account the used heap */
extern uint32_t heap_location;
#ifndef NETSTACK_CONF_WITH_IPV4
#define NETSTACK_CONF_WITH_IPV4 0
#endif
#if NETSTACK_CONF_WITH_IPV4
#include "net/ip/uip.h"
#include "net/ipv4/uip-fw.h"
#include "net/ipv4/uip-fw-drv.h"
#include "net/ipv4/uip-over-mesh.h"
static struct uip_fw_netif slipif =
{ UIP_FW_NETIF(192, 168, 1, 2, 255, 255, 255, 255, slip_send) };
static struct uip_fw_netif meshif =
{ UIP_FW_NETIF(172, 16, 0, 0, 255, 255, 0, 0, uip_over_mesh_send) };
#define UIP_OVER_MESH_CHANNEL 8
static uint8_t is_gateway;
#endif /* NETSTACK_CONF_WITH_IPV4 */
#ifdef EXPERIMENT_SETUP
#include "experiment-setup.h"
#endif
@ -165,23 +147,6 @@ print_processes(struct process *const processes[])
}
#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */
/*---------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV4
static void
set_gateway(void)
{
if(!is_gateway) {
leds_on(LEDS_RED);
printf("%d.%d: making myself the IP network gateway.\n\n",
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
uip_ipaddr_to_quad(&uip_hostaddr));
uip_over_mesh_set_gateway(&linkaddr_node_addr);
uip_over_mesh_make_announced_gateway();
is_gateway = 1;
}
}
#endif /* NETSTACK_CONF_WITH_IPV4 */
/*---------------------------------------------------------------------------*/
static void
start_autostart_processes()
{
@ -332,10 +297,6 @@ main(void)
ctimer_init();
uart0_init(UART_BAUD_RATE); /* Must come before first PRINTF */
#if NETSTACK_CONF_WITH_IPV4
slip_arch_init(UART_BAUD_RATE);
#endif /* NETSTACK_CONF_WITH_IPV4 */
/* check for reset source */
if(bAHI_WatchdogResetEvent()) {
PRINTF("Init: Watchdog timer has reset device!\r\n");
@ -350,9 +311,6 @@ main(void)
#else
PRINTF(CONTIKI_VERSION_STRING " started with IPV6\n");
#endif
#elif NETSTACK_CONF_WITH_IPV4
PRINTF(CONTIKI_VERSION_STRING " started with IPV4\n");
#else
PRINTF(CONTIKI_VERSION_STRING " started\n");
#endif
@ -378,35 +336,6 @@ main(void)
timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16);
#endif /* TIMESYNCH_CONF_ENABLED */
#if NETSTACK_CONF_WITH_IPV4
process_start(&tcpip_process, NULL);
process_start(&uip_fw_process, NULL); /* Start IP output */
process_start(&slip_process, NULL);
slip_set_input_callback(set_gateway);
{
uip_ipaddr_t hostaddr, netmask;
uip_init();
uip_ipaddr(&hostaddr, 172, 16,
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
uip_ipaddr(&netmask, 255, 255, 0, 0);
uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
uip_sethostaddr(&hostaddr);
uip_setnetmask(&netmask);
uip_over_mesh_set_net(&hostaddr, &netmask);
/* uip_fw_register(&slipif);*/
uip_over_mesh_set_gateway_netif(&slipif);
uip_fw_default(&meshif);
uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
PRINTF("uIP started with IP address %d.%d.%d.%d\n",
uip_ipaddr_to_quad(&hostaddr));
}
#endif /* NETSTACK_CONF_WITH_IPV4 */
watchdog_start();
#if NETSTACK_CONF_WITH_IPV6

View File

@ -46,7 +46,6 @@
#include <MicroInt.h>
#include "net/ip/uip.h"
#include "net/ipv4/uip-fw.h"
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#include "dev/slip.h"

View File

@ -70,7 +70,6 @@ typedef unsigned short uip_stats_t;
#define UIP_CONF_BUFFER_SIZE 420
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
#define UIP_CONF_TCP 1
#define UIP_CONF_TCP_SPLIT 0
#define UIP_CONF_LOGGING 0
#define UIP_CONF_UDP_CHECKSUMS 1
@ -117,7 +116,6 @@ typedef unsigned short uip_stats_t;
#define UIP_CONF_ND6_REACHABLE_TIME 600000
#define UIP_CONF_ND6_RETRANS_TIMER 10000
#define UIP_CONF_IP_FORWARD 0
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_CONF_BUFFER_SIZE 240
#endif

View File

@ -230,9 +230,7 @@ main(int argc, char **argv)
printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
}
#elif NETSTACK_CONF_WITH_IPV4
process_start(&tcpip_process, NULL);
#endif
#endif /* NETSTACK_CONF_WITH_IPV6 */
serial_line_init();

View File

@ -110,7 +110,6 @@
/* ND and Routing */
#define UIP_CONF_ROUTER 0 /**< BLE master role, which allows for routing, isn't supported. */
#define UIP_CONF_ND6_SEND_NS 1
#define UIP_CONF_IP_FORWARD 0 /**< No packet forwarding. */
#define UIP_CONF_ND6_REACHABLE_TIME 600000
#define UIP_CONF_ND6_RETRANS_TIMER 10000

View File

@ -442,7 +442,6 @@ typedef uint32_t rtimer_clock_t;
#endif
#define UIP_CONF_ND6_SEND_RA 0
#define UIP_CONF_IP_FORWARD 0
#define RPL_CONF_STATS 0
#define UIP_CONF_ND6_REACHABLE_TIME 600000
@ -484,20 +483,6 @@ typedef uint32_t rtimer_clock_t;
}
#endif
#ifndef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 8
#endif
/*---------------------------------------------------------------------------*/
#else /* NETSTACK_CONF_WITH_IPV6 */
/* Network setup for non-IPv6 (rime). */
#define UIP_CONF_IP_FORWARD 1
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_CONF_BUFFER_SIZE 108
#endif
#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0
#ifndef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 8
#endif

View File

@ -96,7 +96,6 @@
#define UIP_CONF_IPV6_CHECKS 1
#define UIP_CONF_IPV6_REASSEMBLY 0
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
#define UIP_CONF_IP_FORWARD 0
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_CONF_BUFFER_SIZE 240
#endif
@ -107,9 +106,7 @@
#define SICSLOWPAN_CONF_MAXAGE 8
#endif /* SICSLOWPAN_CONF_FRAG */
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2
#else /* NETSTACK_CONF_WITH_IPV6 */
#define UIP_CONF_IP_FORWARD 1
#define UIP_CONF_BUFFER_SIZE 108
#endif /* NETSTACK_CONF_WITH_IPV6 */
#define UIP_CONF_ICMP_DEST_UNREACH 1
@ -133,8 +130,6 @@
#define UIP_CONF_PINGADDRCONF 0
#define UIP_CONF_LOGGING 0
#define UIP_CONF_TCP_SPLIT 0
#ifndef AES_128_CONF
#define AES_128_CONF cc2420_aes_128_driver
#endif /* AES_128_CONF */

View File

@ -71,26 +71,7 @@ static struct timer mgt_timer;
#endif
extern int msp430_dco_required;
#ifndef NETSTACK_CONF_WITH_IPV4
#define NETSTACK_CONF_WITH_IPV4 0
#endif
#if NETSTACK_CONF_WITH_IPV4
#include "net/ip/uip.h"
#include "net/ipv4/uip-fw.h"
#include "net/ipv4/uip-fw-drv.h"
#include "net/ipv4/uip-over-mesh.h"
static struct uip_fw_netif slipif =
{UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)};
static struct uip_fw_netif meshif =
{UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)};
#endif /* NETSTACK_CONF_WITH_IPV4 */
#define UIP_OVER_MESH_CHANNEL 8
#if NETSTACK_CONF_WITH_IPV4
static uint8_t is_gateway;
#endif /* NETSTACK_CONF_WITH_IPV4 */
#ifdef EXPERIMENT_SETUP
#include "experiment-setup.h"
@ -170,23 +151,6 @@ print_processes(struct process * const processes[])
putchar('\n');
}
#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */
/*--------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV4
static void
set_gateway(void)
{
if(!is_gateway) {
leds_on(LEDS_RED);
PRINTF("%d.%d: making myself the IP network gateway.\n\n",
linkaddr_node_addr.u8[0], linkaddr_node_addr.u8[1]);
PRINTF("IPv4 address of the gateway: %d.%d.%d.%d\n\n",
uip_ipaddr_to_quad(&uip_hostaddr));
uip_over_mesh_set_gateway(&linkaddr_node_addr);
uip_over_mesh_make_announced_gateway();
is_gateway = 1;
}
}
#endif /* NETSTACK_CONF_WITH_IPV4 */
/*---------------------------------------------------------------------------*/
#if WITH_TINYOS_AUTO_IDS
uint16_t TOS_NODE_ID = 0x1234; /* non-zero */
@ -255,10 +219,6 @@ main(int argc, char **argv)
ctimer_init();
#if NETSTACK_CONF_WITH_IPV4
slip_arch_init(BAUD2UBR(115200));
#endif /* NETSTACK_CONF_WITH_IPV4 */
init_platform();
set_rime_addr();
@ -345,7 +305,7 @@ main(int argc, char **argv)
NETSTACK_MAC.name CC2420_CONF_CHANNEL);
#endif /* NETSTACK_CONF_WITH_IPV6 */
#if !NETSTACK_CONF_WITH_IPV4 && !NETSTACK_CONF_WITH_IPV6
#if !NETSTACK_CONF_WITH_IPV6
uart1_set_input(serial_line_input_byte);
serial_line_init();
#endif
@ -357,35 +317,6 @@ main(int argc, char **argv)
timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16);
#endif /* TIMESYNCH_CONF_ENABLED */
#if NETSTACK_CONF_WITH_IPV4
process_start(&tcpip_process, NULL);
process_start(&uip_fw_process, NULL); /* Start IP output */
process_start(&slip_process, NULL);
slip_set_input_callback(set_gateway);
{
uip_ipaddr_t hostaddr, netmask;
uip_init();
uip_ipaddr(&hostaddr, 172,16,
linkaddr_node_addr.u8[0],linkaddr_node_addr.u8[1]);
uip_ipaddr(&netmask, 255,255,0,0);
uip_ipaddr_copy(&meshif.ipaddr, &hostaddr);
uip_sethostaddr(&hostaddr);
uip_setnetmask(&netmask);
uip_over_mesh_set_net(&hostaddr, &netmask);
/* uip_fw_register(&slipif);*/
uip_over_mesh_set_gateway_netif(&slipif);
uip_fw_default(&meshif);
uip_over_mesh_init(UIP_OVER_MESH_CHANNEL);
PRINTF("uIP started with IP address %d.%d.%d.%d\n",
uip_ipaddr_to_quad(&hostaddr));
}
#endif /* NETSTACK_CONF_WITH_IPV4 */
watchdog_start();
#if !PROCESS_CONF_NO_PROCESS_NAMES

View File

@ -192,8 +192,6 @@
#endif
#define UIP_CONF_ND6_SEND_RA 0
#define UIP_CONF_IP_FORWARD 0
#define RPL_CONF_STATS 0
#define UIP_CONF_ND6_REACHABLE_TIME 600000
#define UIP_CONF_ND6_RETRANS_TIMER 10000
@ -215,12 +213,6 @@
#define UIP_CONF_UDP 1
#define UIP_CONF_UDP_CHECKSUMS 1
#define UIP_CONF_ICMP6 1
/*---------------------------------------------------------------------------*/
#else /* NETSTACK_CONF_WITH_IPV6 */
/* Network setup for non-IPv6 (rime). */
#define UIP_CONF_IP_FORWARD 1
#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0
#endif /* NETSTACK_CONF_WITH_IPV6 */
/** @} */

View File

@ -473,7 +473,6 @@ typedef uint32_t rtimer_clock_t;
#endif
#define UIP_CONF_ND6_SEND_RA 0
#define UIP_CONF_IP_FORWARD 0
#define RPL_CONF_STATS 0
#define UIP_CONF_ND6_REACHABLE_TIME 600000
@ -517,20 +516,6 @@ typedef uint32_t rtimer_clock_t;
#define MAC_CONF_CHANNEL_CHECK_RATE 8
#ifndef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 8
#endif
/*---------------------------------------------------------------------------*/
#else /* NETSTACK_CONF_WITH_IPV6 */
/* Network setup for non-IPv6 (rime). */
#define UIP_CONF_IP_FORWARD 1
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_CONF_BUFFER_SIZE 108
#endif
#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0
#ifndef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 8
#endif

View File

@ -1,5 +0,0 @@
all: tcp-server
CONTIKI=../..
CONTIKI_WITH_IPV4 = 1
include $(CONTIKI)/Makefile.include

View File

@ -1,119 +0,0 @@
/*
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include "contiki-net.h"
#include "sys/cc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SERVER_PORT 80
static struct tcp_socket socket;
#define INPUTBUFSIZE 400
static uint8_t inputbuf[INPUTBUFSIZE];
#define OUTPUTBUFSIZE 400
static uint8_t outputbuf[OUTPUTBUFSIZE];
PROCESS(tcp_server_process, "TCP echo process");
AUTOSTART_PROCESSES(&tcp_server_process);
static uint8_t get_received;
static int bytes_to_send;
/*---------------------------------------------------------------------------*/
static int
input(struct tcp_socket *s, void *ptr,
const uint8_t *inputptr, int inputdatalen)
{
printf("input %d bytes '%s'\n", inputdatalen, inputptr);
if(!get_received) {
/* See if we have a full GET request in the buffer. */
if(strncmp((char *)inputptr, "GET /", 5) == 0 &&
atoi((char *)&inputptr[5]) != 0) {
bytes_to_send = atoi((char *)&inputptr[5]);
printf("bytes_to_send %d\n", bytes_to_send);
return 0;
}
printf("inputptr '%.*s'\n", inputdatalen, inputptr);
/* Return the number of data bytes we received, to keep them all
in the buffer. */
return inputdatalen;
} else {
/* Discard everything */
return 0; /* all data consumed */
}
}
/*---------------------------------------------------------------------------*/
static void
event(struct tcp_socket *s, void *ptr,
tcp_socket_event_t ev)
{
printf("event %d\n", ev);
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(tcp_server_process, ev, data)
{
PROCESS_BEGIN();
tcp_socket_register(&socket, NULL,
inputbuf, sizeof(inputbuf),
outputbuf, sizeof(outputbuf),
input, event);
tcp_socket_listen(&socket, SERVER_PORT);
printf("Listening on %d\n", SERVER_PORT);
while(1) {
PROCESS_PAUSE();
if(bytes_to_send > 0) {
/* Send header */
printf("sending header\n");
tcp_socket_send_str(&socket, "HTTP/1.0 200 ok\r\nServer: Contiki tcp-socket example\r\n\r\n");
/* Send data */
printf("sending data\n");
while(bytes_to_send > 0) {
PROCESS_PAUSE();
int len, tosend;
tosend = MIN(bytes_to_send, sizeof(outputbuf));
len = tcp_socket_send(&socket, (uint8_t *)"", tosend);
bytes_to_send -= len;
}
tcp_socket_close(&socket);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View File

@ -38,7 +38,6 @@
#include "contiki.h"
#include "net/ip/uip.h"
#include "net/ipv4/uip-fw.h"
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
#include "dev/slip.h"
@ -100,34 +99,6 @@ slip_set_tcpip_input_callback(void (*c)(void))
tcpip_input_callback = c;
}
/*---------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV4
uint8_t
slip_send(void)
{
uint16_t i;
uint8_t *ptr;
uint8_t c;
slip_arch_writeb(SLIP_END);
ptr = &uip_buf[UIP_LLH_LEN];
for(i = 0; i < uip_len; ++i) {
c = *ptr++;
if(c == SLIP_END) {
slip_arch_writeb(SLIP_ESC);
c = SLIP_ESC_END;
} else if(c == SLIP_ESC) {
slip_arch_writeb(SLIP_ESC);
c = SLIP_ESC_ESC;
}
slip_arch_writeb(c);
}
slip_arch_writeb(SLIP_END);
return UIP_FW_OK;
}
#endif /* NETSTACK_CONF_WITH_IPV4 */
/*---------------------------------------------------------------------------*/
uint8_t
slip_write(const void *_ptr, int len)
{
@ -187,9 +158,9 @@ slip_poll_handler(uint8_t *outbuf, uint16_t blen)
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
rxbuf[begin] = 0;
rxbuf[begin + 1] = 0;
rxbuf_init();
/* this is just a test so far... just to see if it works */
slip_arch_writeb('!');
slip_arch_writeb('M');
@ -260,41 +231,6 @@ PROCESS_THREAD(slip_process, ev, data)
/* Move packet from rxbuf to buffer provided by uIP. */
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
UIP_BUFSIZE - UIP_LLH_LEN);
#if !NETSTACK_CONF_WITH_IPV6
if(uip_len == 4 && strncmp((char*)&uip_buf[UIP_LLH_LEN], "?IPA", 4) == 0) {
char buf[8];
memcpy(&buf[0], "=IPA", 4);
memcpy(&buf[4], &uip_hostaddr, 4);
if(input_callback) {
input_callback();
}
slip_write(buf, 8);
} else if(uip_len > 0
&& uip_len == (((uint16_t)(BUF->len[0]) << 8) + BUF->len[1])
&& uip_ipchksum() == 0xffff) {
#define IP_DF 0x40
if(BUF->ipid[0] == 0 && BUF->ipid[1] == 0 && BUF->ipoffset[0] & IP_DF) {
static uint16_t ip_id;
uint16_t nid = ip_id++;
BUF->ipid[0] = nid >> 8;
BUF->ipid[1] = nid;
nid = uip_htons(nid);
nid = ~nid; /* negate */
BUF->ipchksum += nid; /* add */
if(BUF->ipchksum < nid) { /* 1-complement overflow? */
BUF->ipchksum++;
}
}
if(tcpip_input_callback) {
tcpip_input_callback();
} else {
tcpip_input();
}
} else {
uip_clear_buf();
SLIP_STATISTICS(slip_ip_drop++);
}
#else /* NETSTACK_CONF_WITH_IPV6 */
if(uip_len > 0) {
if(tcpip_input_callback) {
tcpip_input_callback();
@ -302,7 +238,6 @@ PROCESS_THREAD(slip_process, ev, data)
tcpip_input();
}
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
PROCESS_END();

View File

@ -114,7 +114,6 @@ static int (* pcap_sendpacket)(struct pcap *, unsigned char *, int);
#define ARP_HWTYPE_ETH 1
#include "net/ip/uip.h"
#include "net/ipv4/uip_arp.h"
struct ethip_hdr {
struct uip_eth_hdr ethhdr;