Removing IPv4 stack
This commit is contained in:
parent
d61cb46e59
commit
1a0f8ab737
@ -66,11 +66,6 @@ MODULES += core/sys core/dev core/lib
|
|||||||
# Include IPv6, IPv4, and/or Rime
|
# Include IPv6, IPv4, and/or Rime
|
||||||
|
|
||||||
HAS_STACK = 0
|
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
|
# Make IPv6 the default stack
|
||||||
ifeq ($(HAS_STACK),0)
|
ifeq ($(HAS_STACK),0)
|
||||||
|
@ -67,11 +67,7 @@
|
|||||||
|
|
||||||
/* direct access into the buffer */
|
/* direct access into the buffer */
|
||||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
#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])
|
#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 */
|
/* bitmap for set options */
|
||||||
enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 };
|
enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 };
|
||||||
|
@ -158,14 +158,6 @@
|
|||||||
#define UIP_CONF_MAX_CONNECTIONS 8
|
#define UIP_CONF_MAX_CONNECTIONS 8
|
||||||
#endif /* UIP_CONF_MAX_CONNECTIONS */
|
#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
|
/* NBR_TABLE_CONF_MAX_NEIGHBORS specifies the maximum number of neighbors
|
||||||
that each node will be able to handle. */
|
that each node will be able to handle. */
|
||||||
#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
|
#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
|
||||||
|
@ -38,9 +38,6 @@
|
|||||||
|
|
||||||
#include "net/ip/tcpip.h"
|
#include "net/ip/tcpip.h"
|
||||||
#include "net/ip/uip.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/uiplib.h"
|
||||||
#include "net/ip/uip-udp-packet.h"
|
#include "net/ip/uip-udp-packet.h"
|
||||||
#include "net/ip/simple-udp.h"
|
#include "net/ip/simple-udp.h"
|
||||||
|
@ -38,7 +38,6 @@
|
|||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
|
|
||||||
#include "net/ip/uip.h"
|
#include "net/ip/uip.h"
|
||||||
#include "net/ipv4/uip-fw.h"
|
|
||||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||||
|
|
||||||
#include "dev/slip.h"
|
#include "dev/slip.h"
|
||||||
@ -166,9 +165,9 @@ slip_poll_handler(uint8_t *outbuf, uint16_t blen)
|
|||||||
&& memcmp(&rxbuf[begin], "CLIENT", 6) == 0) {
|
&& memcmp(&rxbuf[begin], "CLIENT", 6) == 0) {
|
||||||
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
|
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
|
||||||
memset(&rxbuf[begin], 0x0, 6);
|
memset(&rxbuf[begin], 0x0, 6);
|
||||||
|
|
||||||
rxbuf_init();
|
rxbuf_init();
|
||||||
|
|
||||||
for(i = 0; i < 13; i++) {
|
for(i = 0; i < 13; i++) {
|
||||||
slip_arch_writeb("CLIENTSERVER\300"[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 */
|
#endif /* SLIP_CONF_MICROSOFT_CHAT */
|
||||||
|
|
||||||
#ifdef SLIP_CONF_ANSWER_MAC_REQUEST
|
#ifdef SLIP_CONF_ANSWER_MAC_REQUEST
|
||||||
else if(rxbuf[begin] == '?') {
|
else if(rxbuf[begin] == '?') {
|
||||||
/* Used by tapslip6 to request mac for auto configure */
|
/* Used by tapslip6 to request mac for auto configure */
|
||||||
int i, j;
|
int i, j;
|
||||||
char* hexchar = "0123456789abcdef";
|
char* hexchar = "0123456789abcdef";
|
||||||
@ -187,9 +186,9 @@ slip_poll_handler(uint8_t *outbuf, uint16_t blen)
|
|||||||
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
|
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
|
||||||
rxbuf[begin] = 0;
|
rxbuf[begin] = 0;
|
||||||
rxbuf[begin + 1] = 0;
|
rxbuf[begin + 1] = 0;
|
||||||
|
|
||||||
rxbuf_init();
|
rxbuf_init();
|
||||||
|
|
||||||
linkaddr_t addr = get_mac_addr();
|
linkaddr_t addr = get_mac_addr();
|
||||||
/* this is just a test so far... just to see if it works */
|
/* this is just a test so far... just to see if it works */
|
||||||
slip_arch_writeb('!');
|
slip_arch_writeb('!');
|
||||||
@ -328,47 +327,13 @@ PROCESS_THREAD(slip_process, ev, data)
|
|||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
|
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
|
||||||
|
|
||||||
slip_active = 1;
|
slip_active = 1;
|
||||||
|
|
||||||
/* Move packet from rxbuf to buffer provided by uIP. */
|
/* Move packet from rxbuf to buffer provided by uIP. */
|
||||||
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
||||||
UIP_BUFSIZE - 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(uip_len > 0) {
|
||||||
if(input_callback) {
|
if(input_callback) {
|
||||||
input_callback();
|
input_callback();
|
||||||
@ -379,7 +344,6 @@ PROCESS_THREAD(slip_process, ev, data)
|
|||||||
tcpip_input();
|
tcpip_input();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PROCESS_END();
|
PROCESS_END();
|
||||||
|
@ -189,11 +189,7 @@ int strncasecmp(const char *s1, const char *s2, size_t n);
|
|||||||
#define DNS_TYPE_ANY 255
|
#define DNS_TYPE_ANY 255
|
||||||
#define DNS_TYPE_NSEC 47
|
#define DNS_TYPE_NSEC 47
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
#define NATIVE_DNS_TYPE DNS_TYPE_AAAA /* 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_IN 1
|
||||||
#define DNS_CLASS_ANY 255
|
#define DNS_CLASS_ANY 255
|
||||||
@ -239,11 +235,7 @@ struct dns_answer {
|
|||||||
uint16_t class;
|
uint16_t class;
|
||||||
uint16_t ttl[2];
|
uint16_t ttl[2];
|
||||||
uint16_t len;
|
uint16_t len;
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
uint8_t ipaddr[16];
|
uint8_t ipaddr[16];
|
||||||
#else
|
|
||||||
uint8_t ipaddr[4];
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct namemap {
|
struct namemap {
|
||||||
@ -307,13 +299,10 @@ enum {
|
|||||||
static uint8_t mdns_state;
|
static uint8_t mdns_state;
|
||||||
|
|
||||||
static const uip_ipaddr_t resolv_mdns_addr =
|
static const uip_ipaddr_t resolv_mdns_addr =
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
{ { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
{ { 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb } };
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfb } };
|
||||||
#include "net/ipv6/uip-ds6.h"
|
#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;
|
static int mdns_needs_host_announce;
|
||||||
|
|
||||||
PROCESS(mdns_probe_process, "mDNS probe");
|
PROCESS(mdns_probe_process, "mDNS probe");
|
||||||
@ -498,7 +487,6 @@ start_name_collision_check(clock_time_t after)
|
|||||||
static unsigned char *
|
static unsigned char *
|
||||||
mdns_write_announce_records(unsigned char *queryptr, uint8_t *count)
|
mdns_write_announce_records(unsigned char *queryptr, uint8_t *count)
|
||||||
{
|
{
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
for(i = 0; i < UIP_DS6_ADDR_NB; ++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);
|
++(*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;
|
return queryptr;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
@ -576,17 +550,10 @@ mdns_prep_host_announce_packet(void)
|
|||||||
0x00,
|
0x00,
|
||||||
0x04,
|
0x04,
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
0x00,
|
0x00,
|
||||||
0x00,
|
0x00,
|
||||||
0x00,
|
0x00,
|
||||||
0x08,
|
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,
|
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
||||||
(query - (uint8_t *) uip_appdata),
|
(query - (uint8_t *) uip_appdata),
|
||||||
(const uip_ipaddr_t *)
|
(const uip_ipaddr_t *)
|
||||||
uip_nameserver_get(namemapptr->server),
|
uip_nameserver_get(namemapptr->server),
|
||||||
UIP_HTONS(DNS_PORT));
|
UIP_HTONS(DNS_PORT));
|
||||||
|
|
||||||
PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
|
PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
|
||||||
@ -770,7 +737,7 @@ check_entries(void)
|
|||||||
#else /* RESOLV_CONF_SUPPORTS_MDNS */
|
#else /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||||
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
||||||
(query - (uint8_t *) uip_appdata),
|
(query - (uint8_t *) uip_appdata),
|
||||||
uip_nameserver_get(namemapptr->server),
|
uip_nameserver_get(namemapptr->server),
|
||||||
UIP_HTONS(DNS_PORT));
|
UIP_HTONS(DNS_PORT));
|
||||||
PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
|
PRINTF("resolver: (i=%d) Sent DNS request for \"%s\".\n", i,
|
||||||
namemapptr->name);
|
namemapptr->name);
|
||||||
@ -1067,10 +1034,10 @@ newdata(void)
|
|||||||
/* Got to this point there's no answer, try next nameserver if available
|
/* Got to this point there's no answer, try next nameserver if available
|
||||||
since this one doesn't know the answer */
|
since this one doesn't know the answer */
|
||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#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)
|
&& hdr->id != 0)
|
||||||
#else
|
#else
|
||||||
if(nanswers == 0)
|
if(nanswers == 0)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if(try_next_server(namemapptr)) {
|
if(try_next_server(namemapptr)) {
|
||||||
@ -1173,11 +1140,7 @@ PROCESS_THREAD(resolv_process, ev, data)
|
|||||||
PRINTF("resolver: Supports MDNS.\n");
|
PRINTF("resolver: Supports MDNS.\n");
|
||||||
uip_udp_bind(resolv_conn, UIP_HTONS(MDNS_PORT));
|
uip_udp_bind(resolv_conn, UIP_HTONS(MDNS_PORT));
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
uip_ds6_maddr_add(&resolv_mdns_addr);
|
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);
|
resolv_set_hostname(CONTIKI_CONF_DEFAULT_HOSTNAME);
|
||||||
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
#endif /* RESOLV_CONF_SUPPORTS_MDNS */
|
||||||
@ -1276,7 +1239,7 @@ resolv_query(const char *name)
|
|||||||
register struct namemap *nameptr = 0;
|
register struct namemap *nameptr = 0;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
lseq = lseqi = 0;
|
lseq = lseqi = 0;
|
||||||
|
|
||||||
/* Remove trailing dots, if present. */
|
/* Remove trailing dots, if present. */
|
||||||
@ -1360,12 +1323,8 @@ resolv_lookup(const char *name, uip_ipaddr_t ** ipaddr)
|
|||||||
#if UIP_CONF_LOOPBACK_INTERFACE
|
#if UIP_CONF_LOOPBACK_INTERFACE
|
||||||
if(strcmp(name, "localhost")) {
|
if(strcmp(name, "localhost")) {
|
||||||
static uip_ipaddr_t loopback =
|
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, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } };
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } };
|
||||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
|
||||||
{ { 127, 0, 0, 1 } };
|
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
|
||||||
if(ipaddr) {
|
if(ipaddr) {
|
||||||
*ipaddr = &loopback;
|
*ipaddr = &loopback;
|
||||||
}
|
}
|
||||||
@ -1448,11 +1407,7 @@ resolv_found(char *name, uip_ipaddr_t * ipaddr)
|
|||||||
#if RESOLV_CONF_SUPPORTS_MDNS
|
#if RESOLV_CONF_SUPPORTS_MDNS
|
||||||
if(strncasecmp(resolv_hostname, name, strlen(resolv_hostname)) == 0 &&
|
if(strncasecmp(resolv_hostname, name, strlen(resolv_hostname)) == 0 &&
|
||||||
ipaddr
|
ipaddr
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
&& !uip_ds6_is_my_addr(ipaddr)
|
&& !uip_ds6_is_my_addr(ipaddr)
|
||||||
#else
|
|
||||||
&& uip_ipaddr_cmp(&uip_hostaddr, ipaddr) != 0
|
|
||||||
#endif
|
|
||||||
) {
|
) {
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
|
||||||
|
@ -39,13 +39,10 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "contiki-net.h"
|
#include "contiki-net.h"
|
||||||
#include "net/ip/uip-split.h"
|
|
||||||
#include "net/ip/uip-packetqueue.h"
|
#include "net/ip/uip-packetqueue.h"
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
#include "net/ipv6/uip-nd6.h"
|
#include "net/ipv6/uip-nd6.h"
|
||||||
#include "net/ipv6/uip-ds6.h"
|
#include "net/ipv6/uip-ds6.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#if UIP_CONF_IPV6_RPL
|
#if UIP_CONF_IPV6_RPL
|
||||||
#include "net/rpl/rpl.h"
|
#include "net/rpl/rpl.h"
|
||||||
@ -85,7 +82,7 @@ process_event_t tcpip_icmp6_event;
|
|||||||
/* Periodic check of active connections. */
|
/* Periodic check of active connections. */
|
||||||
static struct etimer periodic;
|
static struct etimer periodic;
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_REASSEMBLY
|
#if UIP_CONF_IPV6_REASSEMBLY
|
||||||
/* Timer for reassembly. */
|
/* Timer for reassembly. */
|
||||||
extern struct etimer uip_reass_timer;
|
extern struct etimer uip_reass_timer;
|
||||||
#endif
|
#endif
|
||||||
@ -111,8 +108,7 @@ enum {
|
|||||||
PACKET_INPUT
|
PACKET_INPUT
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Called on IP packet output. */
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
|
|
||||||
static uint8_t (* outputfunc)(const uip_lladdr_t *a);
|
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;
|
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");
|
PROCESS(tcpip_process, "TCP/IP stack");
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if UIP_TCP || UIP_CONF_IP_FORWARD
|
#if UIP_TCP
|
||||||
static void
|
static void
|
||||||
start_periodic_tcp_timer(void)
|
start_periodic_tcp_timer(void)
|
||||||
{
|
{
|
||||||
@ -168,12 +141,12 @@ start_periodic_tcp_timer(void)
|
|||||||
etimer_restart(&periodic);
|
etimer_restart(&periodic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */
|
#endif /* UIP_TCP */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
check_for_tcp_syn(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
|
/* 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
|
an incoming packet contains a SYN: since uIP does not inform the
|
||||||
application if a SYN arrives, we have no other way of starting
|
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) {
|
(UIP_TCP_BUF->flags & TCP_SYN) == TCP_SYN) {
|
||||||
start_periodic_tcp_timer();
|
start_periodic_tcp_timer();
|
||||||
}
|
}
|
||||||
#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */
|
#endif /* UIP_TCP */
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
packet_input(void)
|
packet_input(void)
|
||||||
{
|
{
|
||||||
if(uip_len > 0) {
|
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();
|
check_for_tcp_syn();
|
||||||
uip_input();
|
uip_input();
|
||||||
if(uip_len > 0) {
|
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();
|
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;
|
uip_ipaddr_t addr;
|
||||||
struct uip_udp_conn *conn;
|
struct uip_udp_conn *conn;
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
uip_create_linklocal_allnodes_mcast(&addr);
|
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);
|
conn = udp_new(&addr, port, appstate);
|
||||||
if(conn != NULL) {
|
if(conn != NULL) {
|
||||||
udp_bind(conn, port);
|
udp_bind(conn, port);
|
||||||
@ -427,24 +378,12 @@ eventhandler(process_event_t ev, process_data_t data)
|
|||||||
connections. */
|
connections. */
|
||||||
etimer_restart(&periodic);
|
etimer_restart(&periodic);
|
||||||
uip_periodic(i);
|
uip_periodic(i);
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
tcpip_ipv6_output();
|
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 */
|
#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
|
#if UIP_CONF_IPV6_REASSEMBLY
|
||||||
/*
|
/*
|
||||||
* check the timer for reassembly
|
* check the timer for reassembly
|
||||||
@ -476,7 +415,6 @@ eventhandler(process_event_t ev, process_data_t data)
|
|||||||
uip_ds6_periodic();
|
uip_ds6_periodic();
|
||||||
tcpip_ipv6_output();
|
tcpip_ipv6_output();
|
||||||
}
|
}
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -484,14 +422,7 @@ eventhandler(process_event_t ev, process_data_t data)
|
|||||||
case TCP_POLL:
|
case TCP_POLL:
|
||||||
if(data != NULL) {
|
if(data != NULL) {
|
||||||
uip_poll_conn(data);
|
uip_poll_conn(data);
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
tcpip_ipv6_output();
|
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 the periodic polling, if it isn't already active. */
|
||||||
start_periodic_tcp_timer();
|
start_periodic_tcp_timer();
|
||||||
}
|
}
|
||||||
@ -501,13 +432,7 @@ eventhandler(process_event_t ev, process_data_t data)
|
|||||||
case UDP_POLL:
|
case UDP_POLL:
|
||||||
if(data != NULL) {
|
if(data != NULL) {
|
||||||
uip_udp_periodic_conn(data);
|
uip_udp_periodic_conn(data);
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
tcpip_ipv6_output();
|
tcpip_ipv6_output();
|
||||||
#else
|
|
||||||
if(uip_len > 0) {
|
|
||||||
tcpip_output();
|
|
||||||
}
|
|
||||||
#endif /* UIP_UDP */
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
@ -525,7 +450,6 @@ tcpip_input(void)
|
|||||||
uip_clear_buf();
|
uip_clear_buf();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
void
|
void
|
||||||
tcpip_ipv6_output(void)
|
tcpip_ipv6_output(void)
|
||||||
{
|
{
|
||||||
@ -694,7 +618,7 @@ tcpip_ipv6_output(void)
|
|||||||
#else /* UIP_ND6_SEND_NS */
|
#else /* UIP_ND6_SEND_NS */
|
||||||
PRINTF("tcpip_ipv6_output: neighbor not in cache\n");
|
PRINTF("tcpip_ipv6_output: neighbor not in cache\n");
|
||||||
uip_len = 0;
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
#endif /* UIP_ND6_SEND_NS */
|
#endif /* UIP_ND6_SEND_NS */
|
||||||
} else {
|
} else {
|
||||||
#if UIP_ND6_SEND_NS
|
#if UIP_ND6_SEND_NS
|
||||||
@ -746,7 +670,6 @@ tcpip_ipv6_output(void)
|
|||||||
tcpip_output(NULL);
|
tcpip_output(NULL);
|
||||||
uip_clear_buf();
|
uip_clear_buf();
|
||||||
}
|
}
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if UIP_UDP
|
#if UIP_UDP
|
||||||
void
|
void
|
||||||
@ -835,7 +758,7 @@ PROCESS_THREAD(tcpip_process, ev, data)
|
|||||||
UIP_FALLBACK_INTERFACE.init();
|
UIP_FALLBACK_INTERFACE.init();
|
||||||
#endif
|
#endif
|
||||||
/* initialize RPL if configured for using RPL */
|
/* initialize RPL if configured for using RPL */
|
||||||
#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_RPL
|
#if UIP_CONF_IPV6_RPL
|
||||||
rpl_init();
|
rpl_init();
|
||||||
#endif /* UIP_CONF_IPV6_RPL */
|
#endif /* UIP_CONF_IPV6_RPL */
|
||||||
|
|
||||||
|
@ -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);
|
CCIF void tcpip_poll_udp(struct uip_udp_conn *conn);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \name ICMPv6 functions
|
* \name ICMPv6 functions
|
||||||
* @{
|
* @{
|
||||||
@ -340,20 +340,13 @@ CCIF void tcpip_input(void);
|
|||||||
* \brief Output packet to layer 2
|
* \brief Output packet to layer 2
|
||||||
* The eventual parameter is the MAC address of the destination.
|
* The eventual parameter is the MAC address of the destination.
|
||||||
*/
|
*/
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
uint8_t tcpip_output(const uip_lladdr_t *);
|
uint8_t tcpip_output(const uip_lladdr_t *);
|
||||||
void tcpip_set_outputfunc(uint8_t (* f)(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
|
* \brief This function does address resolution and then calls tcpip_output
|
||||||
*/
|
*/
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
void tcpip_ipv6_output(void);
|
void tcpip_ipv6_output(void);
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Is forwarding generally enabled?
|
* \brief Is forwarding generally enabled?
|
||||||
|
@ -44,16 +44,15 @@
|
|||||||
void
|
void
|
||||||
uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
|
uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
|
||||||
{
|
{
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
uint16_t a;
|
uint16_t a;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int f;
|
int f;
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
|
||||||
if(addr == NULL) {
|
if(addr == NULL) {
|
||||||
PRINTA("(NULL IP addr)");
|
PRINTA("(NULL IP addr)");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
if(ip64_addr_is_ipv4_mapped_addr(addr)) {
|
if(ip64_addr_is_ipv4_mapped_addr(addr)) {
|
||||||
/*
|
/*
|
||||||
* Printing IPv4-mapped addresses is done according to RFC 4291 [1]
|
* 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);
|
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 */
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -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 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------*/
|
|
@ -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_ */
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
@ -53,12 +53,8 @@
|
|||||||
#define UIP_H_
|
#define UIP_H_
|
||||||
|
|
||||||
/* Header sizes. */
|
/* Header sizes. */
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
|
||||||
#define UIP_IPH_LEN 40
|
#define UIP_IPH_LEN 40
|
||||||
#define UIP_FRAGH_LEN 8
|
#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_UDPH_LEN 8 /* Size of UDP header */
|
||||||
#define UIP_TCPH_LEN 20 /* Size of TCP 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:
|
/* uint8_t uip_flags:
|
||||||
*
|
*
|
||||||
@ -2154,6 +2161,60 @@ CCIF extern uip_lladdr_t uip_lladdr;
|
|||||||
|
|
||||||
#endif /*NETSTACK_CONF_WITH_IPV6*/
|
#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.
|
* Calculate the Internet checksum over a buffer.
|
||||||
*
|
*
|
||||||
|
@ -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_ */
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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_ */
|
|
@ -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();
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
@ -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_ */
|
|
@ -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 */
|
|
@ -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_ */
|
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*------------------------------------------------------------------------------*/
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
@ -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_ */
|
|
||||||
|
|
||||||
/** @} */
|
|
@ -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;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
@ -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_ */
|
|
@ -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);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
@ -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_ */
|
|
1973
core/net/ipv4/uip.c
1973
core/net/ipv4/uip.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
|
||||||
}
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
/** @} */
|
|
||||||
|
|
@ -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_ */
|
|
||||||
/** @} */
|
|
@ -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/
|
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 uip6 and sicslowpan
|
||||||
\sa \ref uipopt "uIP Compile-time configuration options"
|
\sa \ref uipopt "uIP Compile-time configuration options"
|
||||||
\sa \ref uipconffunc "uIP Run-time configuration functions"
|
\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"
|
\ref uipdrivervars "uIP variables used by device drivers"
|
||||||
\sa \ref uipappfunc "uIP functions called from application programs"
|
\sa \ref uipappfunc "uIP functions called from application programs"
|
||||||
(see below) and the \ref psock "protosockets API" and their underlying
|
(see below) and the \ref psock "protosockets API" and their underlying
|
||||||
\ref pt "protothreads"
|
\ref pt "protothreads"
|
||||||
|
|
||||||
\section uIPIntroduction Introduction
|
\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
|
specified in a number of RFC documents published by the Internet
|
||||||
Engineering Task Force, IETF. Each of the protocols in the stack is
|
Engineering Task Force, IETF. Each of the protocols in the stack is
|
||||||
defined in one more RFC documents and RFC1122 collects
|
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
|
The RFC1122 requirements can be divided into two categories; those
|
||||||
that deal with the host to host communication and those that deal with
|
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
|
which service the connection should provide. For instance, an
|
||||||
application might decide to act as an HTTP server if the value of
|
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
|
uip_conn->lport is equal to 80 and act as a TELNET server if the value
|
||||||
is 23.
|
is 23.
|
||||||
|
|
||||||
\subsubsection recvdata Receiving Data
|
\subsubsection recvdata Receiving Data
|
||||||
|
|
||||||
@ -442,7 +442,7 @@ the next time the connection is polled by uIP. The uip_connect()
|
|||||||
function returns
|
function returns
|
||||||
a pointer to the uip_conn structure for the new
|
a pointer to the uip_conn structure for the new
|
||||||
connection. If there are no free connection slots, the function
|
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
|
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.
|
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
|
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
|
connection. If there are not enough TCP connection slots to allow a
|
||||||
new connection to be opened, the uip_connect() function returns NULL
|
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
|
\code
|
||||||
void connect_example1_app(void) {
|
void connect_example1_app(void) {
|
||||||
if(uip_connect(uip_conn->ripaddr, HTONS(8080)) == NULL) {
|
if(uip_connect(uip_conn->ripaddr, HTONS(8080)) == NULL) {
|
||||||
uip_abort();
|
uip_abort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
The second example shows how to open a new connection to a specific IP
|
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
|
and has to be retransmitted, it also sends an "ok". Note that this
|
||||||
example actually shows a complete uIP application. It is not required
|
example actually shows a complete uIP application. It is not required
|
||||||
for an application to deal with all types of events such as
|
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
|
\subsection example2 A More Advanced Application
|
||||||
|
|
||||||
@ -573,12 +573,12 @@ void example2_app(void) {
|
|||||||
struct example2_state *s;
|
struct example2_state *s;
|
||||||
|
|
||||||
s = (struct example2_state *)uip_conn->appstate;
|
s = (struct example2_state *)uip_conn->appstate;
|
||||||
|
|
||||||
if(uip_connected()) {
|
if(uip_connected()) {
|
||||||
s->state = WELCOME_SENT;
|
s->state = WELCOME_SENT;
|
||||||
uip_send("Welcome!\n", 9);
|
uip_send("Welcome!\n", 9);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uip_acked() && s->state == WELCOME_SENT) {
|
if(uip_acked() && s->state == WELCOME_SENT) {
|
||||||
s->state = WELCOME_ACKED;
|
s->state = WELCOME_ACKED;
|
||||||
@ -618,7 +618,7 @@ how the two examples above can be combined into one application.
|
|||||||
\code
|
\code
|
||||||
void example3_init(void) {
|
void example3_init(void) {
|
||||||
example1_init();
|
example1_init();
|
||||||
example2_init();
|
example2_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void example3_app(void) {
|
void example3_app(void) {
|
||||||
@ -708,7 +708,7 @@ void example5_init(void) {
|
|||||||
void example5_app(void) {
|
void example5_app(void) {
|
||||||
struct example5_state *s;
|
struct example5_state *s;
|
||||||
s = (struct example5_state)uip_conn->appstate;
|
s = (struct example5_state)uip_conn->appstate;
|
||||||
|
|
||||||
if(uip_connected()) {
|
if(uip_connected()) {
|
||||||
switch(uip_conn->lport) {
|
switch(uip_conn->lport) {
|
||||||
case HTONS(80):
|
case HTONS(80):
|
||||||
@ -721,7 +721,7 @@ void example5_app(void) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
uip_send(s->dataptr, s->dataleft);
|
uip_send(s->dataptr, s->dataleft);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(uip_acked()) {
|
if(uip_acked()) {
|
||||||
@ -731,7 +731,7 @@ void example5_app(void) {
|
|||||||
}
|
}
|
||||||
s->dataptr += uip_conn->len;
|
s->dataptr += uip_conn->len;
|
||||||
s->dataleft -= uip_conn->len;
|
s->dataleft -= uip_conn->len;
|
||||||
uip_send(s->dataptr, s->dataleft);
|
uip_send(s->dataptr, s->dataleft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\endcode
|
\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
|
connects to the application, the local port number is used to
|
||||||
determine which file to send. The first chunk of data is sent using
|
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
|
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
|
The application is driven by incoming acknowledgments. When data has
|
||||||
been acknowledged, new data can be sent. If there is no more data to
|
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) {
|
static void acked(void) {
|
||||||
struct example6_state *s = (struct example6_state *)uip_conn->appstate;
|
struct example6_state *s = (struct example6_state *)uip_conn->appstate;
|
||||||
|
|
||||||
s->textlen -= uip_conn->len;
|
s->textlen -= uip_conn->len;
|
||||||
s->textptr += uip_conn->len;
|
s->textptr += uip_conn->len;
|
||||||
if(s->textlen == 0) {
|
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,
|
that the application is waiting for data to arrive from the network,
|
||||||
"STATE_HELLO", in which the application is sending the "Hello" part of
|
"STATE_HELLO", in which the application is sending the "Hello" part of
|
||||||
the message, or "STATE_WORLD", in which the application is sending the
|
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,
|
The application does not handle errors or connection closing events,
|
||||||
and therefore the aborted(), timedout() and closed() functions are
|
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
|
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
|
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
|
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
|
than a single TCP segment, and would therefore not be affected by the
|
||||||
throughput degradation anyway.
|
throughput degradation anyway.
|
||||||
@ -1179,13 +1179,9 @@ throughput degradation anyway.
|
|||||||
The maximum throughput when uIP acts as a receiver is not affected by
|
The maximum throughput when uIP acts as a receiver is not affected by
|
||||||
the delayed acknowledgment throughput degradation.
|
the delayed acknowledgment throughput degradation.
|
||||||
|
|
||||||
\note The \ref uipsplit module implements a hack that overcomes the
|
|
||||||
problems with the delayed acknowledgment throughput degradation.
|
|
||||||
|
|
||||||
@{
|
@{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
|
||||||
}
|
|
@ -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__ */
|
|
@ -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, <, 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);
|
|
||||||
}
|
|
@ -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__ */
|
|
@ -1,6 +1,5 @@
|
|||||||
#include "dev/uart0.h"
|
#include "dev/uart0.h"
|
||||||
|
|
||||||
#if !NETSTACK_CONF_WITH_IPV4
|
|
||||||
/* In case of IPv4: putchar() is defined by the SLIP driver */
|
/* In case of IPv4: putchar() is defined by the SLIP driver */
|
||||||
int
|
int
|
||||||
putchar(int c)
|
putchar(int c)
|
||||||
@ -8,4 +7,3 @@ putchar(int c)
|
|||||||
uart0_writeb((char)c);
|
uart0_writeb((char)c);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
#endif /* ! NETSTACK_CONF_WITH_IPV4 */
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include "dev/uart1.h"
|
#include "dev/uart1.h"
|
||||||
|
|
||||||
#if !NETSTACK_CONF_WITH_IPV4
|
|
||||||
/* In case of IPv4: putchar() is defined by the SLIP driver */
|
/* In case of IPv4: putchar() is defined by the SLIP driver */
|
||||||
int
|
int
|
||||||
putchar(int c)
|
putchar(int c)
|
||||||
@ -8,4 +7,3 @@ putchar(int c)
|
|||||||
uart1_writeb((char)c);
|
uart1_writeb((char)c);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
#endif /* ! NETSTACK_CONF_WITH_IPV4 */
|
|
||||||
|
@ -132,9 +132,6 @@ uart0_writeb(unsigned char c)
|
|||||||
#endif /* TX_WITH_INTERRUPT */
|
#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.
|
* Initalize the RS232 port.
|
||||||
*
|
*
|
||||||
|
@ -97,9 +97,6 @@ uart1_writeb(unsigned char c)
|
|||||||
#endif /* TX_WITH_INTERRUPT */
|
#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.
|
* Initalize the RS232 port.
|
||||||
*
|
*
|
||||||
@ -116,7 +113,7 @@ uart1_init(unsigned long ubr)
|
|||||||
UCA0CTL1 &= ~UCSWRST; /* Initialize USCI state machine */
|
UCA0CTL1 &= ~UCSWRST; /* Initialize USCI state machine */
|
||||||
|
|
||||||
transmitting = 0;
|
transmitting = 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
ISR(USCIAB1RX, uart1_rx_interrupt)
|
ISR(USCIAB1RX, uart1_rx_interrupt)
|
||||||
@ -149,7 +146,7 @@ ISR(USCIAB1TX, uart1_tx_interrupt)
|
|||||||
UCA0TXBUF = ringbuf_get(&txbuf);
|
UCA0TXBUF = ringbuf_get(&txbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||||
}
|
}
|
||||||
#endif /* TX_WITH_INTERRUPT */
|
#endif /* TX_WITH_INTERRUPT */
|
||||||
|
@ -41,42 +41,6 @@ slip_arch_writeb(unsigned char c)
|
|||||||
{
|
{
|
||||||
uart0_writeb(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.
|
* Initalize the RS232 port and the SLIP driver.
|
||||||
*
|
*
|
||||||
|
@ -42,41 +42,6 @@ slip_arch_writeb(unsigned char c)
|
|||||||
uart1_writeb(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.
|
* Initalize the RS232 port and the SLIP driver.
|
||||||
*
|
*
|
||||||
|
@ -53,7 +53,7 @@ uint8_t
|
|||||||
tapdev_output(void)
|
tapdev_output(void)
|
||||||
{
|
{
|
||||||
uip_arp_out();
|
uip_arp_out();
|
||||||
tapdev_send();
|
tapdev_send();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -81,7 +81,7 @@ pollhandler(void)
|
|||||||
if(uip_len > 0) {
|
if(uip_len > 0) {
|
||||||
tapdev_send();
|
tapdev_send();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
uip_clear_buf();
|
uip_clear_buf();
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "contiki-net.h"
|
#include "contiki-net.h"
|
||||||
#include "net/ipv4/uip-neighbor.h"
|
|
||||||
#include "net/wpcap.h"
|
#include "net/wpcap.h"
|
||||||
|
|
||||||
#include "net/wpcap-drv.h"
|
#include "net/wpcap-drv.h"
|
||||||
@ -69,7 +68,7 @@ uint8_t
|
|||||||
wpcap_output(void)
|
wpcap_output(void)
|
||||||
{
|
{
|
||||||
uip_arp_out();
|
uip_arp_out();
|
||||||
wpcap_send();
|
wpcap_send();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -121,7 +120,7 @@ pollhandler(void)
|
|||||||
// memcpy(uip_buf, uip_buf+14, uip_len);
|
// 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
|
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);
|
// 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();
|
tcpip_input();
|
||||||
} else
|
} else
|
||||||
goto bail;
|
goto bail;
|
||||||
|
@ -385,7 +385,6 @@ typedef uint32_t rtimer_clock_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UIP_CONF_ND6_SEND_RA 0
|
#define UIP_CONF_ND6_SEND_RA 0
|
||||||
#define UIP_CONF_IP_FORWARD 0
|
|
||||||
#define RPL_CONF_STATS 0
|
#define RPL_CONF_STATS 0
|
||||||
|
|
||||||
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
||||||
@ -427,20 +426,6 @@ typedef uint32_t rtimer_clock_t;
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifndef QUEUEBUF_CONF_NUM
|
||||||
#define QUEUEBUF_CONF_NUM 8
|
#define QUEUEBUF_CONF_NUM 8
|
||||||
#endif
|
#endif
|
||||||
|
@ -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
|
## Copied from Makefile.include, since Cooja overrides CFLAGS et al
|
||||||
HAS_STACK = 0
|
HAS_STACK = 0
|
||||||
ifeq ($(CONTIKI_WITH_IPV4),1)
|
|
||||||
HAS_STACK = 1
|
|
||||||
CFLAGS += -DNETSTACK_CONF_WITH_IPV4=1
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(CONTIKI_WITH_RIME),1)
|
ifeq ($(CONTIKI_WITH_RIME),1)
|
||||||
HAS_STACK = 1
|
HAS_STACK = 1
|
||||||
CFLAGS += -DNETSTACK_CONF_WITH_RIME=1
|
CFLAGS += -DNETSTACK_CONF_WITH_RIME=1
|
||||||
|
@ -49,12 +49,6 @@
|
|||||||
|
|
||||||
#define w_memcpy memcpy
|
#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
|
#ifdef NETSTACK_CONF_H
|
||||||
|
|
||||||
/* These header overrides the below default configuration */
|
/* These header overrides the below default configuration */
|
||||||
@ -75,16 +69,6 @@
|
|||||||
/* Radio setup */
|
/* Radio setup */
|
||||||
#define NETSTACK_CONF_RADIO cooja_radio_driver
|
#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_WITH_IPV6 */
|
||||||
|
|
||||||
#endif /* NETSTACK_CONF_H */
|
#endif /* NETSTACK_CONF_H */
|
||||||
@ -138,8 +122,7 @@
|
|||||||
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
||||||
#define UIP_CONF_IPV6_CHECKS 1
|
#define UIP_CONF_IPV6_CHECKS 1
|
||||||
#define UIP_CONF_IPV6_REASSEMBLY 0
|
#define UIP_CONF_IPV6_REASSEMBLY 0
|
||||||
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
|
#define UIP_CONF_NETIF_MAX_ADDRESSES
|
||||||
#define UIP_CONF_IP_FORWARD 0
|
|
||||||
|
|
||||||
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06
|
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06
|
||||||
#ifndef SICSLOWPAN_CONF_FRAG
|
#ifndef SICSLOWPAN_CONF_FRAG
|
||||||
@ -203,8 +186,6 @@ typedef uint64_t rtimer_clock_t;
|
|||||||
#define UIP_CONF_PINGADDRCONF 0
|
#define UIP_CONF_PINGADDRCONF 0
|
||||||
#define UIP_CONF_LOGGING 0
|
#define UIP_CONF_LOGGING 0
|
||||||
|
|
||||||
#define UIP_CONF_TCP_SPLIT 0
|
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
#if NETSTACK_CONF_WITH_IPV6
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||||
|
|
||||||
|
@ -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_tick COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_tick)
|
||||||
#define Java_org_contikios_cooja_corecomm_CLASSNAME_setReferenceAddress COOJA__QUOTEME(COOJA_JNI_PATH,CLASSNAME,_setReferenceAddress)
|
#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
|
#ifndef NETSTACK_CONF_WITH_IPV6
|
||||||
#define NETSTACK_CONF_WITH_IPV6 0
|
#define NETSTACK_CONF_WITH_IPV6 0
|
||||||
#endif
|
#endif
|
||||||
@ -137,22 +118,6 @@ long referenceVar;
|
|||||||
static struct cooja_mt_thread rtimer_thread;
|
static struct cooja_mt_thread rtimer_thread;
|
||||||
static struct cooja_mt_thread process_run_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
|
static void
|
||||||
print_processes(struct process * const processes[])
|
print_processes(struct process * const processes[])
|
||||||
@ -243,35 +208,6 @@ contiki_init()
|
|||||||
printf("%s/%s\n",
|
printf("%s/%s\n",
|
||||||
NETSTACK_NETWORK.name, NETSTACK_MAC.name);
|
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
|
#if NETSTACK_CONF_WITH_IPV6
|
||||||
/* IPv6 CONFIGURATION */
|
/* IPv6 CONFIGURATION */
|
||||||
{
|
{
|
||||||
|
@ -44,13 +44,6 @@ char simIP[16];
|
|||||||
|
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV4
|
|
||||||
|
|
||||||
char simIPChanged;
|
|
||||||
char simIP[4];
|
|
||||||
|
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
doInterfaceActionsBeforeTick(void)
|
doInterfaceActionsBeforeTick(void)
|
||||||
@ -60,20 +53,6 @@ doInterfaceActionsBeforeTick(void)
|
|||||||
/* check if IPv6 address should change */
|
/* check if IPv6 address should change */
|
||||||
|
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
#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
|
static void
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
@ -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_ */
|
|
@ -36,14 +36,6 @@
|
|||||||
|
|
||||||
#define IMPLEMENT_PRINTF 1
|
#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
|
#if MAX_LOG_LENGTH < 1024
|
||||||
#undef MAX_LOG_LENGTH
|
#undef MAX_LOG_LENGTH
|
||||||
#define MAX_LOG_LENGTH 1024
|
#define MAX_LOG_LENGTH 1024
|
||||||
|
@ -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();
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------*/
|
|
@ -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(ð_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(ð_process);
|
|
||||||
|
|
||||||
PROCESS_WAIT_UNTIL(ev == PROCESS_EVENT_EXIT);
|
|
||||||
|
|
||||||
PROCESS_END();
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
@ -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_ */
|
|
@ -62,12 +62,12 @@
|
|||||||
#define PROCESS_CONF_NUMEVENTS 8
|
#define PROCESS_CONF_NUMEVENTS 8
|
||||||
#define PROCESS_CONF_STATS 1
|
#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
|
#define NETSTACK_CONF_WITH_IPV6 1
|
||||||
#endif /* NETSTACK_CONF_ not defined */
|
#endif /* NETSTACK_CONF_ not defined */
|
||||||
|
|
||||||
/* Network setup for IP */
|
/* Network setup for IP */
|
||||||
#if NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6
|
#if NETSTACK_CONF_WITH_IPV6
|
||||||
|
|
||||||
#define LINKADDR_CONF_SIZE 8
|
#define LINKADDR_CONF_SIZE 8
|
||||||
|
|
||||||
@ -88,7 +88,7 @@
|
|||||||
#define QUEUEBUF_CONF_NUM 16
|
#define QUEUEBUF_CONF_NUM 16
|
||||||
#endif /* QUEUEBUF_CONF_NUM */
|
#endif /* QUEUEBUF_CONF_NUM */
|
||||||
|
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV4 || NETSTACK_CONF_WITH_IPV6 */
|
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||||
|
|
||||||
/* Network setup for IPv6 */
|
/* Network setup for IPv6 */
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
#if NETSTACK_CONF_WITH_IPV6
|
||||||
@ -130,7 +130,6 @@
|
|||||||
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
|
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
|
||||||
#define UIP_CONF_ND6_MAX_PREFIXES 3
|
#define UIP_CONF_ND6_MAX_PREFIXES 3
|
||||||
#define UIP_CONF_ND6_MAX_DEFROUTERS 2
|
#define UIP_CONF_ND6_MAX_DEFROUTERS 2
|
||||||
#define UIP_CONF_IP_FORWARD 0
|
|
||||||
#ifndef UIP_CONF_BUFFER_SIZE
|
#ifndef UIP_CONF_BUFFER_SIZE
|
||||||
#define UIP_CONF_BUFFER_SIZE 1280
|
#define UIP_CONF_BUFFER_SIZE 1280
|
||||||
#endif
|
#endif
|
||||||
@ -166,8 +165,6 @@
|
|||||||
#define UIP_CONF_LOGGING 0
|
#define UIP_CONF_LOGGING 0
|
||||||
#define LOG_CONF_ENABLED 0
|
#define LOG_CONF_ENABLED 0
|
||||||
|
|
||||||
#define UIP_CONF_TCP_SPLIT 0
|
|
||||||
|
|
||||||
#define UIP_CONF_BYTE_ORDER UIP_BIG_ENDIAN
|
#define UIP_CONF_BYTE_ORDER UIP_BIG_ENDIAN
|
||||||
#define UIP_CONF_LOGGING 0
|
#define UIP_CONF_LOGGING 0
|
||||||
|
|
||||||
|
@ -92,24 +92,6 @@ unsigned char node_mac[8];
|
|||||||
* marks the end of the stack taking into account the used heap */
|
* marks the end of the stack taking into account the used heap */
|
||||||
extern uint32_t heap_location;
|
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
|
#ifdef EXPERIMENT_SETUP
|
||||||
#include "experiment-setup.h"
|
#include "experiment-setup.h"
|
||||||
#endif
|
#endif
|
||||||
@ -165,23 +147,6 @@ print_processes(struct process *const processes[])
|
|||||||
}
|
}
|
||||||
#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */
|
#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
|
static void
|
||||||
start_autostart_processes()
|
start_autostart_processes()
|
||||||
{
|
{
|
||||||
@ -332,10 +297,6 @@ main(void)
|
|||||||
ctimer_init();
|
ctimer_init();
|
||||||
uart0_init(UART_BAUD_RATE); /* Must come before first PRINTF */
|
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 */
|
/* check for reset source */
|
||||||
if(bAHI_WatchdogResetEvent()) {
|
if(bAHI_WatchdogResetEvent()) {
|
||||||
PRINTF("Init: Watchdog timer has reset device!\r\n");
|
PRINTF("Init: Watchdog timer has reset device!\r\n");
|
||||||
@ -350,9 +311,6 @@ main(void)
|
|||||||
#else
|
#else
|
||||||
PRINTF(CONTIKI_VERSION_STRING " started with IPV6\n");
|
PRINTF(CONTIKI_VERSION_STRING " started with IPV6\n");
|
||||||
#endif
|
#endif
|
||||||
#elif NETSTACK_CONF_WITH_IPV4
|
|
||||||
PRINTF(CONTIKI_VERSION_STRING " started with IPV4\n");
|
|
||||||
#else
|
|
||||||
PRINTF(CONTIKI_VERSION_STRING " started\n");
|
PRINTF(CONTIKI_VERSION_STRING " started\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -378,35 +336,6 @@ main(void)
|
|||||||
timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16);
|
timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16);
|
||||||
#endif /* TIMESYNCH_CONF_ENABLED */
|
#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();
|
watchdog_start();
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV6
|
#if NETSTACK_CONF_WITH_IPV6
|
||||||
|
@ -46,7 +46,6 @@
|
|||||||
|
|
||||||
#include <MicroInt.h>
|
#include <MicroInt.h>
|
||||||
#include "net/ip/uip.h"
|
#include "net/ip/uip.h"
|
||||||
#include "net/ipv4/uip-fw.h"
|
|
||||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||||
|
|
||||||
#include "dev/slip.h"
|
#include "dev/slip.h"
|
||||||
|
@ -70,7 +70,6 @@ typedef unsigned short uip_stats_t;
|
|||||||
#define UIP_CONF_BUFFER_SIZE 420
|
#define UIP_CONF_BUFFER_SIZE 420
|
||||||
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
|
#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN
|
||||||
#define UIP_CONF_TCP 1
|
#define UIP_CONF_TCP 1
|
||||||
#define UIP_CONF_TCP_SPLIT 0
|
|
||||||
#define UIP_CONF_LOGGING 0
|
#define UIP_CONF_LOGGING 0
|
||||||
#define UIP_CONF_UDP_CHECKSUMS 1
|
#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_REACHABLE_TIME 600000
|
||||||
#define UIP_CONF_ND6_RETRANS_TIMER 10000
|
#define UIP_CONF_ND6_RETRANS_TIMER 10000
|
||||||
|
|
||||||
#define UIP_CONF_IP_FORWARD 0
|
|
||||||
#ifndef UIP_CONF_BUFFER_SIZE
|
#ifndef UIP_CONF_BUFFER_SIZE
|
||||||
#define UIP_CONF_BUFFER_SIZE 240
|
#define UIP_CONF_BUFFER_SIZE 240
|
||||||
#endif
|
#endif
|
||||||
|
@ -230,9 +230,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
|
printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]);
|
||||||
}
|
}
|
||||||
#elif NETSTACK_CONF_WITH_IPV4
|
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||||
process_start(&tcpip_process, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
serial_line_init();
|
serial_line_init();
|
||||||
|
|
||||||
|
@ -110,7 +110,6 @@
|
|||||||
/* ND and Routing */
|
/* ND and Routing */
|
||||||
#define UIP_CONF_ROUTER 0 /**< BLE master role, which allows for routing, isn't supported. */
|
#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_ND6_SEND_NS 1
|
||||||
#define UIP_CONF_IP_FORWARD 0 /**< No packet forwarding. */
|
|
||||||
|
|
||||||
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
||||||
#define UIP_CONF_ND6_RETRANS_TIMER 10000
|
#define UIP_CONF_ND6_RETRANS_TIMER 10000
|
||||||
|
@ -442,7 +442,6 @@ typedef uint32_t rtimer_clock_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UIP_CONF_ND6_SEND_RA 0
|
#define UIP_CONF_ND6_SEND_RA 0
|
||||||
#define UIP_CONF_IP_FORWARD 0
|
|
||||||
#define RPL_CONF_STATS 0
|
#define RPL_CONF_STATS 0
|
||||||
|
|
||||||
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
||||||
@ -484,20 +483,6 @@ typedef uint32_t rtimer_clock_t;
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
#ifndef QUEUEBUF_CONF_NUM
|
||||||
#define QUEUEBUF_CONF_NUM 8
|
#define QUEUEBUF_CONF_NUM 8
|
||||||
#endif
|
#endif
|
||||||
|
@ -96,7 +96,6 @@
|
|||||||
#define UIP_CONF_IPV6_CHECKS 1
|
#define UIP_CONF_IPV6_CHECKS 1
|
||||||
#define UIP_CONF_IPV6_REASSEMBLY 0
|
#define UIP_CONF_IPV6_REASSEMBLY 0
|
||||||
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
|
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
|
||||||
#define UIP_CONF_IP_FORWARD 0
|
|
||||||
#ifndef UIP_CONF_BUFFER_SIZE
|
#ifndef UIP_CONF_BUFFER_SIZE
|
||||||
#define UIP_CONF_BUFFER_SIZE 240
|
#define UIP_CONF_BUFFER_SIZE 240
|
||||||
#endif
|
#endif
|
||||||
@ -107,9 +106,7 @@
|
|||||||
#define SICSLOWPAN_CONF_MAXAGE 8
|
#define SICSLOWPAN_CONF_MAXAGE 8
|
||||||
#endif /* SICSLOWPAN_CONF_FRAG */
|
#endif /* SICSLOWPAN_CONF_FRAG */
|
||||||
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2
|
#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 */
|
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||||
|
|
||||||
#define UIP_CONF_ICMP_DEST_UNREACH 1
|
#define UIP_CONF_ICMP_DEST_UNREACH 1
|
||||||
@ -133,8 +130,6 @@
|
|||||||
#define UIP_CONF_PINGADDRCONF 0
|
#define UIP_CONF_PINGADDRCONF 0
|
||||||
#define UIP_CONF_LOGGING 0
|
#define UIP_CONF_LOGGING 0
|
||||||
|
|
||||||
#define UIP_CONF_TCP_SPLIT 0
|
|
||||||
|
|
||||||
#ifndef AES_128_CONF
|
#ifndef AES_128_CONF
|
||||||
#define AES_128_CONF cc2420_aes_128_driver
|
#define AES_128_CONF cc2420_aes_128_driver
|
||||||
#endif /* AES_128_CONF */
|
#endif /* AES_128_CONF */
|
||||||
|
@ -71,26 +71,7 @@ static struct timer mgt_timer;
|
|||||||
#endif
|
#endif
|
||||||
extern int msp430_dco_required;
|
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
|
#define UIP_OVER_MESH_CHANNEL 8
|
||||||
#if NETSTACK_CONF_WITH_IPV4
|
|
||||||
static uint8_t is_gateway;
|
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
|
||||||
|
|
||||||
#ifdef EXPERIMENT_SETUP
|
#ifdef EXPERIMENT_SETUP
|
||||||
#include "experiment-setup.h"
|
#include "experiment-setup.h"
|
||||||
@ -170,23 +151,6 @@ print_processes(struct process * const processes[])
|
|||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
#endif /* !PROCESS_CONF_NO_PROCESS_NAMES */
|
#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
|
#if WITH_TINYOS_AUTO_IDS
|
||||||
uint16_t TOS_NODE_ID = 0x1234; /* non-zero */
|
uint16_t TOS_NODE_ID = 0x1234; /* non-zero */
|
||||||
@ -255,10 +219,6 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
ctimer_init();
|
ctimer_init();
|
||||||
|
|
||||||
#if NETSTACK_CONF_WITH_IPV4
|
|
||||||
slip_arch_init(BAUD2UBR(115200));
|
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV4 */
|
|
||||||
|
|
||||||
init_platform();
|
init_platform();
|
||||||
|
|
||||||
set_rime_addr();
|
set_rime_addr();
|
||||||
@ -345,7 +305,7 @@ main(int argc, char **argv)
|
|||||||
NETSTACK_MAC.name CC2420_CONF_CHANNEL);
|
NETSTACK_MAC.name CC2420_CONF_CHANNEL);
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
#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);
|
uart1_set_input(serial_line_input_byte);
|
||||||
serial_line_init();
|
serial_line_init();
|
||||||
#endif
|
#endif
|
||||||
@ -357,35 +317,6 @@ main(int argc, char **argv)
|
|||||||
timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16);
|
timesynch_set_authority_level((linkaddr_node_addr.u8[0] << 4) + 16);
|
||||||
#endif /* TIMESYNCH_CONF_ENABLED */
|
#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();
|
watchdog_start();
|
||||||
|
|
||||||
#if !PROCESS_CONF_NO_PROCESS_NAMES
|
#if !PROCESS_CONF_NO_PROCESS_NAMES
|
||||||
|
@ -192,8 +192,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UIP_CONF_ND6_SEND_RA 0
|
#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_REACHABLE_TIME 600000
|
||||||
#define UIP_CONF_ND6_RETRANS_TIMER 10000
|
#define UIP_CONF_ND6_RETRANS_TIMER 10000
|
||||||
@ -215,12 +213,6 @@
|
|||||||
#define UIP_CONF_UDP 1
|
#define UIP_CONF_UDP 1
|
||||||
#define UIP_CONF_UDP_CHECKSUMS 1
|
#define UIP_CONF_UDP_CHECKSUMS 1
|
||||||
#define UIP_CONF_ICMP6 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 */
|
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -473,7 +473,6 @@ typedef uint32_t rtimer_clock_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define UIP_CONF_ND6_SEND_RA 0
|
#define UIP_CONF_ND6_SEND_RA 0
|
||||||
#define UIP_CONF_IP_FORWARD 0
|
|
||||||
#define RPL_CONF_STATS 0
|
#define RPL_CONF_STATS 0
|
||||||
|
|
||||||
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
#define UIP_CONF_ND6_REACHABLE_TIME 600000
|
||||||
@ -517,20 +516,6 @@ typedef uint32_t rtimer_clock_t;
|
|||||||
|
|
||||||
#define MAC_CONF_CHANNEL_CHECK_RATE 8
|
#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
|
#ifndef QUEUEBUF_CONF_NUM
|
||||||
#define QUEUEBUF_CONF_NUM 8
|
#define QUEUEBUF_CONF_NUM 8
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
all: tcp-server
|
|
||||||
|
|
||||||
CONTIKI=../..
|
|
||||||
CONTIKI_WITH_IPV4 = 1
|
|
||||||
include $(CONTIKI)/Makefile.include
|
|
@ -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();
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
@ -38,7 +38,6 @@
|
|||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
|
|
||||||
#include "net/ip/uip.h"
|
#include "net/ip/uip.h"
|
||||||
#include "net/ipv4/uip-fw.h"
|
|
||||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||||
|
|
||||||
#include "dev/slip.h"
|
#include "dev/slip.h"
|
||||||
@ -100,34 +99,6 @@ slip_set_tcpip_input_callback(void (*c)(void))
|
|||||||
tcpip_input_callback = c;
|
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
|
uint8_t
|
||||||
slip_write(const void *_ptr, int len)
|
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. */
|
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
|
||||||
rxbuf[begin] = 0;
|
rxbuf[begin] = 0;
|
||||||
rxbuf[begin + 1] = 0;
|
rxbuf[begin + 1] = 0;
|
||||||
|
|
||||||
rxbuf_init();
|
rxbuf_init();
|
||||||
|
|
||||||
/* this is just a test so far... just to see if it works */
|
/* this is just a test so far... just to see if it works */
|
||||||
slip_arch_writeb('!');
|
slip_arch_writeb('!');
|
||||||
slip_arch_writeb('M');
|
slip_arch_writeb('M');
|
||||||
@ -260,41 +231,6 @@ PROCESS_THREAD(slip_process, ev, data)
|
|||||||
/* Move packet from rxbuf to buffer provided by uIP. */
|
/* Move packet from rxbuf to buffer provided by uIP. */
|
||||||
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
||||||
UIP_BUFSIZE - 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(uip_len > 0) {
|
||||||
if(tcpip_input_callback) {
|
if(tcpip_input_callback) {
|
||||||
tcpip_input_callback();
|
tcpip_input_callback();
|
||||||
@ -302,7 +238,6 @@ PROCESS_THREAD(slip_process, ev, data)
|
|||||||
tcpip_input();
|
tcpip_input();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PROCESS_END();
|
PROCESS_END();
|
||||||
|
@ -114,7 +114,6 @@ static int (* pcap_sendpacket)(struct pcap *, unsigned char *, int);
|
|||||||
#define ARP_HWTYPE_ETH 1
|
#define ARP_HWTYPE_ETH 1
|
||||||
|
|
||||||
#include "net/ip/uip.h"
|
#include "net/ip/uip.h"
|
||||||
#include "net/ipv4/uip_arp.h"
|
|
||||||
|
|
||||||
struct ethip_hdr {
|
struct ethip_hdr {
|
||||||
struct uip_eth_hdr ethhdr;
|
struct uip_eth_hdr ethhdr;
|
||||||
|
Loading…
Reference in New Issue
Block a user