Merge branch 'develop' into cc2420_carrier
This commit is contained in:
commit
cf9be4e7f8
|
@ -68,3 +68,4 @@ env:
|
|||
- TEST_NAME='compile-tools'
|
||||
- TEST_NAME='native-runs'
|
||||
- TEST_NAME='ipv6' BUILD_COOJA=true
|
||||
- TEST_NAME='ipv6-nbr' BUILD_COOJA=true
|
||||
|
|
|
@ -51,7 +51,7 @@ uint16_t
|
|||
uip_ipchksum(void)
|
||||
{
|
||||
/* Assumes proper alignement of uip_buf. */
|
||||
uint16_t *p = (uint16_t *)&uip_buf[UIP_LLH_LEN];
|
||||
uint16_t *p = (uint16_t *)UIP_IP_BUF;
|
||||
register uint16_t sum;
|
||||
|
||||
sum = p[0];
|
||||
|
|
|
@ -263,7 +263,7 @@ output(const linkaddr_t *localdest)
|
|||
{
|
||||
LOG_DBG("SUT: %u\n", uip_len);
|
||||
if(uip_len > 0) {
|
||||
return tun_output(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
return tun_output(uip_buf, uip_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ handle_fd(fd_set *rset, fd_set *wset)
|
|||
LOG_INFO("Tun6-handle FD\n");
|
||||
|
||||
if(FD_ISSET(tunfd, rset)) {
|
||||
size = tun_input(&uip_buf[UIP_LLH_LEN], sizeof(uip_buf));
|
||||
size = tun_input(uip_buf, sizeof(uip_buf));
|
||||
LOG_DBG("TUN data incoming read:%d\n", size);
|
||||
uip_len = size;
|
||||
tcpip_input();
|
||||
|
|
|
@ -347,6 +347,12 @@ off(void)
|
|||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
max_payload(void)
|
||||
{
|
||||
return PACKETBUF_SIZE;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
init(void)
|
||||
{
|
||||
|
@ -371,7 +377,8 @@ const struct mac_driver ble_ipsp_mac_driver = {
|
|||
send_packet,
|
||||
NULL,
|
||||
on,
|
||||
off
|
||||
off,
|
||||
max_payload
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
static uint8_t
|
||||
uip_driver_send(const linkaddr_t *addr)
|
||||
{
|
||||
packetbuf_copyfrom(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
packetbuf_copyfrom(uip_buf, uip_len);
|
||||
|
||||
/* XXX we should provide a callback function that is called when the
|
||||
packet is sent. For now, we just supply a NULL pointer. */
|
||||
|
@ -64,9 +64,8 @@ init(void)
|
|||
static void
|
||||
input(void)
|
||||
{
|
||||
if(packetbuf_datalen() > 0 &&
|
||||
packetbuf_datalen() <= UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], packetbuf_dataptr(), packetbuf_datalen());
|
||||
if(packetbuf_datalen() > 0 && packetbuf_datalen() <= UIP_BUFSIZE) {
|
||||
memcpy(uip_buf, packetbuf_dataptr(), packetbuf_datalen());
|
||||
uip_len = packetbuf_datalen();
|
||||
tcpip_input();
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
|
||||
#include <MicroInt.h>
|
||||
#include "net/ipv6/uip.h"
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#include "dev/slip.h"
|
||||
|
||||
|
@ -117,7 +116,7 @@ unsigned long slip_received, slip_frames;
|
|||
#ifdef SLIP_CONF_RX_BUFSIZE
|
||||
#define RX_BUFSIZE SLIP_CONF_RX_BUFSIZE
|
||||
|
||||
#if RX_BUFSIZE < (UIP_BUFSIZE - UIP_LLH_LEN + 16)
|
||||
#if RX_BUFSIZE < (UIP_BUFSIZE + 16)
|
||||
#error "SLIP_CONF_RX_BUFSIZE too small for UIP_BUFSIZE"
|
||||
#endif
|
||||
|
||||
|
@ -195,7 +194,7 @@ slip_send(void)
|
|||
|
||||
slip_arch_writeb(SLIP_END);
|
||||
|
||||
ptr = &uip_buf[UIP_LLH_LEN];
|
||||
ptr = uip_buf;
|
||||
for(i = 0; i < uip_len; ++i) {
|
||||
c = *ptr++;
|
||||
slip_write_char(c);
|
||||
|
@ -317,8 +316,7 @@ PROCESS_THREAD(slip_process, ev, data)
|
|||
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
|
||||
|
||||
/* Move packet from rxbuf to buffer provided by uIP. */
|
||||
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
||||
UIP_BUFSIZE - UIP_LLH_LEN);
|
||||
uip_len = slip_poll_handler(uip_buf, UIP_BUFSIZE);
|
||||
|
||||
PRINTF("SLIP: recv bytes %u frames RECV: %u. is_full %u, is_dropping %u.\n",
|
||||
end_counter, uip_len, is_full, is_dropping);
|
||||
|
|
|
@ -74,6 +74,10 @@
|
|||
|
||||
/* Packet buffer */
|
||||
#define PACKETBUF_CONF_SIZE 1280 /**< Required IPv6 MTU size */
|
||||
|
||||
/* Queuebuf */
|
||||
#define QUEUEBUF_CONF_ENABLED 0
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#define LOG_MODULE "App"
|
||||
#define LOG_LEVEL LOG_LEVEL_INFO
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(ipv6_hooks_process, "IPv6 Hooks");
|
||||
AUTOSTART_PROCESSES(&ipv6_hooks_process);
|
||||
|
|
|
@ -55,8 +55,6 @@
|
|||
static struct uip_udp_conn *sink_conn;
|
||||
static uint16_t count;
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#if !NETSTACK_CONF_WITH_IPV6 || !UIP_CONF_ROUTER || !UIP_IPV6_MULTICAST || !UIP_CONF_IPV6_RPL
|
||||
#error "This example can not work with the current contiki configuration"
|
||||
#error "Check the values of: NETSTACK_CONF_WITH_IPV6, UIP_CONF_ROUTER, UIP_CONF_IPV6_RPL"
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
/*---------------------------------------------------------------------------*/
|
||||
#include "contiki.h"
|
||||
#include "httpd-simple.h"
|
||||
#include "net/ipv6/uip-ds6-nbr.h"
|
||||
#include "net/ipv6/uip-ds6-route.h"
|
||||
#include "batmon-sensor.h"
|
||||
#include "lib/sensors.h"
|
||||
|
@ -436,8 +437,8 @@ PT_THREAD(generate_index(struct httpd_state *s))
|
|||
PT_WAIT_THREAD(&s->generate_pt,
|
||||
enqueue_chunk(s, 0, SECTION_OPEN "Neighbors" CONTENT_OPEN));
|
||||
|
||||
for(s->nbr = nbr_table_head(ds6_neighbors); s->nbr != NULL;
|
||||
s->nbr = nbr_table_next(ds6_neighbors, s->nbr)) {
|
||||
for(s->nbr = uip_ds6_nbr_head(); s->nbr != NULL;
|
||||
s->nbr = uip_ds6_nbr_next(s->nbr)) {
|
||||
|
||||
PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "\n"));
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#define REST_MAX_CHUNK_SIZE 256
|
||||
|
||||
/* Network config */
|
||||
//#define UIP_CONF_BUFFER_SIZE (REST_MAX_CHUNK_SIZE + UIP_LLH_LEN + UIP_IPUDPH_LEN + COAP_MAX_HEADER_SIZE)
|
||||
//#define UIP_CONF_BUFFER_SIZE (REST_MAX_CHUNK_SIZE + UIP_IPUDPH_LEN + COAP_MAX_HEADER_SIZE)
|
||||
//#define UIP_CONF_BUFFER_SIZE (REST_MAX_CHUNK_SIZE + 0 + 48 + 70)
|
||||
#define UIP_CONF_BUFFER_SIZE 1280 /* ipv6 required minimum */
|
||||
|
||||
|
|
|
@ -50,8 +50,6 @@
|
|||
#define DEBUG DEBUG_PRINT
|
||||
#include "net/ipv6/uip-debug.h"
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#define INTERVAL (10)
|
||||
#define BLINK_TIME (CLOCK_SECOND/4)
|
||||
|
||||
|
|
|
@ -97,7 +97,6 @@ PROCESS_THREAD(er_example_server, ev, data)
|
|||
PRINTF("Starting Erbium Example Server\n");
|
||||
|
||||
PRINTF("uIP buffer: %u\n", UIP_BUFSIZE);
|
||||
PRINTF("LL header: %u\n", UIP_LLH_LEN);
|
||||
PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN);
|
||||
PRINTF("REST max chunk: %u\n", COAP_MAX_CHUNK_SIZE);
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "contiki-net.h"
|
||||
#include "net/ipv6/uip.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include "net/ipv6/uip-ds6-nbr.h"
|
||||
#include "net/routing/routing.h"
|
||||
#include "dev/leds.h"
|
||||
#include "ip64/ip64.h"
|
||||
|
@ -142,9 +143,9 @@ PT_THREAD(generate_routes(struct httpd_state *s))
|
|||
#endif
|
||||
ADD("Neighbors<pre>");
|
||||
|
||||
for(nbr = nbr_table_head(ds6_neighbors);
|
||||
for(nbr = uip_ds6_nbr_head();
|
||||
nbr != NULL;
|
||||
nbr = nbr_table_next(ds6_neighbors, nbr)) {
|
||||
nbr = uip_ds6_nbr_next(nbr)) {
|
||||
|
||||
#if WEBSERVER_CONF_NEIGHBOR_STATUS
|
||||
#if BUF_USES_STACK
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include "contiki.h"
|
||||
#include "net/routing/routing.h"
|
||||
#include "net/ipv6/uip-ds6-nbr.h"
|
||||
#include "net/ipv6/uip-ds6-route.h"
|
||||
#include "net/ipv6/uip-sr.h"
|
||||
|
||||
|
@ -90,9 +91,9 @@ PT_THREAD(generate_routes(struct httpd_state *s))
|
|||
|
||||
ADD(" Neighbors\n <ul>\n");
|
||||
SEND(&s->sout);
|
||||
for(nbr = nbr_table_head(ds6_neighbors);
|
||||
for(nbr = uip_ds6_nbr_head();
|
||||
nbr != NULL;
|
||||
nbr = nbr_table_next(ds6_neighbors, nbr)) {
|
||||
nbr = uip_ds6_nbr_next(nbr)) {
|
||||
ADD(" <li>");
|
||||
ipaddr_add(&nbr->ipaddr);
|
||||
ADD("</li>\n");
|
||||
|
|
|
@ -32,16 +32,21 @@ udp_rx_callback(struct simple_udp_connection *c,
|
|||
const uint8_t *data,
|
||||
uint16_t datalen)
|
||||
{
|
||||
unsigned count = *(unsigned *)data;
|
||||
LOG_INFO("Received response %u from ", count);
|
||||
|
||||
LOG_INFO("Received response '%.*s' from ", datalen, (char *) data);
|
||||
LOG_INFO_6ADDR(sender_addr);
|
||||
#if LLSEC802154_CONF_ENABLED
|
||||
LOG_INFO_(" LLSEC LV:%d", uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
|
||||
#endif
|
||||
LOG_INFO_("\n");
|
||||
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(udp_client_process, ev, data)
|
||||
{
|
||||
static struct etimer periodic_timer;
|
||||
static unsigned count;
|
||||
static char str[32];
|
||||
uip_ipaddr_t dest_ipaddr;
|
||||
|
||||
PROCESS_BEGIN();
|
||||
|
@ -59,7 +64,8 @@ PROCESS_THREAD(udp_client_process, ev, data)
|
|||
LOG_INFO("Sending request %u to ", count);
|
||||
LOG_INFO_6ADDR(&dest_ipaddr);
|
||||
LOG_INFO_("\n");
|
||||
simple_udp_sendto(&udp_conn, &count, sizeof(count), &dest_ipaddr);
|
||||
snprintf(str, sizeof(str), "hello %d", count);
|
||||
simple_udp_sendto(&udp_conn, str, strlen(str), &dest_ipaddr);
|
||||
count++;
|
||||
} else {
|
||||
LOG_INFO("Not reachable yet\n");
|
||||
|
|
|
@ -54,15 +54,13 @@ udp_rx_callback(struct simple_udp_connection *c,
|
|||
const uint8_t *data,
|
||||
uint16_t datalen)
|
||||
{
|
||||
unsigned count = *(unsigned *)data;
|
||||
LOG_INFO("Received request %u from ", count);
|
||||
LOG_INFO("Received request '%.*s' from ", datalen, (char *) data);
|
||||
LOG_INFO_6ADDR(sender_addr);
|
||||
LOG_INFO_("\n");
|
||||
#if WITH_SERVER_REPLY
|
||||
LOG_INFO("Sending response %u to ", count);
|
||||
LOG_INFO_6ADDR(sender_addr);
|
||||
LOG_INFO_("\n");
|
||||
simple_udp_sendto(&udp_conn, &count, sizeof(count), sender_addr);
|
||||
/* send back the same string to the client as an echo reply */
|
||||
LOG_INFO("Sending response.\n");
|
||||
simple_udp_sendto(&udp_conn, data, datalen, sender_addr);
|
||||
#endif /* WITH_SERVER_REPLY */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -226,12 +226,11 @@ slip_radio_cmd_handler(const uint8_t *data, int len)
|
|||
static void
|
||||
slip_input_callback(void)
|
||||
{
|
||||
LOG_DBG("SR-SIN: %u '%c%c'\n", uip_len,
|
||||
uip_buf[UIP_LLH_LEN], uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(!cmd_input(&uip_buf[UIP_LLH_LEN], uip_len)) {
|
||||
LOG_DBG("SR-SIN: %u '%c%c'\n", uip_len, uip_buf[0], uip_buf[1]);
|
||||
if(!cmd_input(uip_buf, uip_len)) {
|
||||
cmd_send((uint8_t *)"EUnknown command", 16);
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "sys/stack-check.h"
|
||||
#include "dev/watchdog.h"
|
||||
|
||||
#include "net/queuebuf.h"
|
||||
#include "net/app-layer/coap/coap-engine.h"
|
||||
#include "services/rpl-border-router/rpl-border-router.h"
|
||||
#include "services/orchestra/orchestra.h"
|
||||
|
@ -89,6 +90,9 @@ main(void)
|
|||
|
||||
platform_init_stage_two();
|
||||
|
||||
#if QUEUEBUF_ENABLED
|
||||
queuebuf_init();
|
||||
#endif /* QUEUEBUF_ENABLED */
|
||||
netstack_init();
|
||||
node_id_init();
|
||||
|
||||
|
|
|
@ -44,10 +44,8 @@
|
|||
#include "net/ipv6/uip-nameserver.h"
|
||||
#include "net/routing/routing.h"
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#include "net/ipv6/uip-icmp6.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
#include "net/ipv6/resolv.h"
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ static uint16_t slip_rubbish, slip_twopackets, slip_overflow, slip_ip_drop;
|
|||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Must be at least one byte larger than UIP_BUFSIZE! */
|
||||
#define RX_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN + 16)
|
||||
#define RX_BUFSIZE (UIP_BUFSIZE + 16)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
enum {
|
||||
STATE_TWOPACKETS = 0, /* We have 2 packets and drop incoming data. */
|
||||
|
@ -87,7 +87,7 @@ slip_set_input_callback(void (*c)(void))
|
|||
void
|
||||
slip_send(void)
|
||||
{
|
||||
slip_write(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
slip_write(uip_buf, uip_len);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -252,8 +252,7 @@ PROCESS_THREAD(slip_process, ev, data)
|
|||
slip_active = 1;
|
||||
|
||||
/* Move packet from rxbuf to buffer provided by uIP. */
|
||||
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
||||
UIP_BUFSIZE - UIP_LLH_LEN);
|
||||
uip_len = slip_poll_handler(uip_buf, UIP_BUFSIZE);
|
||||
|
||||
if(uip_len > 0) {
|
||||
if(input_callback) {
|
||||
|
|
|
@ -70,21 +70,13 @@
|
|||
#endif /* WITH_DTLS */
|
||||
|
||||
/* sanity check for configured values */
|
||||
#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPH_LEN - UIP_UDPH_LEN)
|
||||
#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_IPH_LEN - UIP_UDPH_LEN)
|
||||
#error "UIP_CONF_BUFFER_SIZE too small for COAP_MAX_CHUNK_SIZE"
|
||||
#endif
|
||||
|
||||
#define SERVER_LISTEN_PORT UIP_HTONS(COAP_DEFAULT_PORT)
|
||||
#define SERVER_LISTEN_SECURE_PORT UIP_HTONS(COAP_DEFAULT_SECURE_PORT)
|
||||
|
||||
/* direct access into the buffer */
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#else
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DTLS
|
||||
static dtls_handler_t cb;
|
||||
static dtls_context_t *dtls_context = NULL;
|
||||
|
|
|
@ -103,26 +103,18 @@ static struct uip_udp_conn *c;
|
|||
static uip_ipaddr_t src_ip;
|
||||
static uip_ipaddr_t des_ip;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* uIPv6 Pointers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Local function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void icmp_input(void);
|
||||
static void icmp_output(void);
|
||||
static void mcast_fwd(void *p);
|
||||
int remove_ext_hdr(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Internal Data Structures */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct multicast_on_behalf{ /* ICMP message of multicast_on_behalf */
|
||||
uint16_t mcast_port;
|
||||
uip_ipaddr_t mcast_ip;
|
||||
uint8_t mcast_payload[UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN];
|
||||
uint8_t mcast_payload[UIP_BUFSIZE - UIP_IPUDPH_LEN];
|
||||
};
|
||||
#define UIP_ICMP_MOB 18 /* Size of multicast_on_behalf ICMP header */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -143,7 +135,7 @@ icmp_output()
|
|||
|
||||
struct multicast_on_behalf *mob;
|
||||
mob = (struct multicast_on_behalf *)UIP_ICMP_PAYLOAD;
|
||||
memcpy(&mob->mcast_payload, &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], uip_slen);
|
||||
memcpy(&mob->mcast_payload, &uip_buf[UIP_IPUDPH_LEN], uip_slen);
|
||||
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
UIP_IP_BUF->tcflow = 0;
|
||||
|
@ -164,8 +156,7 @@ icmp_output()
|
|||
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
PRINTF("\n");
|
||||
|
||||
UIP_IP_BUF->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8;
|
||||
UIP_IP_BUF->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + payload_len);
|
||||
|
||||
UIP_ICMP_BUF->type = ICMP6_ESMRF;
|
||||
UIP_ICMP_BUF->icode = ESMRF_ICMP_CODE;
|
||||
|
@ -199,7 +190,7 @@ icmp_input()
|
|||
}
|
||||
#endif
|
||||
|
||||
remove_ext_hdr();
|
||||
uip_remove_ext_hdr();
|
||||
|
||||
PRINTF("ESMRF: ICMPv6 In from ");
|
||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
|
@ -210,11 +201,11 @@ icmp_input()
|
|||
VERBOSE_PRINTF("ESMRF: ICMPv6 In, parse from %p to %p\n",
|
||||
UIP_ICMP_PAYLOAD,
|
||||
(uint8_t *)UIP_ICMP_PAYLOAD + uip_len -
|
||||
uip_l2_l3_icmp_hdr_len);
|
||||
uip_l3_icmp_hdr_len);
|
||||
|
||||
|
||||
locmobptr = (struct multicast_on_behalf *) UIP_ICMP_PAYLOAD;
|
||||
loclen = uip_len - (uip_l2_l3_icmp_hdr_len + UIP_ICMP_MOB);
|
||||
loclen = uip_len - (uip_l3_icmp_hdr_len + UIP_ICMP_MOB);
|
||||
|
||||
uip_ipaddr_copy(&src_ip, &UIP_IP_BUF->srcipaddr);
|
||||
uip_ipaddr_copy(&des_ip, &UIP_IP_BUF->destipaddr);
|
||||
|
@ -224,13 +215,13 @@ icmp_input()
|
|||
c->rport = locmobptr->mcast_port;
|
||||
uip_slen = loclen;
|
||||
uip_udp_conn=c;
|
||||
memcpy(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], locmobptr->mcast_payload,
|
||||
loclen > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN?
|
||||
UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: loclen);
|
||||
memcpy(&uip_buf[UIP_IPUDPH_LEN], locmobptr->mcast_payload,
|
||||
loclen > UIP_BUFSIZE - UIP_IPUDPH_LEN?
|
||||
UIP_BUFSIZE - UIP_IPUDPH_LEN: loclen);
|
||||
|
||||
uip_process(UIP_UDP_SEND_CONN);
|
||||
|
||||
memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len);
|
||||
memcpy(&mcast_buf, uip_buf, uip_len);
|
||||
mcast_len = uip_len;
|
||||
/* pass the packet to our uip_process to check if it is allowed to
|
||||
* accept this packet or not */
|
||||
|
@ -240,7 +231,7 @@ icmp_input()
|
|||
|
||||
uip_process(UIP_DATA);
|
||||
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len);
|
||||
memcpy(uip_buf, &mcast_buf, mcast_len);
|
||||
uip_len = mcast_len;
|
||||
/* Return the IP of the original Multicast sender */
|
||||
uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &src_ip);
|
||||
|
@ -252,17 +243,17 @@ icmp_input()
|
|||
/* If we enter here, we will definitely forward */
|
||||
tcpip_ipv6_output();
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
mcast_fwd(void *p)
|
||||
{
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len);
|
||||
memcpy(uip_buf, &mcast_buf, mcast_len);
|
||||
uip_len = mcast_len;
|
||||
UIP_IP_BUF->ttl--;
|
||||
tcpip_output(NULL);
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
|
@ -352,7 +343,7 @@ in()
|
|||
fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread));
|
||||
}
|
||||
|
||||
memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len);
|
||||
memcpy(&mcast_buf, uip_buf, uip_len);
|
||||
mcast_len = uip_len;
|
||||
ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL);
|
||||
}
|
||||
|
|
|
@ -276,7 +276,7 @@ struct mcast_packet {
|
|||
uint16_t seq_val; /* host-byte order */
|
||||
struct sliding_window *sw; /* Pointer to the SW this packet belongs to */
|
||||
uint8_t flags; /* Is-Used, Must Send, Is Listed */
|
||||
uint8_t buff[UIP_BUFSIZE - UIP_LLH_LEN];
|
||||
uint8_t buff[UIP_BUFSIZE];
|
||||
};
|
||||
|
||||
/* Flag bits */
|
||||
|
@ -289,7 +289,7 @@ struct mcast_packet {
|
|||
#define MCAST_PACKET_GET_SEED(p) ((seed_id_t *)&((p)->seed_id))
|
||||
#else
|
||||
#define MCAST_PACKET_GET_SEED(p) \
|
||||
((seed_id_t *)&((struct uip_ip_hdr *)&(p)->buff[UIP_LLH_LEN])->srcipaddr)
|
||||
((seed_id_t *)&((struct uip_ip_hdr *)&(p)->buff[0])->srcipaddr)
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -456,14 +456,9 @@ static uint16_t last_seq;
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* uIPv6 Pointers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_DATA_BUF ((uint8_t *)&uip_buf[uip_l2_l3_hdr_len + UIP_UDPH_LEN])
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#define UIP_EXT_BUF_NEXT ((uint8_t *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + HBHO_TOTAL_LEN])
|
||||
#define UIP_EXT_OPT_FIRST ((struct hbho_mcast *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + 2])
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)UIP_IP_PAYLOAD(0))
|
||||
#define UIP_EXT_BUF_NEXT ((uint8_t *)(UIP_IP_PAYLOAD(HBHO_TOTAL_LEN)))
|
||||
#define UIP_EXT_OPT_FIRST ((struct hbho_mcast *)(UIP_IP_PAYLOAD(0) + 2))
|
||||
extern uint16_t uip_slen;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Local function prototypes */
|
||||
|
@ -864,8 +859,7 @@ icmp_output()
|
|||
roll_tm_create_dest(&UIP_IP_BUF->destipaddr);
|
||||
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
|
||||
|
||||
UIP_IP_BUF->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8;
|
||||
UIP_IP_BUF->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + payload_len);
|
||||
|
||||
UIP_ICMP_BUF->type = ICMP6_ROLL_TM;
|
||||
UIP_ICMP_BUF->icode = ROLL_TM_ICMP_CODE;
|
||||
|
@ -1153,10 +1147,10 @@ icmp_input()
|
|||
VERBOSE_PRINTF("ROLL TM: ICMPv6 In, parse from %p to %p\n",
|
||||
UIP_ICMP_PAYLOAD,
|
||||
(uint8_t *)UIP_ICMP_PAYLOAD + uip_len -
|
||||
uip_l2_l3_icmp_hdr_len);
|
||||
uip_l3_icmp_hdr_len);
|
||||
while(locslhptr <
|
||||
(struct sequence_list_header *)((uint8_t *)UIP_ICMP_PAYLOAD +
|
||||
uip_len - uip_l2_l3_icmp_hdr_len)) {
|
||||
uip_len - uip_l3_icmp_hdr_len)) {
|
||||
VERBOSE_PRINTF("ROLL TM: ICMPv6 In, seq hdr @ %p\n", locslhptr);
|
||||
|
||||
if((locslhptr->flags & SEQUENCE_LIST_RES) != 0) {
|
||||
|
@ -1321,7 +1315,7 @@ static void
|
|||
out()
|
||||
{
|
||||
|
||||
if(uip_len + HBHO_TOTAL_LEN > UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
if(uip_len + HBHO_TOTAL_LEN > UIP_BUFSIZE) {
|
||||
PRINTF("ROLL TM: Multicast Out can not add HBHO. Packet too long\n");
|
||||
goto drop;
|
||||
}
|
||||
|
@ -1355,13 +1349,11 @@ out()
|
|||
HBH_SET_M(lochbhmptr);
|
||||
#endif
|
||||
|
||||
uip_ext_len += HBHO_TOTAL_LEN;
|
||||
uip_len += HBHO_TOTAL_LEN;
|
||||
uipbuf_add_ext_hdr(HBHO_TOTAL_LEN);
|
||||
|
||||
/* Update the proto and length field in the v6 header */
|
||||
UIP_IP_BUF->proto = UIP_PROTO_HBHO;
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
PRINTF("ROLL TM: Multicast Out, HBHO: T=%u, L=%u, M=%u, S=0x%02x%02x\n",
|
||||
lochbhmptr->type, lochbhmptr->len, HBH_GET_M(lochbhmptr),
|
||||
|
@ -1383,7 +1375,7 @@ out()
|
|||
|
||||
drop:
|
||||
uip_slen = 0;
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
|
|
|
@ -77,18 +77,14 @@ static uip_buf_t mcast_buf;
|
|||
static uint8_t fwd_delay;
|
||||
static uint8_t fwd_spread;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* uIPv6 Pointers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
mcast_fwd(void *p)
|
||||
{
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len);
|
||||
memcpy(uip_buf, &mcast_buf, mcast_len);
|
||||
uip_len = mcast_len;
|
||||
UIP_IP_BUF->ttl--;
|
||||
tcpip_output(NULL);
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
|
@ -178,7 +174,7 @@ in()
|
|||
fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread));
|
||||
}
|
||||
|
||||
memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len);
|
||||
memcpy(&mcast_buf, uip_buf, uip_len);
|
||||
mcast_len = uip_len;
|
||||
ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL);
|
||||
}
|
||||
|
|
|
@ -116,8 +116,6 @@ int strcasecmp(const char *s1, const char *s2);
|
|||
int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
#endif /* __SDCC */
|
||||
|
||||
#define UIP_UDP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
/* If RESOLV_CONF_SUPPORTS_MDNS is set, then queries
|
||||
* for domain names in the local TLD will use mDNS as
|
||||
* described by draft-cheshire-dnsext-multicastdns.
|
||||
|
@ -837,7 +835,7 @@ newdata(void)
|
|||
} else {
|
||||
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
||||
mdns_prep_host_announce_packet(),
|
||||
&UIP_UDP_BUF->srcipaddr,
|
||||
&UIP_IP_BUF->srcipaddr,
|
||||
UIP_UDP_BUF->srcport);
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -121,33 +121,11 @@
|
|||
#define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN])
|
||||
#define SICSLOWPAN_IPPAYLOAD_BUF(buf) (&buf[UIP_IPH_LEN])
|
||||
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_UDP_BUF(p) ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN + p])
|
||||
#define UIP_TCP_BUF ((struct uip_tcp_hdr *)&uip_buf[UIP_LLIPH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLIPH_LEN])
|
||||
#define UIP_IPPAYLOAD_BUF(pos) (&uip_buf[UIP_LLIPH_LEN + pos])
|
||||
#define UIP_IPPAYLOAD_BUF_POS(pos) (&uip_buf[UIP_IPH_LEN + (pos)])
|
||||
#define UIP_UDP_BUF_POS(pos) ((struct uip_udp_hdr *)UIP_IPPAYLOAD_BUF_POS(pos))
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
/** \brief Maximum available size for frame headers,
|
||||
link layer security-related overhead, as well as
|
||||
6LoWPAN payload. */
|
||||
#ifdef SICSLOWPAN_CONF_MAC_MAX_PAYLOAD
|
||||
#define MAC_MAX_PAYLOAD SICSLOWPAN_CONF_MAC_MAX_PAYLOAD
|
||||
#else /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
|
||||
#define MAC_MAX_PAYLOAD (127 - 2)
|
||||
#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
|
||||
|
||||
/** \brief Maximum size of a frame header. This value is
|
||||
* used in case framer returns an error */
|
||||
#ifdef SICSLOWPAN_CONF_MAC_MAX_HEADER
|
||||
#define MAC_MAX_HEADER SICSLOWPAN_CONF_MAC_MAX_HEADER
|
||||
#else /* SICSLOWPAN_CONF_MAC_MAX_HEADER */
|
||||
#define MAC_MAX_HEADER 21
|
||||
#endif /* SICSLOWPAN_CONF_MAC_MAX_HEADER */
|
||||
|
||||
/* set this to zero if not compressing EXT_HDR - for backwards compatibility */
|
||||
#ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR
|
||||
#define COMPRESS_EXT_HDR SICSLOWPAN_CONF_COMPRESS_EXT_HDR
|
||||
|
@ -250,7 +228,7 @@ static uint16_t my_tag;
|
|||
#define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE
|
||||
#else
|
||||
/* The default fragment size (110 bytes for 127-2 bytes frames) */
|
||||
#define SICSLOWPAN_FRAGMENT_SIZE (MAC_MAX_PAYLOAD - 15)
|
||||
#define SICSLOWPAN_FRAGMENT_SIZE (127 - 2 - 15)
|
||||
#endif
|
||||
|
||||
/* Assuming that the worst growth for uncompression is 38 bytes */
|
||||
|
@ -466,9 +444,9 @@ set_packet_attrs(void)
|
|||
|
||||
/* assign values to the channel attribute (port or type + code) */
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_UDP) {
|
||||
c = UIP_UDP_BUF(0)->srcport;
|
||||
if(UIP_UDP_BUF(0)->destport < c) {
|
||||
c = UIP_UDP_BUF(0)->destport;
|
||||
c = UIP_UDP_BUF_POS(0)->srcport;
|
||||
if(UIP_UDP_BUF_POS(0)->destport < c) {
|
||||
c = UIP_UDP_BUF_POS(0)->destport;
|
||||
}
|
||||
} else if(UIP_IP_BUF->proto == UIP_PROTO_TCP) {
|
||||
c = UIP_TCP_BUF->srcport;
|
||||
|
@ -919,7 +897,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
|
|||
/* Handle the header here! */
|
||||
{
|
||||
struct uip_ext_hdr *ext_hdr =
|
||||
(struct uip_ext_hdr *) UIP_IPPAYLOAD_BUF(ext_hdr_len);
|
||||
(struct uip_ext_hdr *) UIP_IPPAYLOAD_BUF_POS(ext_hdr_len);
|
||||
int len;
|
||||
proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_DESTO : proto;
|
||||
/* Len is defined to be in octets from the length byte */
|
||||
|
@ -958,7 +936,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
|
|||
case UIP_PROTO_UDP:
|
||||
/* allocate a byte for the next header posision as UDP has no next */
|
||||
hc06_ptr++;
|
||||
udp_buf = UIP_UDP_BUF(ext_hdr_len);
|
||||
udp_buf = UIP_UDP_BUF_POS(ext_hdr_len);
|
||||
LOG_DBG("compression: inlined UDP ports on send side: %x, %x\n",
|
||||
UIP_HTONS(udp_buf->srcport), UIP_HTONS(udp_buf->destport));
|
||||
/* Mask out the last 4 bits can be used as a mask */
|
||||
|
@ -1548,8 +1526,6 @@ fragment_copy_payload_and_send(uint16_t uip_offset, linkaddr_t *dest) {
|
|||
static uint8_t
|
||||
output(const linkaddr_t *localdest)
|
||||
{
|
||||
int framer_hdrlen;
|
||||
int max_payload;
|
||||
int frag_needed;
|
||||
|
||||
/* The MAC address of the destination of the packet */
|
||||
|
@ -1588,13 +1564,23 @@ output(const linkaddr_t *localdest)
|
|||
|
||||
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC */
|
||||
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
|
||||
framer_hdrlen = NETSTACK_FRAMER.length();
|
||||
if(framer_hdrlen < 0) {
|
||||
/* Framing failed, we assume the maximum header length */
|
||||
framer_hdrlen = MAC_MAX_HEADER;
|
||||
}
|
||||
#if LLSEC802154_USES_AUX_HEADER
|
||||
/* copy LLSEC level */
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
|
||||
uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
|
||||
#if LLSEC802154_USES_EXPLICIT_KEYS
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
|
||||
uipbuf_get_attr(UIPBUF_ATTR_LLSEC_KEY_ID));
|
||||
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
|
||||
#endif /* LLSEC802154_USES_AUX_HEADER */
|
||||
|
||||
mac_max_payload = MAC_MAX_PAYLOAD - framer_hdrlen;
|
||||
mac_max_payload = NETSTACK_MAC.max_payload();
|
||||
|
||||
if(mac_max_payload <= 0) {
|
||||
/* Framing failed, drop packet */
|
||||
LOG_WARN("output: failed to calculate payload size - dropping packet\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try to compress the headers */
|
||||
#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
|
||||
|
@ -1615,22 +1601,17 @@ output(const linkaddr_t *localdest)
|
|||
}
|
||||
#endif /* SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC */
|
||||
|
||||
/* Calculate NETSTACK_FRAMER's header length, that will be added in the NETSTACK_MAC.
|
||||
* We calculate it here only to make a better decision of whether the outgoing packet
|
||||
* needs to be fragmented or not. */
|
||||
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
|
||||
framer_hdrlen = NETSTACK_FRAMER.length();
|
||||
if(framer_hdrlen < 0) {
|
||||
/* Framing failed, we assume the maximum header length */
|
||||
framer_hdrlen = MAC_MAX_HEADER;
|
||||
}
|
||||
/* Use the mac_max_payload to understand what is the max payload in a MAC
|
||||
* packet. We calculate it here only to make a better decision of whether
|
||||
* the outgoing packet needs to be fragmented or not. */
|
||||
|
||||
max_payload = MAC_MAX_PAYLOAD - framer_hdrlen;
|
||||
frag_needed = (int)uip_len - (int)uncomp_hdr_len + (int)packetbuf_hdr_len > max_payload;
|
||||
packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER, &dest);
|
||||
|
||||
frag_needed = (int)uip_len - (int)uncomp_hdr_len + (int)packetbuf_hdr_len > mac_max_payload;
|
||||
LOG_INFO("output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
|
||||
uncomp_hdr_len, packetbuf_hdr_len,
|
||||
uip_len, uip_len - uncomp_hdr_len + packetbuf_hdr_len,
|
||||
max_payload, frag_needed);
|
||||
mac_max_payload, frag_needed);
|
||||
|
||||
if(frag_needed) {
|
||||
#if SICSLOWPAN_CONF_FRAG
|
||||
|
@ -1650,11 +1631,11 @@ output(const linkaddr_t *localdest)
|
|||
/* Total IPv6 payload */
|
||||
int total_payload = (uip_len - uncomp_hdr_len);
|
||||
/* IPv6 payload that goes to first fragment */
|
||||
int frag1_payload = (max_payload - packetbuf_hdr_len - SICSLOWPAN_FRAG1_HDR_LEN) & 0xfffffff8;
|
||||
int frag1_payload = (mac_max_payload - packetbuf_hdr_len - SICSLOWPAN_FRAG1_HDR_LEN) & 0xfffffff8;
|
||||
/* max IPv6 payload in each FRAGN. Must be multiple of 8 bytes */
|
||||
int fragn_max_payload = (max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
|
||||
int fragn_max_payload = (mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
|
||||
/* max IPv6 payload in the last fragment. Needs not be multiple of 8 bytes */
|
||||
int last_fragn_max_payload = max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
|
||||
int last_fragn_max_payload = mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
|
||||
/* sum of all IPv6 payload that goes to non-first and non-last fragments */
|
||||
int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
|
||||
/* Ceiling of: 2 + middle_fragn_total_payload / fragn_max_payload */
|
||||
|
@ -1806,6 +1787,9 @@ input(void)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Clear uipbuf and set default attributes */
|
||||
uipbuf_clear();
|
||||
|
||||
/* This is default uip_buf since we assume that this is not fragmented */
|
||||
buffer = (uint8_t *)UIP_IP_BUF;
|
||||
|
||||
|
@ -1840,7 +1824,6 @@ input(void)
|
|||
}
|
||||
|
||||
buffer = frag_info[frag_context].first_frag;
|
||||
|
||||
break;
|
||||
case SICSLOWPAN_DISPATCH_FRAGN:
|
||||
/*
|
||||
|
@ -1936,12 +1919,12 @@ input(void)
|
|||
|
||||
/* Sanity-check size of incoming packet to avoid buffer overflow */
|
||||
{
|
||||
int req_size = UIP_LLH_LEN + uncomp_hdr_len + (uint16_t)(frag_offset << 3)
|
||||
int req_size = uncomp_hdr_len + (uint16_t)(frag_offset << 3)
|
||||
+ packetbuf_payload_len;
|
||||
if(req_size > sizeof(uip_buf)) {
|
||||
LOG_ERR(
|
||||
"input: packet dropped, minimum required IP_BUF size: %d+%d+%d+%d=%d (current size: %u)\n",
|
||||
UIP_LLH_LEN, uncomp_hdr_len, (uint16_t)(frag_offset << 3),
|
||||
"input: packet dropped, minimum required IP_BUF size: %d+%d+%d=%d (current size: %u)\n",
|
||||
uncomp_hdr_len, (uint16_t)(frag_offset << 3),
|
||||
packetbuf_payload_len, req_size, (unsigned)sizeof(uip_buf));
|
||||
return;
|
||||
}
|
||||
|
@ -2004,6 +1987,19 @@ input(void)
|
|||
callback->input_callback();
|
||||
}
|
||||
|
||||
#if LLSEC802154_USES_AUX_HEADER
|
||||
/*
|
||||
* Assuming that the last packet in packetbuf is containing
|
||||
* the LLSEC state so that it can be copied to uipbuf.
|
||||
*/
|
||||
uipbuf_set_attr(UIPBUF_ATTR_LLSEC_LEVEL,
|
||||
packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
|
||||
#if LLSEC802154_USES_EXPLICIT_KEYS
|
||||
uipbuf_set_attr(UIPBUF_ATTR_LLSEC_KEY_ID,
|
||||
packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX));
|
||||
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
|
||||
#endif /* LLSEC802154_USES_AUX_HEADER */
|
||||
|
||||
tcpip_input();
|
||||
#if SICSLOWPAN_CONF_FRAG
|
||||
}
|
||||
|
@ -2061,11 +2057,6 @@ sicslowpan_init(void)
|
|||
#endif /* SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1 */
|
||||
|
||||
#endif /* SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC */
|
||||
|
||||
/* We use the queuebuf module if fragmentation is enabled */
|
||||
#if SICSLOWPAN_CONF_FRAG
|
||||
queuebuf_init();
|
||||
#endif
|
||||
}
|
||||
/*--------------------------------------------------------------------*/
|
||||
int
|
||||
|
|
|
@ -52,8 +52,6 @@ PROCESS(simple_udp_process, "Simple UDP process");
|
|||
static uint8_t started = 0;
|
||||
static uint8_t databuffer[UIP_BUFSIZE];
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
init_simple_udp(void)
|
||||
|
@ -134,7 +132,7 @@ PROCESS_THREAD(simple_udp_process, ev, data)
|
|||
{
|
||||
struct simple_udp_connection *c;
|
||||
PROCESS_BEGIN();
|
||||
|
||||
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT();
|
||||
if(ev == tcpip_event) {
|
||||
|
@ -165,9 +163,9 @@ PROCESS_THREAD(simple_udp_process, ev, data)
|
|||
PROCESS_CONTEXT_BEGIN(c->client_process);
|
||||
c->receive_callback(c,
|
||||
&(UIP_IP_BUF->srcipaddr),
|
||||
UIP_HTONS(UIP_IP_BUF->srcport),
|
||||
UIP_HTONS(UIP_UDP_BUF->srcport),
|
||||
&(UIP_IP_BUF->destipaddr),
|
||||
UIP_HTONS(UIP_IP_BUF->destport),
|
||||
UIP_HTONS(UIP_UDP_BUF->destport),
|
||||
databuffer, uip_datalen());
|
||||
PROCESS_CONTEXT_END();
|
||||
}
|
||||
|
|
|
@ -55,10 +55,6 @@
|
|||
#define LOG_MODULE "TCP/IP"
|
||||
#define LOG_LEVEL LOG_LEVEL_TCPIP
|
||||
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLIPH_LEN + uip_ext_len])
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_TCP_BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#ifdef UIP_FALLBACK_INTERFACE
|
||||
extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE;
|
||||
#endif
|
||||
|
@ -129,7 +125,7 @@ tcpip_output(const uip_lladdr_t *a)
|
|||
return ret;
|
||||
} else {
|
||||
/* Ok, ignore and drop... */
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -452,18 +448,16 @@ tcpip_input(void)
|
|||
NETSTACK_IP_PROCESS) {
|
||||
process_post_synch(&tcpip_process, PACKET_INPUT, NULL);
|
||||
} /* else - do nothing and drop */
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
extern void remove_ext_hdr(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
output_fallback(void)
|
||||
{
|
||||
#ifdef UIP_FALLBACK_INTERFACE
|
||||
LOG_INFO("fallback: removing ext hdrs & setting proto %d %d\n",
|
||||
uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40));
|
||||
remove_ext_hdr();
|
||||
uip_remove_ext_hdr();
|
||||
/* Inform the other end that the destination is not reachable. If it's
|
||||
* not informed routes might get lost unexpectedly until there's a need
|
||||
* to send a new packet to the peer */
|
||||
|
@ -658,7 +652,7 @@ tcpip_ipv6_output(void)
|
|||
if(!NETSTACK_ROUTING.ext_header_update()) {
|
||||
/* Packet can not be forwarded */
|
||||
LOG_ERR("output: routing protocol extension header update error\n");
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -746,7 +740,7 @@ send_packet:
|
|||
}
|
||||
|
||||
exit:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -38,9 +38,6 @@ PROCESS(udp_socket_process, "UDP socket process");
|
|||
|
||||
static uint8_t buf[UIP_BUFSIZE];
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
init(void)
|
||||
|
@ -182,9 +179,9 @@ PROCESS_THREAD(udp_socket_process, ev, data)
|
|||
PROCESS_CONTEXT_BEGIN(c->p);
|
||||
c->input_callback(c, c->ptr,
|
||||
&(UIP_IP_BUF->srcipaddr),
|
||||
UIP_HTONS(UIP_IP_BUF->srcport),
|
||||
UIP_HTONS(UIP_UDP_BUF->srcport),
|
||||
&(UIP_IP_BUF->destipaddr),
|
||||
UIP_HTONS(UIP_IP_BUF->destport),
|
||||
UIP_HTONS(UIP_UDP_BUF->destport),
|
||||
buf, uip_datalen());
|
||||
PROCESS_CONTEXT_END();
|
||||
}
|
||||
|
|
|
@ -55,19 +55,67 @@
|
|||
#include "net/ipv6/uip-nd6.h"
|
||||
#include "net/routing/routing.h"
|
||||
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
#include "lib/memb.h"
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "IPv6 Nbr"
|
||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||
|
||||
NBR_TABLE_GLOBAL(uip_ds6_nbr_t, ds6_neighbors);
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
/**
|
||||
* Add nbr to the list in nbr_entry. In other words, this function associates an
|
||||
* IPv6 address in nbr with a link-layer address in nbr_entry.
|
||||
* \param nbr the neighbor cache entry for an IPv6 address
|
||||
* \param nbr_entry the nbr_table entry for an link-layer address
|
||||
*/
|
||||
static void add_uip_ds6_nbr_to_nbr_entry(uip_ds6_nbr_t *nbr,
|
||||
uip_ds6_nbr_entry_t *nbr_entry);
|
||||
|
||||
/**
|
||||
* Remove nbr from the list of the corresponding nbr_entry
|
||||
* \param nbr a neighbor cache entry (nbr) to be removed
|
||||
*/
|
||||
static void remove_uip_ds6_nbr_from_nbr_entry(uip_ds6_nbr_t *nbr);
|
||||
|
||||
/**
|
||||
* Remove nbr_etnry from nbr_table
|
||||
* \param nbr_entry a nbr_table entry (nbr_entry) to be removed
|
||||
*/
|
||||
static void remove_nbr_entry(uip_ds6_nbr_entry_t *nbr_entry);
|
||||
|
||||
/**
|
||||
* Free memory for a specified neighbor cache entry
|
||||
* \param nbr a neighbor cache entry to be freed
|
||||
*/
|
||||
static void free_uip_ds6_nbr(uip_ds6_nbr_t *nbr);
|
||||
|
||||
/**
|
||||
* Callback function called when a nbr_table entry is removed
|
||||
* \param nbr_entry a nbr_entry to be removed
|
||||
*/
|
||||
static void callback_nbr_entry_removal(uip_ds6_nbr_entry_t *nbr_entry);
|
||||
|
||||
NBR_TABLE(uip_ds6_nbr_entry_t, uip_ds6_nbr_entries);
|
||||
MEMB(uip_ds6_nbr_memb, uip_ds6_nbr_t, UIP_DS6_NBR_MAX_NEIGHBOR_CACHES);
|
||||
#else
|
||||
NBR_TABLE(uip_ds6_nbr_t, ds6_neighbors);
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_ds6_neighbors_init(void)
|
||||
{
|
||||
link_stats_init();
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
memb_init(&uip_ds6_nbr_memb);
|
||||
nbr_table_register(uip_ds6_nbr_entries,
|
||||
(nbr_table_callback *)callback_nbr_entry_removal);
|
||||
#else
|
||||
nbr_table_register(ds6_neighbors, (nbr_table_callback *)uip_ds6_nbr_rm);
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_nbr_t *
|
||||
|
@ -75,8 +123,63 @@ uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
|
|||
uint8_t isrouter, uint8_t state, nbr_table_reason_t reason,
|
||||
void *data)
|
||||
{
|
||||
uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr
|
||||
, reason, data);
|
||||
uip_ds6_nbr_t *nbr;
|
||||
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
uip_ds6_nbr_entry_t *nbr_entry;
|
||||
|
||||
assert(uip_ds6_nbr_lookup(ipaddr) == NULL);
|
||||
if(uip_ds6_nbr_lookup(ipaddr)) {
|
||||
LOG_ERR("%s: uip_ds6_nbr for ", __func__);
|
||||
LOG_ERR_6ADDR(ipaddr);
|
||||
LOG_ERR_("has already existed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* firstly, allocate memory for a new nbr cache entry */
|
||||
if((nbr = (uip_ds6_nbr_t *)memb_alloc(&uip_ds6_nbr_memb)) == NULL) {
|
||||
LOG_ERR("%s: cannot allocate a new uip_ds6_nbr\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* secondly, get or allocate nbr_entry for the link-layer address */
|
||||
nbr_entry = nbr_table_get_from_lladdr(uip_ds6_nbr_entries,
|
||||
(const linkaddr_t *)lladdr);
|
||||
if(nbr_entry == NULL) {
|
||||
if((nbr_entry =
|
||||
nbr_table_add_lladdr(uip_ds6_nbr_entries,
|
||||
(linkaddr_t*)lladdr, reason, data)) == NULL) {
|
||||
LOG_ERR("%s: cannot allocate a new uip_ds6_nbr_entry\n", __func__);
|
||||
/* return from this function later */
|
||||
} else {
|
||||
LIST_STRUCT_INIT(nbr_entry, uip_ds6_nbrs);
|
||||
}
|
||||
}
|
||||
|
||||
/* free nbr and return if nbr_entry is not available */
|
||||
if((nbr_entry == NULL) ||
|
||||
(list_length(nbr_entry->uip_ds6_nbrs) == UIP_DS6_NBR_MAX_6ADDRS_PER_NBR)) {
|
||||
if(list_length(nbr_entry->uip_ds6_nbrs) == UIP_DS6_NBR_MAX_6ADDRS_PER_NBR) {
|
||||
/*
|
||||
* it's already had the maximum number of IPv6 addresses; cannot
|
||||
* add another.
|
||||
*/
|
||||
LOG_ERR("%s: no room in nbr_entry for ", __func__);
|
||||
LOG_ERR_LLADDR((const linkaddr_t *)lladdr);
|
||||
LOG_ERR_("\n");
|
||||
}
|
||||
/* free the newly allocated memory in this function call */
|
||||
memb_free(&uip_ds6_nbr_memb, nbr);
|
||||
return NULL;
|
||||
} else {
|
||||
/* everything is fine; nbr is ready to be used */
|
||||
/* it has room to add another IPv6 address */
|
||||
add_uip_ds6_nbr_to_nbr_entry(nbr, nbr_entry);
|
||||
}
|
||||
#else
|
||||
nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr, reason, data);
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
|
||||
if(nbr) {
|
||||
uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
|
||||
#if UIP_ND6_SEND_RA || !UIP_CONF_ROUTER
|
||||
|
@ -113,10 +216,91 @@ uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
|
|||
}
|
||||
}
|
||||
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
add_uip_ds6_nbr_to_nbr_entry(uip_ds6_nbr_t *nbr,
|
||||
uip_ds6_nbr_entry_t *nbr_entry)
|
||||
{
|
||||
LOG_DBG("%s: add nbr(%p) to nbr_entry (%p)\n",
|
||||
__func__, nbr, nbr_entry);
|
||||
nbr->nbr_entry = nbr_entry;
|
||||
list_add(nbr_entry->uip_ds6_nbrs, nbr);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
remove_uip_ds6_nbr_from_nbr_entry(uip_ds6_nbr_t *nbr)
|
||||
{
|
||||
if(nbr == NULL) {
|
||||
return;
|
||||
}
|
||||
LOG_DBG("%s: remove nbr(%p) from nbr_entry (%p)\n",
|
||||
__func__, nbr, nbr->nbr_entry);
|
||||
list_remove(nbr->nbr_entry->uip_ds6_nbrs, nbr);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
remove_nbr_entry(uip_ds6_nbr_entry_t *nbr_entry)
|
||||
{
|
||||
if(nbr_entry == NULL) {
|
||||
return;
|
||||
}
|
||||
LOG_DBG("%s: remove nbr_entry (%p) from nbr_table\n",
|
||||
__func__, nbr_entry);
|
||||
(void)nbr_table_remove(uip_ds6_nbr_entries, nbr_entry);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
free_uip_ds6_nbr(uip_ds6_nbr_t *nbr)
|
||||
{
|
||||
if(nbr == NULL) {
|
||||
return;
|
||||
}
|
||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||
uip_packetqueue_free(&nbr->packethandle);
|
||||
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
|
||||
NETSTACK_ROUTING.neighbor_state_changed(nbr);
|
||||
assert(nbr->nbr_entry != NULL);
|
||||
if(nbr->nbr_entry == NULL) {
|
||||
LOG_ERR("%s: unexpected error nbr->nbr_entry is NULL\n", __func__);
|
||||
} else {
|
||||
remove_uip_ds6_nbr_from_nbr_entry(nbr);
|
||||
if(list_length(nbr->nbr_entry->uip_ds6_nbrs) == 0) {
|
||||
remove_nbr_entry(nbr->nbr_entry);
|
||||
}
|
||||
}
|
||||
LOG_DBG("%s: free memory for nbr(%p)\n", __func__, nbr);
|
||||
memb_free(&uip_ds6_nbr_memb, nbr);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
callback_nbr_entry_removal(uip_ds6_nbr_entry_t *nbr_entry)
|
||||
{
|
||||
uip_ds6_nbr_t *nbr;
|
||||
uip_ds6_nbr_t *next_nbr;
|
||||
if(nbr_entry == NULL) {
|
||||
return;
|
||||
}
|
||||
for(nbr = (uip_ds6_nbr_t *)list_head(nbr_entry->uip_ds6_nbrs);
|
||||
nbr != NULL;
|
||||
nbr = next_nbr) {
|
||||
next_nbr = (uip_ds6_nbr_t *)list_item_next(nbr);
|
||||
free_uip_ds6_nbr(nbr);
|
||||
}
|
||||
}
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
|
||||
{
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
if(nbr == NULL) {
|
||||
return 0;
|
||||
} else {
|
||||
free_uip_ds6_nbr(nbr);
|
||||
return 1;
|
||||
}
|
||||
#else /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
if(nbr != NULL) {
|
||||
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||
uip_packetqueue_free(&nbr->packethandle);
|
||||
|
@ -125,19 +309,52 @@ uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
|
|||
return nbr_table_remove(ds6_neighbors, nbr);
|
||||
}
|
||||
return 0;
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
uip_ds6_nbr_update_ll(uip_ds6_nbr_t **nbr_pp, const uip_lladdr_t *new_ll_addr)
|
||||
{
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
uip_ds6_nbr_entry_t *nbr_entry;
|
||||
uip_ds6_nbr_t *nbr;
|
||||
#else
|
||||
uip_ds6_nbr_t nbr_backup;
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
|
||||
if(nbr_pp == NULL || new_ll_addr == NULL) {
|
||||
LOG_ERR("%s: invalid argument\n", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
|
||||
if((nbr_entry =
|
||||
nbr_table_get_from_lladdr(uip_ds6_nbr_entries,
|
||||
(const linkaddr_t *)new_ll_addr)) == NULL) {
|
||||
if((nbr_entry =
|
||||
nbr_table_add_lladdr(uip_ds6_nbr_entries,
|
||||
(const linkaddr_t*)new_ll_addr,
|
||||
NBR_TABLE_REASON_IPV6_ND, NULL)) == NULL) {
|
||||
LOG_ERR("%s: cannot allocate a nbr_entry for", __func__);
|
||||
LOG_ERR_LLADDR((const linkaddr_t *)new_ll_addr);
|
||||
return -1;
|
||||
} else {
|
||||
LIST_STRUCT_INIT(nbr_entry, uip_ds6_nbrs);
|
||||
}
|
||||
}
|
||||
|
||||
nbr = *nbr_pp;
|
||||
|
||||
remove_uip_ds6_nbr_from_nbr_entry(nbr);
|
||||
if(list_length(nbr->nbr_entry->uip_ds6_nbrs) == 0) {
|
||||
remove_nbr_entry(nbr->nbr_entry);
|
||||
}
|
||||
add_uip_ds6_nbr_to_nbr_entry(nbr, nbr_entry);
|
||||
|
||||
#else /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
|
||||
/* make sure new_ll_addr is not used in some other nbr */
|
||||
if(uip_ds6_nbr_ll_lookup(new_ll_addr) != NULL) {
|
||||
LOG_ERR("%s: new_ll_addr, ", __func__);
|
||||
|
@ -159,6 +376,7 @@ uip_ds6_nbr_update_ll(uip_ds6_nbr_t **nbr_pp, const uip_lladdr_t *new_ll_addr)
|
|||
return -1;
|
||||
}
|
||||
memcpy(*nbr_pp, &nbr_backup, sizeof(uip_ds6_nbr_t));
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -173,46 +391,88 @@ uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr)
|
|||
const uip_lladdr_t *
|
||||
uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr)
|
||||
{
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
if(nbr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return (const uip_lladdr_t *)nbr_table_get_lladdr(uip_ds6_nbr_entries,
|
||||
nbr->nbr_entry);
|
||||
#else
|
||||
return (const uip_lladdr_t *)nbr_table_get_lladdr(ds6_neighbors, nbr);
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
uip_ds6_nbr_num(void)
|
||||
{
|
||||
uip_ds6_nbr_t *nbr;
|
||||
int num;
|
||||
int num = 0;
|
||||
|
||||
num = 0;
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
uip_ds6_nbr_entry_t *nbr_entry;
|
||||
for(nbr_entry = nbr_table_head(uip_ds6_nbr_entries);
|
||||
nbr_entry != NULL;
|
||||
nbr_entry = nbr_table_next(uip_ds6_nbr_entries, nbr_entry)) {
|
||||
num += list_length(nbr_entry->uip_ds6_nbrs);
|
||||
}
|
||||
#else
|
||||
uip_ds6_nbr_t *nbr;
|
||||
for(nbr = nbr_table_head(ds6_neighbors);
|
||||
nbr != NULL;
|
||||
nbr = nbr_table_next(ds6_neighbors, nbr)) {
|
||||
num++;
|
||||
}
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
return num;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_nbr_t *
|
||||
uip_ds6_nbr_head(void)
|
||||
{
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
uip_ds6_nbr_entry_t *nbr_entry;
|
||||
if((nbr_entry = nbr_table_head(uip_ds6_nbr_entries)) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
assert(list_head(nbr_entry->uip_ds6_nbrs) != NULL);
|
||||
return (uip_ds6_nbr_t *)list_head(nbr_entry->uip_ds6_nbrs);
|
||||
#else
|
||||
return nbr_table_head(ds6_neighbors);
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_nbr_t *
|
||||
uip_ds6_nbr_next(uip_ds6_nbr_t *nbr)
|
||||
{
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
uip_ds6_nbr_entry_t *nbr_entry;
|
||||
if(nbr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if(list_item_next(nbr) != NULL) {
|
||||
return list_item_next(nbr);
|
||||
}
|
||||
nbr_entry = nbr_table_next(uip_ds6_nbr_entries, nbr->nbr_entry);
|
||||
if(nbr_entry == NULL) {
|
||||
return NULL;
|
||||
} else {
|
||||
assert(list_head(nbr_entry->uip_ds6_nbrs) != NULL);
|
||||
return (uip_ds6_nbr_t *)list_head(nbr_entry->uip_ds6_nbrs);
|
||||
}
|
||||
#else
|
||||
return nbr_table_next(ds6_neighbors, nbr);
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uip_ds6_nbr_t *
|
||||
uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
||||
if(ipaddr != NULL) {
|
||||
while(nbr != NULL) {
|
||||
if(uip_ipaddr_cmp(&nbr->ipaddr, ipaddr)) {
|
||||
return nbr;
|
||||
}
|
||||
nbr = nbr_table_next(ds6_neighbors, nbr);
|
||||
uip_ds6_nbr_t *nbr;
|
||||
if(ipaddr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
for(nbr = uip_ds6_nbr_head(); nbr != NULL; nbr = uip_ds6_nbr_next(nbr)) {
|
||||
if(uip_ipaddr_cmp(&nbr->ipaddr, ipaddr)) {
|
||||
return nbr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
@ -221,7 +481,23 @@ uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr)
|
|||
uip_ds6_nbr_t *
|
||||
uip_ds6_nbr_ll_lookup(const uip_lladdr_t *lladdr)
|
||||
{
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
uip_ds6_nbr_entry_t *nbr_entry;
|
||||
/*
|
||||
* we cannot determine which entry should return by lladdr alone;
|
||||
* return the first entry associated with lladdr.
|
||||
*/
|
||||
nbr_entry =
|
||||
(uip_ds6_nbr_entry_t *)nbr_table_get_from_lladdr(uip_ds6_nbr_entries,
|
||||
(linkaddr_t*)lladdr);
|
||||
if(nbr_entry == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
assert(list_head(nbr_entry->uip_ds6_nbrs) != NULL);
|
||||
return (uip_ds6_nbr_t *)list_head(nbr_entry->uip_ds6_nbrs);
|
||||
#else
|
||||
return nbr_table_get_from_lladdr(ds6_neighbors, (linkaddr_t*)lladdr);
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -239,6 +515,20 @@ uip_ds6_nbr_lladdr_from_ipaddr(const uip_ipaddr_t *ipaddr)
|
|||
uip_ds6_nbr_t *nbr = uip_ds6_nbr_lookup(ipaddr);
|
||||
return nbr ? uip_ds6_nbr_get_ll(nbr) : NULL;
|
||||
}
|
||||
#if UIP_DS6_LL_NUD
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
update_nbr_reachable_state_by_ack(uip_ds6_nbr_t *nbr, const linkaddr_t *lladdr)
|
||||
{
|
||||
if(nbr != NULL && nbr->state != NBR_INCOMPLETE) {
|
||||
nbr->state = NBR_REACHABLE;
|
||||
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
||||
LOG_INFO("received a link layer ACK : ");
|
||||
LOG_INFO_LLADDR(lladdr);
|
||||
LOG_INFO_(" is reachable.\n");
|
||||
}
|
||||
}
|
||||
#endif /* UIP_DS6_LL_NUD */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_ds6_link_callback(int status, int numtx)
|
||||
|
@ -266,14 +556,22 @@ uip_ds6_link_callback(int status, int numtx)
|
|||
* acknowledges link packets. */
|
||||
if(status == MAC_TX_OK) {
|
||||
uip_ds6_nbr_t *nbr;
|
||||
nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
|
||||
if(nbr != NULL && nbr->state != NBR_INCOMPLETE) {
|
||||
nbr->state = NBR_REACHABLE;
|
||||
stimer_set(&nbr->reachable, UIP_ND6_REACHABLE_TIME / 1000);
|
||||
LOG_INFO("received a link layer ACK : ");
|
||||
LOG_INFO_LLADDR((uip_lladdr_t *)dest);
|
||||
LOG_INFO_(" is reachable.\n");
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
uip_ds6_nbr_entry_t *nbr_entry;
|
||||
if((nbr_entry =
|
||||
(uip_ds6_nbr_entry_t *)nbr_table_get_from_lladdr(uip_ds6_nbr_entries,
|
||||
dest)) == NULL) {
|
||||
return;
|
||||
}
|
||||
for(nbr = (uip_ds6_nbr_t *)list_head(nbr_entry->uip_ds6_nbrs);
|
||||
nbr != NULL;
|
||||
nbr = (uip_ds6_nbr_t *)list_item_next(nbr)) {
|
||||
update_nbr_reachable_state_by_ack(nbr, dest);
|
||||
}
|
||||
#else /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
nbr = uip_ds6_nbr_ll_lookup((uip_lladdr_t *)dest);
|
||||
update_nbr_reachable_state_by_ack(nbr, dest);
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
}
|
||||
#endif /* UIP_DS6_LL_NUD */
|
||||
}
|
||||
|
@ -283,7 +581,7 @@ uip_ds6_link_callback(int status, int numtx)
|
|||
void
|
||||
uip_ds6_neighbor_periodic(void)
|
||||
{
|
||||
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
||||
uip_ds6_nbr_t *nbr = uip_ds6_nbr_head();
|
||||
while(nbr != NULL) {
|
||||
switch(nbr->state) {
|
||||
case NBR_REACHABLE:
|
||||
|
@ -354,7 +652,7 @@ uip_ds6_neighbor_periodic(void)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
nbr = nbr_table_next(ds6_neighbors, nbr);
|
||||
nbr = uip_ds6_nbr_next(nbr);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -373,7 +671,7 @@ uip_ds6_nbr_refresh_reachable_state(const uip_ipaddr_t *ipaddr)
|
|||
uip_ds6_nbr_t *
|
||||
uip_ds6_get_least_lifetime_neighbor(void)
|
||||
{
|
||||
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
|
||||
uip_ds6_nbr_t *nbr = uip_ds6_nbr_head();
|
||||
uip_ds6_nbr_t *nbr_expiring = NULL;
|
||||
while(nbr != NULL) {
|
||||
if(nbr_expiring != NULL) {
|
||||
|
@ -384,7 +682,7 @@ uip_ds6_get_least_lifetime_neighbor(void)
|
|||
} else {
|
||||
nbr_expiring = nbr;
|
||||
}
|
||||
nbr = nbr_table_next(ds6_neighbors, nbr);
|
||||
nbr = uip_ds6_nbr_next(nbr);
|
||||
}
|
||||
return nbr_expiring;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,10 @@
|
|||
#if UIP_CONF_IPV6_QUEUE_PKT
|
||||
#include "net/ipv6/uip-packetqueue.h"
|
||||
#endif /*UIP_CONF_QUEUE_PKT */
|
||||
#if UIP_DS6_NBR_CONF_MULTI_IPV6_ADDRS
|
||||
#include "lib/assert.h"
|
||||
#include "lib/list.h"
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------*/
|
||||
/** \brief Possible states for the nbr cache entries */
|
||||
|
@ -63,10 +67,46 @@
|
|||
#define NBR_DELAY 3
|
||||
#define NBR_PROBE 4
|
||||
|
||||
NBR_TABLE_DECLARE(ds6_neighbors);
|
||||
/** \brief Set non-zero (1) to enable multiple IPv6 addresses to be
|
||||
* associated with a link-layer address */
|
||||
#ifdef UIP_DS6_NBR_CONF_MULTI_IPV6_ADDRS
|
||||
#define UIP_DS6_NBR_MULTI_IPV6_ADDRS UIP_DS6_NBR_CONF_MULTI_IPV6_ADDRS
|
||||
#else
|
||||
#define UIP_DS6_NBR_MULTI_IPV6_ADDRS 0
|
||||
#endif /* UIP_DS6_NBR_CONF_MULTI_IPV6_ADDRS */
|
||||
|
||||
/** \brief An entry in the nbr cache */
|
||||
/** \brief Set the maximum number of IPv6 addresses per link-layer
|
||||
* address */
|
||||
#ifdef UIP_DS6_NBR_CONF_MAX_6ADDRS_PER_NBR
|
||||
#define UIP_DS6_NBR_MAX_6ADDRS_PER_NBR UIP_DS6_NBR_CONF_MAX_6ADDRS_PER_NBR
|
||||
#else
|
||||
#define UIP_DS6_NBR_MAX_6ADDRS_PER_NBR 2
|
||||
#endif /* UIP_DS6_NBR_CONF_MAX_6ADDRS_PER_NBR */
|
||||
|
||||
/** \brief Set the maximum number of neighbor cache entries */
|
||||
#ifdef UIP_DS6_NBR_CONF_MAX_NEIGHBOR_CACHES
|
||||
#define UIP_DS6_NBR_MAX_NEIGHBOR_CACHES UIP_DS6_NBR_CONF_MAX_NEIGHBOR_CACHES
|
||||
#else
|
||||
#define UIP_DS6_NBR_MAX_NEIGHBOR_CACHES \
|
||||
(NBR_TABLE_MAX_NEIGHBORS * UIP_DS6_NBR_MAX_6ADDRS_PER_NBR)
|
||||
#endif /* UIP_DS6_NBR_CONF_MAX_NEIGHBOR_CACHES */
|
||||
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
/** \brief nbr_table entry when UIP_DS6_NBR_MULTI_IPV6_ADDRS is
|
||||
* enabled. uip_ds6_nbrs is a list of uip_ds6_nbr_t objects */
|
||||
typedef struct {
|
||||
LIST_STRUCT(uip_ds6_nbrs);
|
||||
} uip_ds6_nbr_entry_t;
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
|
||||
/** \brief The default nbr_table entry (when
|
||||
* UIP_DS6_NBR_MULTI_IPV6_ADDRS is disabled), that implements nbr
|
||||
* cache */
|
||||
typedef struct uip_ds6_nbr {
|
||||
#if UIP_DS6_NBR_MULTI_IPV6_ADDRS
|
||||
struct uip_ds6_nbr *next;
|
||||
uip_ds6_nbr_entry_t *nbr_entry;
|
||||
#endif /* UIP_DS6_NBR_MULTI_IPV6_ADDRS */
|
||||
uip_ipaddr_t ipaddr;
|
||||
uint8_t isrouter;
|
||||
uint8_t state;
|
||||
|
@ -83,25 +123,119 @@ typedef struct uip_ds6_nbr {
|
|||
|
||||
void uip_ds6_neighbors_init(void);
|
||||
|
||||
/** \brief Neighbor Cache basic routines */
|
||||
/**
|
||||
* Add a neighbor cache for a specified IPv6 address, which is
|
||||
* associated with a specified link-layer address
|
||||
* \param ipaddr IPv6 address of a neighbor to add
|
||||
* \param lladdr Link-layer address to associate with ipaddr
|
||||
* \param isrouter Set 1 if the neighbor is a router
|
||||
* \param state Set the initial neighbor cache state (e.g.,
|
||||
* NBR_INCOMPLETE)
|
||||
* \param reason Set a reason of the addition (e.g.,
|
||||
* NBR_TABLE_REASON_RPL_DIO)
|
||||
* \param data Set data associated with the nbr cache
|
||||
* \return the address of a newly added nbr cache on success, NULL on
|
||||
* failure
|
||||
*/
|
||||
uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr,
|
||||
const uip_lladdr_t *lladdr,
|
||||
uint8_t isrouter, uint8_t state,
|
||||
nbr_table_reason_t reason, void *data);
|
||||
|
||||
/**
|
||||
* Remove a neighbor cache
|
||||
* \param nbr the address of a neighbor cache to remove
|
||||
* \return 1 on success, 0 on failure (nothing was removed)
|
||||
*/
|
||||
int uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr);
|
||||
|
||||
/**
|
||||
* Get the link-layer address associated with a specified nbr cache
|
||||
* \param nbr the address of a neighbor cache
|
||||
* \return pointer to the link-layer address on success, NULL on failure
|
||||
*/
|
||||
const uip_lladdr_t *uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr);
|
||||
int uip_ds6_nbr_update_ll(uip_ds6_nbr_t **nbr, const uip_lladdr_t *new_ll_addr);
|
||||
const uip_ipaddr_t *uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr);
|
||||
uip_ds6_nbr_t *uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr);
|
||||
uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(const uip_lladdr_t *lladdr);
|
||||
uip_ipaddr_t *uip_ds6_nbr_ipaddr_from_lladdr(const uip_lladdr_t *lladdr);
|
||||
|
||||
/**
|
||||
* Get the link-layer address associated with a specified IPv6 address
|
||||
* \param ipaddr an IPv6 address used as a search key
|
||||
* \return the pointer to the link-layer address on success, NULL on failure
|
||||
*/
|
||||
const uip_lladdr_t *uip_ds6_nbr_lladdr_from_ipaddr(const uip_ipaddr_t *ipaddr);
|
||||
void uip_ds6_link_callback(int status, int numtx);
|
||||
void uip_ds6_neighbor_periodic(void);
|
||||
|
||||
/**
|
||||
* Update the link-layer address associated with an IPv6 address
|
||||
* \param nbr the double pointer to a neighbor cache which has the
|
||||
* target IPv6 address
|
||||
* \param new_ll_addr the new link-layer address of the IPv6 address
|
||||
* return 0 on success, -1 on failure
|
||||
*/
|
||||
int uip_ds6_nbr_update_ll(uip_ds6_nbr_t **nbr, const uip_lladdr_t *new_ll_addr);
|
||||
|
||||
/**
|
||||
* Get an IPv6 address of a neighbor cache
|
||||
* \param nbr the pointer to a neighbor cache
|
||||
* \return the pointer to an IPv6 address associated with the neighbor cache
|
||||
* \note This returns the first IPv6 address found in the neighbor
|
||||
* cache when UIP_DS6_NBR_MULTI_IPV6_ADDRS is enabled
|
||||
*/
|
||||
const uip_ipaddr_t *uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr);
|
||||
|
||||
/**
|
||||
* Get an IPv6 address associated with a specified link-layer address
|
||||
* \param lladdr a link-layer address used as a search key
|
||||
* \return the pointer to an IPv6 address associated with the neighbor cache
|
||||
* \note This returns the first IPv6 address found in the neighbor
|
||||
* cache when UIP_DS6_NBR_MULTI_IPV6_ADDRS is enabled
|
||||
*/
|
||||
uip_ipaddr_t *uip_ds6_nbr_ipaddr_from_lladdr(const uip_lladdr_t *lladdr);
|
||||
|
||||
/**
|
||||
* Get the neighbor cache associated with a specified IPv6 address
|
||||
* \param ipaddr an IPv6 address used as a search key
|
||||
* \return the pointer to a neighbor cache on success, NULL on failure
|
||||
*/
|
||||
uip_ds6_nbr_t *uip_ds6_nbr_lookup(const uip_ipaddr_t *ipaddr);
|
||||
|
||||
/**
|
||||
* Get the neighbor cache associated with a specified link-layer address
|
||||
* \param lladdr a link-layer address used as a search key
|
||||
* \return the pointer to a neighbor cache on success, NULL on failure
|
||||
*/
|
||||
uip_ds6_nbr_t *uip_ds6_nbr_ll_lookup(const uip_lladdr_t *lladdr);
|
||||
|
||||
/**
|
||||
* Return the number of neighbor caches
|
||||
* \return the number of neighbor caches in use
|
||||
*/
|
||||
int uip_ds6_nbr_num(void);
|
||||
|
||||
/**
|
||||
* Get the first neighbor cache in nbr_table
|
||||
* \return the pointer to the first neighbor cache entry
|
||||
*/
|
||||
uip_ds6_nbr_t *uip_ds6_nbr_head(void);
|
||||
|
||||
/**
|
||||
* Get the next neighbor cache of a specified one
|
||||
* \param nbr the pointer to a neighbor cache
|
||||
* \return the pointer to the next one on success, NULL on failure
|
||||
*/
|
||||
uip_ds6_nbr_t *uip_ds6_nbr_next(uip_ds6_nbr_t *nbr);
|
||||
|
||||
/**
|
||||
* The callback function to update link-layer stats in a neighbor
|
||||
* cache
|
||||
* \param status MAC return value defined in mac.h
|
||||
* \param numtx the number of transmissions happened for a packet
|
||||
*/
|
||||
void uip_ds6_link_callback(int status, int numtx);
|
||||
|
||||
/**
|
||||
* The housekeeping function called periodically
|
||||
*/
|
||||
void uip_ds6_neighbor_periodic(void);
|
||||
|
||||
#if UIP_ND6_SEND_NS
|
||||
/**
|
||||
* \brief Refresh the reachable state of a neighbor. This function
|
||||
|
|
|
@ -53,11 +53,7 @@
|
|||
#define LOG_MODULE "ICMPv6"
|
||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_FIRST_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[UIP_LLIPH_LEN])
|
||||
#define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)UIP_ICMP_PAYLOAD)
|
||||
|
||||
/** \brief temporary IP address */
|
||||
static uip_ipaddr_t tmp_ipaddr;
|
||||
|
@ -134,22 +130,7 @@ echo_request_input(void)
|
|||
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &tmp_ipaddr);
|
||||
}
|
||||
|
||||
if(uip_ext_len > 0) {
|
||||
/* Remove extension headers if any */
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
uip_len -= uip_ext_len;
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
/* move the echo request payload (starting after the icmp header)
|
||||
* to the new location in the reply.
|
||||
* The shift is equal to the length of the extension headers present
|
||||
* Note: UIP_ICMP_BUF still points to the echo request at this stage
|
||||
*/
|
||||
memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - uip_ext_len,
|
||||
(uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN,
|
||||
(uip_len - UIP_IPH_LEN - UIP_ICMPH_LEN));
|
||||
uip_ext_len = 0;
|
||||
}
|
||||
uip_remove_ext_hdr();
|
||||
|
||||
/* Below is important for the correctness of UIP_ICMP_BUF and the
|
||||
* checksum
|
||||
|
@ -173,47 +154,38 @@ echo_request_input(void)
|
|||
void
|
||||
uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
||||
/* check if originating packet is not an ICMP error */
|
||||
if(uip_ext_len) {
|
||||
if(UIP_EXT_BUF->next == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128) {
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128) {
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
uint16_t shift;
|
||||
if(uip_last_proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128) {
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove all extension headers related to the routing protocol in place */
|
||||
/* Remove all extension headers related to the routing protocol in place.
|
||||
* Keep all other extension headers, so as to match original packet. */
|
||||
NETSTACK_ROUTING.ext_header_remove();
|
||||
|
||||
/* remember data of original packet before shifting */
|
||||
uip_ipaddr_copy(&tmp_ipaddr, &UIP_IP_BUF->destipaddr);
|
||||
|
||||
uip_len += UIP_IPICMPH_LEN + UIP_ICMP6_ERROR_LEN;
|
||||
|
||||
if(uip_len > UIP_LINK_MTU) {
|
||||
uip_len = UIP_LINK_MTU;
|
||||
}
|
||||
|
||||
memmove((uint8_t *)UIP_ICMP6_ERROR_BUF + uip_ext_len + UIP_ICMP6_ERROR_LEN,
|
||||
(void *)UIP_IP_BUF, uip_len - UIP_IPICMPH_LEN - uip_ext_len - UIP_ICMP6_ERROR_LEN);
|
||||
/* The ICMPv6 error message contains as much of possible of the invoking packet
|
||||
* (see RFC 4443 section 3). Make space for the additional IPv6 and
|
||||
* ICMPv6 headers here and move payload to the "right". What we move includes
|
||||
* extension headers */
|
||||
shift = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ICMP6_ERROR_LEN;
|
||||
uip_len += shift;
|
||||
uip_len = MIN(uip_len, UIP_LINK_MTU);
|
||||
memmove(uip_buf + shift, (void *)UIP_IP_BUF, uip_len - shift);
|
||||
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
UIP_IP_BUF->tcflow = 0;
|
||||
UIP_IP_BUF->flow = 0;
|
||||
if (uip_ext_len) {
|
||||
UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6;
|
||||
} else {
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
}
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
|
||||
|
||||
/* the source should not be unspecified nor multicast, the check for
|
||||
multicast is done in uip_process */
|
||||
if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)){
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -223,7 +195,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
|||
if(type == ICMP6_PARAM_PROB && code == ICMP6_PARAMPROB_OPTION){
|
||||
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr);
|
||||
} else {
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -234,8 +206,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
|||
UIP_ICMP_BUF->type = type;
|
||||
UIP_ICMP_BUF->icode = code;
|
||||
UIP_ICMP6_ERROR_BUF->param = uip_htonl(param);
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
UIP_ICMP_BUF->icmpchksum = 0;
|
||||
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
|
||||
|
||||
|
@ -258,8 +229,7 @@ uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
|
|||
UIP_IP_BUF->flow = 0;
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
|
||||
UIP_IP_BUF->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8;
|
||||
UIP_IP_BUF->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + payload_len);
|
||||
|
||||
memcpy(&UIP_IP_BUF->destipaddr, dest, sizeof(*dest));
|
||||
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
|
||||
|
@ -297,22 +267,7 @@ echo_reply_input(void)
|
|||
uip_ipaddr_copy(&sender, &UIP_IP_BUF->srcipaddr);
|
||||
ttl = UIP_IP_BUF->ttl;
|
||||
|
||||
if(uip_ext_len > 0) {
|
||||
/* Remove extension headers if any */
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
uip_len -= uip_ext_len;
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
/* move the echo reply payload (starting after the icmp header)
|
||||
* to the new location in the reply. The shift is equal to the
|
||||
* length of the extension headers present Note: UIP_ICMP_BUF
|
||||
* still points to the echo request at this stage
|
||||
*/
|
||||
memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - uip_ext_len,
|
||||
(uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN,
|
||||
(uip_len - UIP_IPH_LEN - UIP_ICMPH_LEN));
|
||||
uip_ext_len = 0;
|
||||
}
|
||||
uip_remove_ext_hdr();
|
||||
|
||||
/* Call all registered applications to let them know an echo reply
|
||||
has been received. */
|
||||
|
@ -329,7 +284,7 @@ echo_reply_input(void)
|
|||
}
|
||||
}
|
||||
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
/**
|
||||
* \file
|
||||
* Header file for ICMPv6 message and error handing (RFC 4443)
|
||||
* \author Julien Abeille <jabeille@cisco.com>
|
||||
* \author Julien Abeille <jabeille@cisco.com>
|
||||
* \author Mathilde Durvy <mdurvy@cisco.com>
|
||||
*/
|
||||
|
||||
|
@ -52,8 +52,8 @@
|
|||
/** @{ */
|
||||
#define ICMP6_DST_UNREACH 1 /**< dest unreachable */
|
||||
#define ICMP6_PACKET_TOO_BIG 2 /**< packet too big */
|
||||
#define ICMP6_TIME_EXCEEDED 3 /**< time exceeded */
|
||||
#define ICMP6_PARAM_PROB 4 /**< ip6 header bad */
|
||||
#define ICMP6_TIME_EXCEEDED 3 /**< time exceeded */
|
||||
#define ICMP6_PARAM_PROB 4 /**< ip6 header bad */
|
||||
#define ICMP6_ECHO_REQUEST 128 /**< Echo request */
|
||||
#define ICMP6_ECHO_REPLY 129 /**< Echo reply */
|
||||
|
||||
|
@ -76,10 +76,10 @@
|
|||
/** \name ICMPv6 Destination Unreachable message codes*/
|
||||
/** @{ */
|
||||
#define ICMP6_DST_UNREACH_NOROUTE 0 /**< no route to destination */
|
||||
#define ICMP6_DST_UNREACH_ADMIN 1 /**< administratively prohibited */
|
||||
#define ICMP6_DST_UNREACH_ADMIN 1 /**< administratively prohibited */
|
||||
#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /**< not a neighbor(obsolete) */
|
||||
#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /**< beyond scope of source address */
|
||||
#define ICMP6_DST_UNREACH_ADDR 3 /**< address unreachable */
|
||||
#define ICMP6_DST_UNREACH_ADDR 3 /**< address unreachable */
|
||||
#define ICMP6_DST_UNREACH_NOPORT 4 /**< port unreachable */
|
||||
/** @} */
|
||||
|
||||
|
@ -116,7 +116,7 @@ typedef struct uip_icmp6_error{
|
|||
* \param param 32 bit parameter of the error message, semantic depends on error
|
||||
*/
|
||||
void
|
||||
uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param);
|
||||
uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param);
|
||||
|
||||
/**
|
||||
* \brief Send an icmpv6 message
|
||||
|
|
|
@ -108,7 +108,7 @@ uip_nameserver_update(const uip_ipaddr_t *nameserver, uint32_t lifetime)
|
|||
* the the eldest ones */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(e == NULL) {
|
||||
if((e = memb_alloc(&dnsmemb)) != NULL) {
|
||||
list_add(dns, e);
|
||||
|
@ -221,11 +221,7 @@ uip_nameserver_count(void)
|
|||
}
|
||||
return list_length(dns);
|
||||
#else /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
if(uip_is_addr_unspecified(&serveraddr)) {
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
if(uip_ipaddr_cmp(&serveraddr, &uip_all_zeroes_addr)) {
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
|
|
|
@ -84,29 +84,20 @@
|
|||
/*------------------------------------------------------------------*/
|
||||
/** @{ */
|
||||
/** \name Pointers to the header structures.
|
||||
* All pointers except UIP_IP_BUF depend on uip_ext_len, which at
|
||||
* packet reception, is the total length of the extension headers.
|
||||
*
|
||||
* The pointer to ND6 options header also depends on nd6_opt_offset,
|
||||
* which we set in each function.
|
||||
*
|
||||
* Care should be taken when manipulating these buffers about the
|
||||
* value of these length variables
|
||||
*/
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) /**< Pointer to IP header */
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) /**< Pointer to ICMP header*/
|
||||
/**@{ Pointers to messages just after icmp header */
|
||||
#define UIP_ND6_RS_BUF ((uip_nd6_rs *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_ND6_RA_BUF ((uip_nd6_ra *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_ND6_NS_BUF ((uip_nd6_ns *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_ND6_NA_BUF ((uip_nd6_na *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_ND6_RS_BUF ((uip_nd6_rs *)UIP_ICMP_PAYLOAD)
|
||||
#define UIP_ND6_RA_BUF ((uip_nd6_ra *)UIP_ICMP_PAYLOAD)
|
||||
#define UIP_ND6_NS_BUF ((uip_nd6_ns *)UIP_ICMP_PAYLOAD)
|
||||
#define UIP_ND6_NA_BUF ((uip_nd6_na *)UIP_ICMP_PAYLOAD)
|
||||
/** @} */
|
||||
/** Pointer to ND option */
|
||||
#define UIP_ND6_OPT_HDR_BUF ((uip_nd6_opt_hdr *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||
#define UIP_ND6_OPT_PREFIX_BUF ((uip_nd6_opt_prefix_info *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||
#define UIP_ND6_OPT_MTU_BUF ((uip_nd6_opt_mtu *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||
#define UIP_ND6_OPT_RDNSS_BUF ((uip_nd6_opt_dns *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||
#define ND6_OPT(opt) ((unsigned char *)(UIP_ICMP_PAYLOAD + (opt)))
|
||||
#define ND6_OPT_HDR_BUF(opt) ((uip_nd6_opt_hdr *)ND6_OPT(opt))
|
||||
#define ND6_OPT_PREFIX_BUF(opt) ((uip_nd6_opt_prefix_info *)ND6_OPT(opt))
|
||||
#define ND6_OPT_MTU_BUF(opt) ((uip_nd6_opt_mtu *)ND6_OPT(opt))
|
||||
#define ND6_OPT_RDNSS_BUF(opt) ((uip_nd6_opt_dns *)ND6_OPT(opt))
|
||||
/** @} */
|
||||
|
||||
#if UIP_ND6_SEND_NS || UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER
|
||||
|
@ -203,14 +194,14 @@ ns_input(void)
|
|||
nd6_opt_offset = UIP_ND6_NS_LEN;
|
||||
while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
if(UIP_ND6_OPT_HDR_BUF->len == 0) {
|
||||
if(ND6_OPT_HDR_BUF(nd6_opt_offset)->len == 0) {
|
||||
LOG_ERR("NS received is bad\n");
|
||||
goto discard;
|
||||
}
|
||||
#endif /* UIP_CONF_IPV6_CHECKS */
|
||||
switch (UIP_ND6_OPT_HDR_BUF->type) {
|
||||
switch (ND6_OPT_HDR_BUF(nd6_opt_offset)->type) {
|
||||
case UIP_ND6_OPT_SLLAO:
|
||||
nd6_opt_llao = &uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset];
|
||||
nd6_opt_llao = &uip_buf[uip_l3_icmp_hdr_len + nd6_opt_offset];
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
/* There must be NO option in a DAD NS */
|
||||
if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
|
||||
|
@ -252,7 +243,7 @@ ns_input(void)
|
|||
LOG_WARN("ND option not supported in NS");
|
||||
break;
|
||||
}
|
||||
nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3);
|
||||
nd6_opt_offset += (ND6_OPT_HDR_BUF(nd6_opt_offset)->len << 3);
|
||||
}
|
||||
|
||||
addr = uip_ds6_addr_lookup(&UIP_ND6_NS_BUF->tgtipaddr);
|
||||
|
@ -323,12 +314,11 @@ create_na:
|
|||
#if UIP_CONF_ROUTER
|
||||
flags = flags | UIP_ND6_NA_FLAG_ROUTER;
|
||||
#endif
|
||||
uip_ext_len = 0;
|
||||
uipbuf_clear();
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
UIP_IP_BUF->tcflow = 0;
|
||||
UIP_IP_BUF->flow = 0;
|
||||
UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */
|
||||
UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN);
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT;
|
||||
|
||||
|
@ -338,14 +328,13 @@ create_na:
|
|||
UIP_ND6_NA_BUF->flagsreserved = flags;
|
||||
memcpy(&UIP_ND6_NA_BUF->tgtipaddr, &addr->ipaddr, sizeof(uip_ipaddr_t));
|
||||
|
||||
create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NA_LEN],
|
||||
create_llao(&uip_buf[uip_l3_icmp_hdr_len + UIP_ND6_NA_LEN],
|
||||
UIP_ND6_OPT_TLLAO);
|
||||
|
||||
UIP_ICMP_BUF->icmpchksum = 0;
|
||||
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
|
||||
|
||||
uip_len =
|
||||
UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN;
|
||||
uipbuf_set_len(UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN);
|
||||
|
||||
UIP_STAT(++uip_stat.nd6.sent);
|
||||
LOG_INFO("Sending NA to ");
|
||||
|
@ -358,7 +347,7 @@ create_na:
|
|||
return;
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
#endif /* UIP_ND6_SEND_NA */
|
||||
|
@ -369,7 +358,7 @@ discard:
|
|||
void
|
||||
uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt)
|
||||
{
|
||||
uip_ext_len = 0;
|
||||
uipbuf_clear();
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
UIP_IP_BUF->tcflow = 0;
|
||||
UIP_IP_BUF->flow = 0;
|
||||
|
@ -385,7 +374,6 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt)
|
|||
UIP_ICMP_BUF->icode = 0;
|
||||
UIP_ND6_NS_BUF->reserved = 0;
|
||||
uip_ipaddr_copy((uip_ipaddr_t *) &UIP_ND6_NS_BUF->tgtipaddr, tgt);
|
||||
UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */
|
||||
/*
|
||||
* check if we add a SLLAO option: for DAD, MUST NOT, for NUD, MAY
|
||||
* (here yes), for Address resolution , MUST
|
||||
|
@ -398,13 +386,12 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt)
|
|||
}
|
||||
if (uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
|
||||
LOG_ERR("Dropping NS due to no suitable source address\n");
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
UIP_IP_BUF->len[1] =
|
||||
UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN);
|
||||
|
||||
create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NS_LEN],
|
||||
create_llao(&uip_buf[uip_l3_icmp_hdr_len + UIP_ND6_NS_LEN],
|
||||
UIP_ND6_OPT_SLLAO);
|
||||
|
||||
uip_len =
|
||||
|
@ -493,20 +480,20 @@ na_input(void)
|
|||
nd6_opt_llao = NULL;
|
||||
while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
if(UIP_ND6_OPT_HDR_BUF->len == 0) {
|
||||
if(ND6_OPT_HDR_BUF(nd6_opt_offset)->len == 0) {
|
||||
LOG_ERR("NA received is bad\n");
|
||||
goto discard;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS */
|
||||
switch (UIP_ND6_OPT_HDR_BUF->type) {
|
||||
switch (ND6_OPT_HDR_BUF(nd6_opt_offset)->type) {
|
||||
case UIP_ND6_OPT_TLLAO:
|
||||
nd6_opt_llao = (uint8_t *)UIP_ND6_OPT_HDR_BUF;
|
||||
nd6_opt_llao = (uint8_t *)ND6_OPT_HDR_BUF(nd6_opt_offset);
|
||||
break;
|
||||
default:
|
||||
LOG_WARN("ND option not supported in NA\n");
|
||||
break;
|
||||
}
|
||||
nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3);
|
||||
nd6_opt_offset += (ND6_OPT_HDR_BUF(nd6_opt_offset)->len << 3);
|
||||
}
|
||||
addr = uip_ds6_addr_lookup(&UIP_ND6_NA_BUF->tgtipaddr);
|
||||
/* Message processing, including TLLAO if any */
|
||||
|
@ -605,7 +592,7 @@ na_input(void)
|
|||
#endif /*UIP_CONF_IPV6_QUEUE_PKT */
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
#endif /* UIP_ND6_SEND_NS */
|
||||
|
@ -644,20 +631,20 @@ rs_input(void)
|
|||
|
||||
while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
if(UIP_ND6_OPT_HDR_BUF->len == 0) {
|
||||
if(ND6_OPT_HDR_BUF(nd6_opt_offset)->len == 0) {
|
||||
LOG_ERR("RS received is bad\n");
|
||||
goto discard;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS */
|
||||
switch (UIP_ND6_OPT_HDR_BUF->type) {
|
||||
switch (ND6_OPT_HDR_BUF(nd6_opt_offset)->type) {
|
||||
case UIP_ND6_OPT_SLLAO:
|
||||
nd6_opt_llao = (uint8_t *)UIP_ND6_OPT_HDR_BUF;
|
||||
nd6_opt_llao = (uint8_t *)ND6_OPT_HDR_BUF(nd6_opt_offset);
|
||||
break;
|
||||
default:
|
||||
LOG_WARN("ND option not supported in RS\n");
|
||||
break;
|
||||
}
|
||||
nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3);
|
||||
nd6_opt_offset += (ND6_OPT_HDR_BUF(nd6_opt_offset)->len << 3);
|
||||
}
|
||||
/* Options processing: only SLLAO */
|
||||
if(nd6_opt_llao != NULL) {
|
||||
|
@ -701,7 +688,7 @@ rs_input(void)
|
|||
uip_ds6_send_ra_sollicited();
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -746,31 +733,31 @@ uip_nd6_ra_output(uip_ipaddr_t * dest)
|
|||
for(prefix = uip_ds6_prefix_list;
|
||||
prefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; prefix++) {
|
||||
if((prefix->isused) && (prefix->advertise)) {
|
||||
UIP_ND6_OPT_PREFIX_BUF->type = UIP_ND6_OPT_PREFIX_INFO;
|
||||
UIP_ND6_OPT_PREFIX_BUF->len = UIP_ND6_OPT_PREFIX_INFO_LEN / 8;
|
||||
UIP_ND6_OPT_PREFIX_BUF->preflen = prefix->length;
|
||||
UIP_ND6_OPT_PREFIX_BUF->flagsreserved1 = prefix->l_a_reserved;
|
||||
UIP_ND6_OPT_PREFIX_BUF->validlt = uip_htonl(prefix->vlifetime);
|
||||
UIP_ND6_OPT_PREFIX_BUF->preferredlt = uip_htonl(prefix->plifetime);
|
||||
UIP_ND6_OPT_PREFIX_BUF->reserved2 = 0;
|
||||
uip_ipaddr_copy(&(UIP_ND6_OPT_PREFIX_BUF->prefix), &(prefix->ipaddr));
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->type = UIP_ND6_OPT_PREFIX_INFO;
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->len = UIP_ND6_OPT_PREFIX_INFO_LEN / 8;
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->preflen = prefix->length;
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->flagsreserved1 = prefix->l_a_reserved;
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->validlt = uip_htonl(prefix->vlifetime);
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->preferredlt = uip_htonl(prefix->plifetime);
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->reserved2 = 0;
|
||||
uip_ipaddr_copy(&(ND6_OPT_PREFIX_BUF(nd6_opt_offset)->prefix), &(prefix->ipaddr));
|
||||
nd6_opt_offset += UIP_ND6_OPT_PREFIX_INFO_LEN;
|
||||
uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Source link-layer option */
|
||||
create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF, UIP_ND6_OPT_SLLAO);
|
||||
create_llao((uint8_t *)ND6_OPT_HDR_BUF(nd6_opt_offset), UIP_ND6_OPT_SLLAO);
|
||||
|
||||
uip_len += UIP_ND6_OPT_LLAO_LEN;
|
||||
nd6_opt_offset += UIP_ND6_OPT_LLAO_LEN;
|
||||
|
||||
/* MTU */
|
||||
UIP_ND6_OPT_MTU_BUF->type = UIP_ND6_OPT_MTU;
|
||||
UIP_ND6_OPT_MTU_BUF->len = UIP_ND6_OPT_MTU_LEN >> 3;
|
||||
UIP_ND6_OPT_MTU_BUF->reserved = 0;
|
||||
//UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(uip_ds6_if.link_mtu);
|
||||
UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(1500);
|
||||
ND6_OPT_MTU_BUF(nd6_opt_offset)->type = UIP_ND6_OPT_MTU;
|
||||
ND6_OPT_MTU_BUF(nd6_opt_offset)->len = UIP_ND6_OPT_MTU_LEN >> 3;
|
||||
ND6_OPT_MTU_BUF(nd6_opt_offset)->reserved = 0;
|
||||
//ND6_OPT_MTU_BUF(nd6_opt_offset)->mtu = uip_htonl(uip_ds6_if.link_mtu);
|
||||
ND6_OPT_MTU_BUF(nd6_opt_offset)->mtu = uip_htonl(1500);
|
||||
|
||||
uip_len += UIP_ND6_OPT_MTU_LEN;
|
||||
nd6_opt_offset += UIP_ND6_OPT_MTU_LEN;
|
||||
|
@ -778,27 +765,26 @@ uip_nd6_ra_output(uip_ipaddr_t * dest)
|
|||
#if UIP_ND6_RA_RDNSS
|
||||
if(uip_nameserver_count() > 0) {
|
||||
uint8_t i = 0;
|
||||
uip_ipaddr_t *ip = &UIP_ND6_OPT_RDNSS_BUF->ip;
|
||||
uip_ipaddr_t *ip = &ND6_OPT_RDNSS_BUF(nd6_opt_offset)->ip;
|
||||
uip_ipaddr_t *dns = NULL;
|
||||
UIP_ND6_OPT_RDNSS_BUF->type = UIP_ND6_OPT_RDNSS;
|
||||
UIP_ND6_OPT_RDNSS_BUF->reserved = 0;
|
||||
UIP_ND6_OPT_RDNSS_BUF->lifetime = uip_nameserver_next_expiration();
|
||||
if(UIP_ND6_OPT_RDNSS_BUF->lifetime != UIP_NAMESERVER_INFINITE_LIFETIME) {
|
||||
UIP_ND6_OPT_RDNSS_BUF->lifetime -= clock_seconds();
|
||||
ND6_OPT_RDNSS_BUF(nd6_opt_offset)->type = UIP_ND6_OPT_RDNSS;
|
||||
ND6_OPT_RDNSS_BUF(nd6_opt_offset)->reserved = 0;
|
||||
ND6_OPT_RDNSS_BUF(nd6_opt_offset)->lifetime = uip_nameserver_next_expiration();
|
||||
if(ND6_OPT_RDNSS_BUF(nd6_opt_offset)->lifetime != UIP_NAMESERVER_INFINITE_LIFETIME) {
|
||||
ND6_OPT_RDNSS_BUF(nd6_opt_offset)->lifetime -= clock_seconds();
|
||||
}
|
||||
while((dns = uip_nameserver_get(i)) != NULL) {
|
||||
uip_ipaddr_copy(ip++, dns);
|
||||
i++;
|
||||
}
|
||||
UIP_ND6_OPT_RDNSS_BUF->len = UIP_ND6_OPT_RDNSS_LEN + (i << 1);
|
||||
ND6_OPT_RDNSS_BUF(nd6_opt_offset)->len = UIP_ND6_OPT_RDNSS_LEN + (i << 1);
|
||||
LOG_INFO("%d nameservers reported\n", i);
|
||||
uip_len += UIP_ND6_OPT_RDNSS_BUF->len << 3;
|
||||
nd6_opt_offset += UIP_ND6_OPT_RDNSS_BUF->len << 3;
|
||||
uip_len += ND6_OPT_RDNSS_BUF(nd6_opt_offset)->len << 3;
|
||||
nd6_opt_offset += ND6_OPT_RDNSS_BUF(nd6_opt_offset)->len << 3;
|
||||
}
|
||||
#endif /* UIP_ND6_RA_RDNSS */
|
||||
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
/*ICMP checksum */
|
||||
UIP_ICMP_BUF->icmpchksum = 0;
|
||||
|
@ -829,17 +815,15 @@ uip_nd6_rs_output(void)
|
|||
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
|
||||
UIP_ICMP_BUF->type = ICMP6_RS;
|
||||
UIP_ICMP_BUF->icode = 0;
|
||||
UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */
|
||||
|
||||
if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
|
||||
UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_RS_LEN;
|
||||
uip_len = uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN;
|
||||
} else {
|
||||
uip_len = uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN;
|
||||
UIP_IP_BUF->len[1] =
|
||||
UIP_ICMPH_LEN + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN);
|
||||
|
||||
create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_RS_LEN],
|
||||
create_llao(&uip_buf[uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN],
|
||||
UIP_ND6_OPT_SLLAO);
|
||||
}
|
||||
|
||||
|
@ -904,14 +888,14 @@ ra_input(void)
|
|||
/* Options processing */
|
||||
nd6_opt_offset = UIP_ND6_RA_LEN;
|
||||
while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
|
||||
if(UIP_ND6_OPT_HDR_BUF->len == 0) {
|
||||
if(ND6_OPT_HDR_BUF(nd6_opt_offset)->len == 0) {
|
||||
LOG_ERR("RA received is bad");
|
||||
goto discard;
|
||||
}
|
||||
switch (UIP_ND6_OPT_HDR_BUF->type) {
|
||||
switch (ND6_OPT_HDR_BUF(nd6_opt_offset)->type) {
|
||||
case UIP_ND6_OPT_SLLAO:
|
||||
LOG_DBG("Processing SLLAO option in RA\n");
|
||||
nd6_opt_llao = (uint8_t *) UIP_ND6_OPT_HDR_BUF;
|
||||
nd6_opt_llao = (uint8_t *) ND6_OPT_HDR_BUF(nd6_opt_offset);
|
||||
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
|
||||
if(!extract_lladdr_from_llao_aligned(&lladdr_aligned)) {
|
||||
/* failed to extract llao - discard packet */
|
||||
|
@ -944,11 +928,11 @@ ra_input(void)
|
|||
case UIP_ND6_OPT_MTU:
|
||||
LOG_DBG("Processing MTU option in RA\n");
|
||||
uip_ds6_if.link_mtu =
|
||||
uip_ntohl(((uip_nd6_opt_mtu *) UIP_ND6_OPT_HDR_BUF)->mtu);
|
||||
uip_ntohl(((uip_nd6_opt_mtu *) ND6_OPT_HDR_BUF(nd6_opt_offset))->mtu);
|
||||
break;
|
||||
case UIP_ND6_OPT_PREFIX_INFO:
|
||||
LOG_DBG("Processing PREFIX option in RA\n");
|
||||
nd6_opt_prefix_info = (uip_nd6_opt_prefix_info *) UIP_ND6_OPT_HDR_BUF;
|
||||
nd6_opt_prefix_info = (uip_nd6_opt_prefix_info *) ND6_OPT_HDR_BUF(nd6_opt_offset);
|
||||
if((uip_ntohl(nd6_opt_prefix_info->validlt) >=
|
||||
uip_ntohl(nd6_opt_prefix_info->preferredlt))
|
||||
&& (!uip_is_addr_linklocal(&nd6_opt_prefix_info->prefix))) {
|
||||
|
@ -1035,14 +1019,14 @@ ra_input(void)
|
|||
#if UIP_ND6_RA_RDNSS
|
||||
case UIP_ND6_OPT_RDNSS:
|
||||
LOG_DBG("Processing RDNSS option\n");
|
||||
uint8_t naddr = (UIP_ND6_OPT_RDNSS_BUF->len - 1) / 2;
|
||||
uip_ipaddr_t *ip = (uip_ipaddr_t *)(&UIP_ND6_OPT_RDNSS_BUF->ip);
|
||||
uint8_t naddr = (ND6_OPT_RDNSS_BUF(nd6_opt_offset)->len - 1) / 2;
|
||||
uip_ipaddr_t *ip = (uip_ipaddr_t *)(&ND6_OPT_RDNSS_BUF(nd6_opt_offset)->ip);
|
||||
LOG_DBG("got %d nameservers\n", naddr);
|
||||
while(naddr-- > 0) {
|
||||
LOG_DBG("nameserver: ");
|
||||
LOG_DBG_6ADDR(ip);
|
||||
LOG_DBG_(" lifetime: %"PRIx32"\n", uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime));
|
||||
uip_nameserver_update(ip, uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime));
|
||||
LOG_DBG_(" lifetime: %"PRIx32"\n", uip_ntohl(ND6_OPT_RDNSS_BUF(nd6_opt_offset)->lifetime));
|
||||
uip_nameserver_update(ip, uip_ntohl(ND6_OPT_RDNSS_BUF(nd6_opt_offset)->lifetime));
|
||||
ip++;
|
||||
}
|
||||
break;
|
||||
|
@ -1051,7 +1035,7 @@ ra_input(void)
|
|||
LOG_ERR("ND option not supported in RA\n");
|
||||
break;
|
||||
}
|
||||
nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3);
|
||||
nd6_opt_offset += (ND6_OPT_HDR_BUF(nd6_opt_offset)->len << 3);
|
||||
}
|
||||
|
||||
defrt = uip_ds6_defrt_lookup(&UIP_IP_BUF->srcipaddr);
|
||||
|
@ -1092,7 +1076,7 @@ ra_input(void)
|
|||
#endif /*UIP_CONF_IPV6_QUEUE_PKT */
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
#endif /* !UIP_CONF_ROUTER */
|
||||
|
|
|
@ -7,7 +7,7 @@ struct uip_packetqueue_handle;
|
|||
|
||||
struct uip_packetqueue_packet {
|
||||
struct uip_ds6_queued_packet *next;
|
||||
uint8_t queue_buf[UIP_BUFSIZE - UIP_LLH_LEN];
|
||||
uint8_t queue_buf[UIP_BUFSIZE];
|
||||
uint16_t queue_buf_len;
|
||||
struct ctimer lifetimer;
|
||||
struct uip_packetqueue_handle *handle;
|
||||
|
|
|
@ -51,10 +51,10 @@ void
|
|||
uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len)
|
||||
{
|
||||
#if UIP_UDP
|
||||
if(data != NULL && len <= (UIP_BUFSIZE - (UIP_LLH_LEN + UIP_IPUDPH_LEN))) {
|
||||
if(data != NULL && len <= (UIP_BUFSIZE - UIP_IPUDPH_LEN)) {
|
||||
uip_udp_conn = c;
|
||||
uip_slen = len;
|
||||
memmove(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, len);
|
||||
memmove(&uip_buf[UIP_IPUDPH_LEN], data, len);
|
||||
uip_process(UIP_UDP_SEND_CONN);
|
||||
|
||||
#if UIP_IPV6_MULTICAST
|
||||
|
|
|
@ -62,22 +62,24 @@
|
|||
|
||||
#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP + UDP header */
|
||||
#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + TCP header */
|
||||
#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN
|
||||
#define UIP_IPICMPH_LEN (UIP_IPH_LEN + UIP_ICMPH_LEN) /* Size of ICMP + IP header */
|
||||
#define UIP_LLIPH_LEN (UIP_LLH_LEN + UIP_IPH_LEN) /* Size of L2 + IP header */
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/**
|
||||
* The sums below are quite used in ND. When used for uip_buf, we
|
||||
* include link layer length when used for uip_len, we do not, hence
|
||||
* we need values with and without LLH_LEN we do not use capital
|
||||
* letters as these values are variable
|
||||
*/
|
||||
#define uip_l2_l3_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len)
|
||||
#define uip_l2_l3_icmp_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN)
|
||||
#define uip_l3_hdr_len (UIP_IPH_LEN + uip_ext_len)
|
||||
#define uip_l3_icmp_hdr_len (UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN)
|
||||
#endif /*NETSTACK_CONF_WITH_IPV6*/
|
||||
|
||||
#define uip_l3_icmp_hdr_len (UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN)
|
||||
|
||||
/**
|
||||
* Direct access to IPv6 header
|
||||
*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)uip_buf)
|
||||
#define UIP_IP_PAYLOAD(ext) ((unsigned char *)uip_buf + UIP_IPH_LEN + (ext))
|
||||
|
||||
/**
|
||||
* Direct access to ICMP, UDP, and TCP headers and payload, with implicit ext header offset (global uip_ext_len)
|
||||
*/
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)UIP_IP_PAYLOAD(uip_ext_len))
|
||||
#define UIP_ICMP_PAYLOAD ((unsigned char *)UIP_IP_PAYLOAD(uip_ext_len) + UIP_ICMPH_LEN)
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)UIP_IP_PAYLOAD(uip_ext_len))
|
||||
#define UIP_UDP_PAYLOAD ((unsigned char *)UIP_IP_PAYLOAD(uip_ext_len) + UIP_UDPH_LEN)
|
||||
#define UIP_TCP_BUF ((struct uip_tcp_hdr *)UIP_IP_PAYLOAD(uip_ext_len))
|
||||
#define UIP_TCP_PAYLOAD ((unsigned char *)UIP_IP_PAYLOAD(uip_ext_len) + UIP_TCPH_LEN)
|
||||
|
||||
#include "net/ipv6/uipopt.h"
|
||||
#include "net/ipv6/uipbuf.h"
|
||||
|
@ -100,12 +102,7 @@ typedef union uip_ip6addr_t {
|
|||
uint16_t u16[8];
|
||||
} uip_ip6addr_t;
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
typedef uip_ip6addr_t uip_ipaddr_t;
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
typedef uip_ip4addr_t uip_ipaddr_t;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_802154_SHORTADDR_LEN 2
|
||||
|
@ -1048,11 +1045,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport);
|
|||
(addr1)->u16[1] == (addr2)->u16[1])
|
||||
#define uip_ip6addr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#define uip_ipaddr_cmp(addr1, addr2) uip_ip6addr_cmp(addr1, addr2)
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
#define uip_ipaddr_cmp(addr1, addr2) uip_ip4addr_cmp(addr1, addr2)
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/**
|
||||
* Compare two IP addresses with netmasks
|
||||
|
@ -1308,31 +1301,16 @@ extern uint16_t uip_len;
|
|||
* The length of the extension headers
|
||||
*/
|
||||
extern uint8_t uip_ext_len;
|
||||
|
||||
/** The final protocol after IPv6 extension headers:
|
||||
* UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6 */
|
||||
extern uint8_t uip_last_proto;
|
||||
/** @} */
|
||||
|
||||
#if UIP_URGDATA > 0
|
||||
extern uint16_t uip_urglen, uip_surglen;
|
||||
#endif /* UIP_URGDATA > 0 */
|
||||
|
||||
/*
|
||||
* Clear uIP buffer
|
||||
*
|
||||
* This function clears the uIP buffer by reseting the uip_len and
|
||||
* uip_ext_len pointers.
|
||||
*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#define uip_clear_buf() { \
|
||||
uip_len = 0; \
|
||||
uip_ext_len = 0; \
|
||||
uipbuf_clear_attr();\
|
||||
}
|
||||
#else /*NETSTACK_CONF_WITH_IPV6*/
|
||||
#define uip_clear_buf() { \
|
||||
uip_len = 0; \
|
||||
uipbuf_clear_attr();\
|
||||
}
|
||||
#endif /*NETSTACK_CONF_WITH_IPV6*/
|
||||
|
||||
/**
|
||||
* Representation of a uIP TCP connection.
|
||||
*
|
||||
|
@ -1494,13 +1472,11 @@ struct uip_stats {
|
|||
checksum. */
|
||||
} udp; /**< UDP statistics. */
|
||||
#endif /* UIP_UDP */
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
struct {
|
||||
uip_stats_t drop; /**< Number of dropped ND6 packets. */
|
||||
uip_stats_t recv; /**< Number of recived ND6 packets */
|
||||
uip_stats_t sent; /**< Number of sent ND6 packets */
|
||||
} nd6;
|
||||
#endif /*NETSTACK_CONF_WITH_IPV6*/
|
||||
};
|
||||
|
||||
|
||||
|
@ -1619,113 +1595,14 @@ void uip_process(uint8_t flag);
|
|||
|
||||
#define UIP_STOPPED 16
|
||||
|
||||
/* The TCP and IP headers. */
|
||||
struct uip_tcpip_hdr {
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* IPv6 header. */
|
||||
uint8_t vtc,
|
||||
tcflow;
|
||||
uint16_t flow;
|
||||
uint8_t len[2];
|
||||
uint8_t proto, ttl;
|
||||
uip_ip6addr_t srcipaddr, destipaddr;
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* IPv4 header. */
|
||||
uint8_t vhl,
|
||||
tos,
|
||||
len[2],
|
||||
ipid[2],
|
||||
ipoffset[2],
|
||||
ttl,
|
||||
proto;
|
||||
uint16_t ipchksum;
|
||||
uip_ipaddr_t srcipaddr, destipaddr;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* 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];
|
||||
};
|
||||
|
||||
/* The ICMP and IP headers. */
|
||||
struct uip_icmpip_hdr {
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* IPv6 header. */
|
||||
uint8_t vtc,
|
||||
tcf;
|
||||
uint16_t flow;
|
||||
uint8_t len[2];
|
||||
uint8_t proto, ttl;
|
||||
uip_ip6addr_t srcipaddr, destipaddr;
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* IPv4 header. */
|
||||
uint8_t vhl,
|
||||
tos,
|
||||
len[2],
|
||||
ipid[2],
|
||||
ipoffset[2],
|
||||
ttl,
|
||||
proto;
|
||||
uint16_t ipchksum;
|
||||
uip_ipaddr_t srcipaddr, destipaddr;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* ICMP header. */
|
||||
uint8_t type, icode;
|
||||
uint16_t icmpchksum;
|
||||
#if !NETSTACK_CONF_WITH_IPV6
|
||||
uint16_t id, seqno;
|
||||
uint8_t payload[1];
|
||||
#endif /* !NETSTACK_CONF_WITH_IPV6 */
|
||||
};
|
||||
|
||||
|
||||
/* The UDP and IP headers. */
|
||||
struct uip_udpip_hdr {
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* IPv6 header. */
|
||||
uint8_t vtc,
|
||||
tcf;
|
||||
uint16_t flow;
|
||||
uint8_t len[2];
|
||||
uint8_t proto, ttl;
|
||||
uip_ip6addr_t srcipaddr, destipaddr;
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* IP header. */
|
||||
uint8_t vhl,
|
||||
tos,
|
||||
len[2],
|
||||
ipid[2],
|
||||
ipoffset[2],
|
||||
ttl,
|
||||
proto;
|
||||
uint16_t ipchksum;
|
||||
uip_ipaddr_t srcipaddr, destipaddr;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* UDP header. */
|
||||
uint16_t srcport,
|
||||
destport;
|
||||
uint16_t udplen;
|
||||
uint16_t udpchksum;
|
||||
};
|
||||
|
||||
/*
|
||||
* In IPv6 the length of the L3 headers before the transport header is
|
||||
* not fixed, due to the possibility to include extension option headers
|
||||
* after the IP header. hence we split here L3 and L4 headers
|
||||
*/
|
||||
/* The IP header */
|
||||
|
||||
struct uip_ip_hdr {
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* IPV6 header */
|
||||
uint8_t vtc;
|
||||
uint8_t tcflow;
|
||||
|
@ -1733,18 +1610,6 @@ struct uip_ip_hdr {
|
|||
uint8_t len[2];
|
||||
uint8_t proto, ttl;
|
||||
uip_ip6addr_t srcipaddr, destipaddr;
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* IPV4 header */
|
||||
uint8_t vhl,
|
||||
tos,
|
||||
len[2],
|
||||
ipid[2],
|
||||
ipoffset[2],
|
||||
ttl,
|
||||
proto;
|
||||
uint16_t ipchksum;
|
||||
uip_ipaddr_t srcipaddr, destipaddr;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
};
|
||||
|
||||
|
||||
|
@ -1860,9 +1725,6 @@ struct uip_tcp_hdr {
|
|||
struct uip_icmp_hdr {
|
||||
uint8_t type, icode;
|
||||
uint16_t icmpchksum;
|
||||
#if !NETSTACK_CONF_WITH_IPV6
|
||||
uint16_t id, seqno;
|
||||
#endif /* !NETSTACK_CONF_WITH_IPV6 */
|
||||
};
|
||||
|
||||
|
||||
|
@ -1889,8 +1751,7 @@ struct uip_udp_hdr {
|
|||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
|
||||
#define UIP_APPDATA_PTR (void *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]
|
||||
#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_IPTCPH_LEN)
|
||||
|
||||
#define UIP_PROTO_ICMP 1
|
||||
#define UIP_PROTO_TCP 6
|
||||
|
@ -1898,7 +1759,6 @@ struct uip_udp_hdr {
|
|||
#define UIP_PROTO_ICMP6 58
|
||||
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/** @{ */
|
||||
/** \brief extension headers types */
|
||||
#define UIP_PROTO_HBHO 0
|
||||
|
@ -1908,7 +1768,7 @@ struct uip_udp_hdr {
|
|||
#define UIP_PROTO_NONE 59
|
||||
/** @} */
|
||||
|
||||
#define uip_is_proto_ext_hdr(proto) (proto == UIP_PROTO_HBHO || proto == UIP_PROTO_DESTO || proto == UIP_PROTO_ROUTING || proto == UIP_PROTO_FRAG || proto == UIP_PROTO_NONE)
|
||||
#define uip_is_proto_ext_hdr(proto) ((proto) != UIP_PROTO_TCP && (proto) != UIP_PROTO_UDP && (proto) != UIP_PROTO_ICMP6)
|
||||
|
||||
/** @{ */
|
||||
/** \brief Destination and Hop By Hop extension headers option types */
|
||||
|
@ -1937,9 +1797,6 @@ struct uip_udp_hdr {
|
|||
/** @} */
|
||||
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
|
||||
#if UIP_FIXEDADDR
|
||||
extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
|
||||
#else /* UIP_FIXEDADDR */
|
||||
|
@ -1954,10 +1811,6 @@ extern const uip_lladdr_t uip_lladdr;
|
|||
extern uip_lladdr_t uip_lladdr;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/** Length of the link local prefix */
|
||||
#define UIP_LLPREF_LEN 10
|
||||
|
||||
|
@ -2174,8 +2027,6 @@ extern uip_lladdr_t uip_lladdr;
|
|||
(((a)->u8[14]) == ((b)->u8[14])) && \
|
||||
(((a)->u8[15]) == ((b)->u8[15])))
|
||||
|
||||
#endif /*NETSTACK_CONF_WITH_IPV6*/
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a packet should be
|
||||
* processed locally.
|
||||
|
@ -2288,6 +2139,11 @@ uint16_t uip_udpchksum(void);
|
|||
*/
|
||||
uint16_t uip_icmp6chksum(void);
|
||||
|
||||
/**
|
||||
* Removes all IPv6 extension headers from uip_buf, updates length fields
|
||||
* (uip_len and uip_ext_len)
|
||||
*/
|
||||
void uip_remove_ext_hdr(void);
|
||||
|
||||
#endif /* UIP_H_ */
|
||||
|
||||
|
|
|
@ -114,46 +114,26 @@ uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}};
|
|||
* @{
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Type of the next header in IPv6 header or extension headers
|
||||
*
|
||||
* Can be the next header field in the IPv6 header or in an extension header.
|
||||
* When doing fragment reassembly, we must change the value of the next header
|
||||
* field in the header before the fragmentation header, hence we need a pointer
|
||||
* to this field.
|
||||
*/
|
||||
uint8_t *uip_next_hdr;
|
||||
/** \brief bitmap we use to record which IPv6 headers we have already seen */
|
||||
uint8_t uip_ext_bitmap = 0;
|
||||
/**
|
||||
* \brief length of the extension headers read. updated each time we process
|
||||
* a header
|
||||
* \brief Total length of all IPv6 extension headers
|
||||
*/
|
||||
uint8_t uip_ext_len = 0;
|
||||
/** \brief length of the header options read */
|
||||
uint8_t uip_ext_opt_offset = 0;
|
||||
/** \brief The final protocol after IPv6 extension headers:
|
||||
* UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6 */
|
||||
uint8_t uip_last_proto = 0;
|
||||
/** @} */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Buffers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Buffer defines
|
||||
* \name Reassembly buffer definition
|
||||
* @{
|
||||
*/
|
||||
#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#define UIP_TCP_BUF ((struct uip_tcp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ROUTING_BUF ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_FRAG_BUF ((struct uip_frag_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_DESTO_BUF ((struct uip_desto_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define FBUF ((struct uip_ip_hdr *)&uip_reassbuf[0])
|
||||
|
||||
/** @} */
|
||||
/**
|
||||
* \name Buffer variables
|
||||
|
@ -341,7 +321,7 @@ uip_ipchksum(void)
|
|||
{
|
||||
uint16_t sum;
|
||||
|
||||
sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
|
||||
sum = chksum(0, uip_buf, UIP_IPH_LEN);
|
||||
LOG_DBG("uip_ipchksum: sum 0x%04x\n", sum);
|
||||
return (sum == 0) ? 0xffff : uip_htons(sum);
|
||||
}
|
||||
|
@ -362,10 +342,10 @@ upper_layer_chksum(uint8_t proto)
|
|||
volatile uint16_t upper_layer_len;
|
||||
uint16_t sum;
|
||||
|
||||
upper_layer_len = (((uint16_t)(UIP_IP_BUF->len[0]) << 8) + UIP_IP_BUF->len[1] - uip_ext_len);
|
||||
upper_layer_len = uipbuf_get_len_field(UIP_IP_BUF) - uip_ext_len;
|
||||
|
||||
LOG_DBG("Upper layer checksum len: %d from: %d\n", upper_layer_len,
|
||||
UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len);
|
||||
(int)(UIP_IP_PAYLOAD(uip_ext_len) - uip_buf));
|
||||
|
||||
/* First sum pseudoheader. */
|
||||
/* IP protocol and length fields. This addition cannot carry. */
|
||||
|
@ -373,9 +353,8 @@ upper_layer_chksum(uint8_t proto)
|
|||
/* Sum IP source and destination addresses. */
|
||||
sum = chksum(sum, (uint8_t *)&UIP_IP_BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
|
||||
|
||||
/* Sum TCP header and data. */
|
||||
sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len],
|
||||
upper_layer_len);
|
||||
/* Sum upper-layer header and data. */
|
||||
sum = chksum(sum, UIP_IP_PAYLOAD(uip_ext_len), upper_layer_len);
|
||||
|
||||
return (sum == 0) ? 0xffff : uip_htons(sum);
|
||||
}
|
||||
|
@ -409,6 +388,7 @@ uip_init(void)
|
|||
{
|
||||
int c;
|
||||
|
||||
uipbuf_init();
|
||||
uip_ds6_init();
|
||||
uip_icmp6_init();
|
||||
uip_nd6_init();
|
||||
|
@ -510,29 +490,27 @@ uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport)
|
|||
#endif /* UIP_TCP && UIP_ACTIVE_OPEN */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
remove_ext_hdr(void)
|
||||
uip_remove_ext_hdr(void)
|
||||
{
|
||||
int last_uip_ext_len;
|
||||
/* Remove ext header before TCP/UDP processing. */
|
||||
if(uip_ext_len > 0) {
|
||||
LOG_DBG("Cutting ext-header before processing (extlen: %d, uiplen: %d)\n",
|
||||
LOG_DBG("Removing IPv6 extension headers (extlen: %d, uiplen: %d)\n",
|
||||
uip_ext_len, uip_len);
|
||||
if(uip_len < UIP_IPH_LEN + uip_ext_len) {
|
||||
LOG_ERR("ERROR: uip_len too short compared to ext len\n");
|
||||
uip_clear_buf();
|
||||
LOG_ERR("uip_len too short compared to ext len\n");
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
UIP_IP_BUF->proto = UIP_EXT_BUF->next;
|
||||
memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + last_uip_ext_len,
|
||||
uip_len - UIP_IPH_LEN - last_uip_ext_len);
|
||||
|
||||
uip_len -= last_uip_ext_len;
|
||||
/* Set proto */
|
||||
UIP_IP_BUF->proto = uip_last_proto;
|
||||
/* Move IP payload to the "left"*/
|
||||
memmove(UIP_IP_PAYLOAD(0), UIP_IP_PAYLOAD(uip_ext_len),
|
||||
uip_len - UIP_IPH_LEN - uip_ext_len);
|
||||
|
||||
/* Update the IP length. */
|
||||
UIP_IP_BUF->len[0] = (uip_len - UIP_IPH_LEN) >> 8;
|
||||
UIP_IP_BUF->len[1] = (uip_len - UIP_IPH_LEN) & 0xff;
|
||||
uipbuf_add_ext_hdr(-uip_ext_len);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -610,7 +588,7 @@ uip_listen(uint16_t port)
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if UIP_CONF_IPV6_REASSEMBLY
|
||||
#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
|
||||
#define UIP_REASS_BUFSIZE (UIP_BUFSIZE)
|
||||
|
||||
static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
|
||||
|
||||
|
@ -646,11 +624,12 @@ static uint32_t uip_id; /* For every packet that is to be fragmented, the source
|
|||
#define IP_MF 0x0001
|
||||
|
||||
static uint16_t
|
||||
uip_reass(void)
|
||||
uip_reass(uint8_t *prev_proto_ptr)
|
||||
{
|
||||
uint16_t offset=0;
|
||||
uint16_t len;
|
||||
uint16_t i;
|
||||
struct uip_frag_hdr *frag_buf = (struct uip_frag_hdr *)UIP_IP_PAYLOAD(uip_ext_len);
|
||||
|
||||
/* If ip_reasstmr is zero, no packet is present in the buffer */
|
||||
/* We first write the unfragmentable part of IP header into the reassembly
|
||||
|
@ -662,7 +641,7 @@ uip_reass(void)
|
|||
etimer_set(&uip_reass_timer, UIP_REASS_MAXAGE*CLOCK_SECOND);
|
||||
uip_reass_on = 1;
|
||||
uip_reassflags = 0;
|
||||
uip_id = UIP_FRAG_BUF->id;
|
||||
uip_id = frag_buf->id;
|
||||
/* Clear the bitmap. */
|
||||
memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
|
||||
}
|
||||
|
@ -673,9 +652,9 @@ uip_reass(void)
|
|||
*/
|
||||
if(uip_ipaddr_cmp(&FBUF->srcipaddr, &UIP_IP_BUF->srcipaddr) &&
|
||||
uip_ipaddr_cmp(&FBUF->destipaddr, &UIP_IP_BUF->destipaddr) &&
|
||||
UIP_FRAG_BUF->id == uip_id) {
|
||||
frag_buf->id == uip_id) {
|
||||
len = uip_len - uip_ext_len - UIP_IPH_LEN - UIP_FRAGH_LEN;
|
||||
offset = (uip_ntohs(UIP_FRAG_BUF->offsetresmore) & 0xfff8);
|
||||
offset = (uip_ntohs(frag_buf->offsetresmore) & 0xfff8);
|
||||
/* in byte, originaly in multiple of 8 bytes*/
|
||||
LOG_INFO("len %d\n", len);
|
||||
LOG_INFO("offset %d\n", offset);
|
||||
|
@ -686,7 +665,7 @@ uip_reass(void)
|
|||
* Part is obtained from the Next Header field of the first
|
||||
* fragment's Fragment header.
|
||||
*/
|
||||
*uip_next_hdr = UIP_FRAG_BUF->next;
|
||||
*prev_proto_ptr = frag_buf->next;
|
||||
memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN);
|
||||
LOG_INFO("src ");
|
||||
LOG_INFO_6ADDR(&FBUF->srcipaddr);
|
||||
|
@ -707,7 +686,7 @@ uip_reass(void)
|
|||
|
||||
/* If this fragment has the More Fragments flag set to zero, it is the
|
||||
last fragment*/
|
||||
if((uip_ntohs(UIP_FRAG_BUF->offsetresmore) & IP_MF) == 0) {
|
||||
if((uip_ntohs(frag_buf->offsetresmore) & IP_MF) == 0) {
|
||||
uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
|
||||
/*calculate the size of the entire packet*/
|
||||
uip_reasslen = offset + len;
|
||||
|
@ -731,7 +710,7 @@ uip_reass(void)
|
|||
/* Copy the fragment into the reassembly buffer, at the right
|
||||
offset. */
|
||||
memcpy((uint8_t *)FBUF + UIP_IPH_LEN + uip_ext_len + offset,
|
||||
(uint8_t *)UIP_FRAG_BUF + UIP_FRAGH_LEN, len);
|
||||
(uint8_t *)frag_buf + UIP_FRAGH_LEN, len);
|
||||
|
||||
/* Update the bitmap. */
|
||||
if(offset >> 6 == (offset + len) >> 6) {
|
||||
|
@ -777,10 +756,8 @@ uip_reass(void)
|
|||
|
||||
uip_reasslen += UIP_IPH_LEN + uip_ext_len;
|
||||
memcpy(UIP_IP_BUF, FBUF, uip_reasslen);
|
||||
UIP_IP_BUF->len[0] = ((uip_reasslen - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_reasslen - UIP_IPH_LEN) & 0xff);
|
||||
LOG_INFO("reassembled packet %d (%d)\n", uip_reasslen,
|
||||
(UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_reasslen - UIP_IPH_LEN);
|
||||
LOG_INFO("reassembled packet %d (%d)\n", uip_reasslen, uipbuf_get_len_field(UIP_IP_BUF));
|
||||
|
||||
return uip_reasslen;
|
||||
|
||||
|
@ -810,7 +787,7 @@ uip_reass_over(void)
|
|||
* any RFC, we decided not to include it as it reduces the size of
|
||||
* the packet.
|
||||
*/
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
memcpy(UIP_IP_BUF, FBUF, UIP_IPH_LEN); /* copy the header for src
|
||||
and dest address*/
|
||||
uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY, 0);
|
||||
|
@ -840,16 +817,29 @@ uip_add_rcv_nxt(uint16_t n)
|
|||
* \brief Process the options in Destination and Hop By Hop extension headers
|
||||
*/
|
||||
static uint8_t
|
||||
ext_hdr_options_process(void)
|
||||
ext_hdr_options_process(uint8_t *ext_buf)
|
||||
{
|
||||
/*
|
||||
* Length field in the extension header: length of the header in units of
|
||||
* 8 bytes, excluding the first 8 bytes
|
||||
* length field in an option : the length of data in the option
|
||||
*/
|
||||
uip_ext_opt_offset = 2;
|
||||
while(uip_ext_opt_offset < ((UIP_EXT_BUF->len << 3) + 8)) {
|
||||
switch(UIP_EXT_HDR_OPT_BUF->type) {
|
||||
uint8_t opt_offset = 2; /* 2 first bytes in ext header */
|
||||
struct uip_hbho_hdr *ext_hdr = (struct uip_hbho_hdr *)ext_buf;
|
||||
uint8_t ext_hdr_len = (ext_hdr->len << 3) + 8;
|
||||
|
||||
while(opt_offset + 2 <= ext_hdr_len) { /* + 2 for opt header */
|
||||
struct uip_ext_hdr_opt *opt_hdr = (struct uip_ext_hdr_opt *)(ext_buf + opt_offset);
|
||||
uint8_t opt_len = opt_hdr->len + 2;
|
||||
|
||||
if(opt_offset + opt_len > ext_hdr_len) {
|
||||
LOG_ERR("RPL Option too long: Dropping Packet\n");
|
||||
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION,
|
||||
(ext_buf + opt_offset) - uip_buf);
|
||||
return 2;
|
||||
}
|
||||
|
||||
switch(opt_hdr->type) {
|
||||
/*
|
||||
* for now we do not support any options except padding ones
|
||||
* PAD1 does not make sense as the header must be 8bytes aligned,
|
||||
|
@ -857,11 +847,11 @@ ext_hdr_options_process(void)
|
|||
*/
|
||||
case UIP_EXT_HDR_OPT_PAD1:
|
||||
LOG_DBG("Processing PAD1 option\n");
|
||||
uip_ext_opt_offset += 1;
|
||||
opt_offset += 1;
|
||||
break;
|
||||
case UIP_EXT_HDR_OPT_PADN:
|
||||
LOG_DBG("Processing PADN option\n");
|
||||
uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2;
|
||||
opt_offset += opt_len;
|
||||
break;
|
||||
case UIP_EXT_HDR_OPT_RPL:
|
||||
/* Fixes situation when a node that is not using RPL
|
||||
|
@ -872,12 +862,13 @@ ext_hdr_options_process(void)
|
|||
* Using this fix, the header is ignored, and the next header (if
|
||||
* present) is processed.
|
||||
*/
|
||||
if(!NETSTACK_ROUTING.ext_header_hbh_update(uip_ext_opt_offset)) {
|
||||
LOG_DBG("Processing RPL option\n");
|
||||
if(!NETSTACK_ROUTING.ext_header_hbh_update(ext_buf, opt_offset)) {
|
||||
LOG_ERR("RPL Option Error: Dropping Packet\n");
|
||||
return 1;
|
||||
}
|
||||
uip_ext_opt_offset += (UIP_EXT_HDR_OPT_BUF->len) + 2;
|
||||
return 0;
|
||||
opt_offset += opt_len;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* check the two highest order bits of the option
|
||||
|
@ -892,8 +883,8 @@ ext_hdr_options_process(void)
|
|||
* Problem, Code 2, message to the packet's Source Address,
|
||||
* pointing to the unrecognized Option Type.
|
||||
*/
|
||||
LOG_DBG("MSB %x\n", UIP_EXT_HDR_OPT_BUF->type);
|
||||
switch(UIP_EXT_HDR_OPT_BUF->type & 0xC0) {
|
||||
LOG_DBG("Unrecognized option, MSB 0x%x\n", opt_hdr->type);
|
||||
switch(opt_hdr->type & 0xC0) {
|
||||
case 0:
|
||||
break;
|
||||
case 0x40:
|
||||
|
@ -904,22 +895,49 @@ ext_hdr_options_process(void)
|
|||
}
|
||||
case 0x80:
|
||||
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION,
|
||||
(uint32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset);
|
||||
(ext_buf + opt_offset) - uip_buf);
|
||||
return 2;
|
||||
}
|
||||
/* in the cases were we did not discard, update ext_opt* */
|
||||
uip_ext_opt_offset += UIP_EXT_HDR_OPT_BUF->len + 2;
|
||||
opt_offset += opt_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static bool
|
||||
uip_check_mtu(void)
|
||||
{
|
||||
if(uip_len > UIP_LINK_MTU) {
|
||||
uip_icmp6_error_output(ICMP6_PACKET_TOO_BIG, 0, UIP_LINK_MTU);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static bool
|
||||
uip_update_ttl(void)
|
||||
{
|
||||
if(UIP_IP_BUF->ttl <= 1) {
|
||||
uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT, 0);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
return false;
|
||||
} else {
|
||||
UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_process(uint8_t flag)
|
||||
{
|
||||
uint8_t *last_header;
|
||||
uint8_t protocol;
|
||||
uint8_t *next_header;
|
||||
struct uip_ext_hdr *ext_ptr;
|
||||
#if UIP_TCP
|
||||
int c;
|
||||
uint16_t tmp16;
|
||||
|
@ -931,7 +949,7 @@ uip_process(uint8_t flag)
|
|||
goto udp_send;
|
||||
}
|
||||
#endif /* UIP_UDP */
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN];
|
||||
|
||||
/* Check if we were invoked because of a poll request for a
|
||||
particular connection. */
|
||||
|
@ -955,7 +973,7 @@ uip_process(uint8_t flag)
|
|||
} else if(flag == UIP_TIMER) {
|
||||
/* Reset the length variables. */
|
||||
#if UIP_TCP
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
uip_slen = 0;
|
||||
|
||||
/* Increase the initial sequence number. */
|
||||
|
@ -1068,7 +1086,7 @@ uip_process(uint8_t flag)
|
|||
if(flag == UIP_UDP_TIMER) {
|
||||
if(uip_udp_conn->lport != 0) {
|
||||
uip_conn = NULL;
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
|
||||
uip_len = uip_slen = 0;
|
||||
uip_flags = UIP_POLL;
|
||||
UIP_UDP_APPCALL();
|
||||
|
@ -1101,8 +1119,8 @@ uip_process(uint8_t flag)
|
|||
* value..
|
||||
*/
|
||||
|
||||
if((UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] <= uip_len) {
|
||||
uip_len = (UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + UIP_IPH_LEN;
|
||||
if(uipbuf_get_len_field(UIP_IP_BUF) <= uip_len) {
|
||||
uip_len = uipbuf_get_len_field(UIP_IP_BUF) + UIP_IPH_LEN;
|
||||
/*
|
||||
* The length reported in the IPv6 header is the
|
||||
* length of the payload that follows the
|
||||
|
@ -1115,10 +1133,21 @@ uip_process(uint8_t flag)
|
|||
* header (40 bytes).
|
||||
*/
|
||||
} else {
|
||||
LOG_ERR("packet shorter than reported in IP header.");
|
||||
LOG_ERR("packet shorter than reported in IP header\n");
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Check sanity of extension headers, and compute the total extension header
|
||||
* length (uip_ext_len) as well as the final protocol (uip_last_proto) */
|
||||
uip_last_proto = 0;
|
||||
last_header = uipbuf_get_last_header(uip_buf, uip_len, &uip_last_proto);
|
||||
if(last_header == NULL) {
|
||||
LOG_ERR("invalid extension header chain\n");
|
||||
goto drop;
|
||||
}
|
||||
/* Set uip_ext_len */
|
||||
uip_ext_len = last_header - UIP_IP_PAYLOAD(0);
|
||||
|
||||
LOG_INFO("packet received from ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
LOG_INFO_(" to ");
|
||||
|
@ -1140,32 +1169,20 @@ uip_process(uint8_t flag)
|
|||
|
||||
#if UIP_CONF_ROUTER
|
||||
/*
|
||||
* Next header field processing. In IPv6, we can have extension headers,
|
||||
* if present, the Hop-by-Hop Option must be processed before forwarding
|
||||
* If present, the Hop-by-Hop Option must be processed before forwarding
|
||||
* the packet.
|
||||
*/
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_bitmap = 0;
|
||||
if(*uip_next_hdr == UIP_PROTO_HBHO) {
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO;
|
||||
#endif /* UIP_CONF_IPV6_CHECKS */
|
||||
switch(ext_hdr_options_process()) {
|
||||
|
||||
next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
|
||||
if(next_header != NULL && protocol == UIP_PROTO_HBHO) {
|
||||
switch(ext_hdr_options_process(next_header)) {
|
||||
case 0:
|
||||
/* continue */
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
break; /* done */
|
||||
case 1:
|
||||
LOG_ERR("Dropping packet after extension header processing\n");
|
||||
/* silently discard */
|
||||
goto drop;
|
||||
goto drop; /* silently discard */
|
||||
case 2:
|
||||
LOG_ERR("Sending error message after extension header processing\n");
|
||||
/* send icmp error message (created in ext_hdr_options_process)
|
||||
* and discard*/
|
||||
goto send;
|
||||
goto send; /* send icmp error message (created in
|
||||
ext_hdr_options_process) and discard */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1201,23 +1218,12 @@ uip_process(uint8_t flag)
|
|||
!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) &&
|
||||
!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) {
|
||||
|
||||
|
||||
/* Check MTU */
|
||||
if(uip_len > UIP_LINK_MTU) {
|
||||
uip_icmp6_error_output(ICMP6_PACKET_TOO_BIG, 0, UIP_LINK_MTU);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
goto send;
|
||||
}
|
||||
/* Check Hop Limit */
|
||||
if(UIP_IP_BUF->ttl <= 1) {
|
||||
uip_icmp6_error_output(ICMP6_TIME_EXCEEDED,
|
||||
ICMP6_TIME_EXCEED_TRANSIT, 0);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
if(!uip_check_mtu() || !uip_update_ttl()) {
|
||||
/* Send ICMPv6 error, prepared by the function that just returned false */
|
||||
goto send;
|
||||
}
|
||||
|
||||
UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
|
||||
LOG_INFO("Forwarding packet towards ");
|
||||
LOG_INFO("Forwarding packet to next hop ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
UIP_STAT(++uip_stat.ip.forwarded);
|
||||
|
@ -1246,35 +1252,20 @@ uip_process(uint8_t flag)
|
|||
UIP_STAT(++uip_stat.ip.drop);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/*
|
||||
* Next header field processing. In IPv6, we can have extension headers,
|
||||
* they are processed here
|
||||
*/
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_bitmap = 0;
|
||||
#endif /* UIP_CONF_ROUTER */
|
||||
|
||||
#if UIP_IPV6_MULTICAST && UIP_CONF_ROUTER
|
||||
process:
|
||||
#endif /* UIP_IPV6_MULTICAST && UIP_CONF_ROUTER */
|
||||
|
||||
while(1) {
|
||||
switch(*uip_next_hdr){
|
||||
#if UIP_TCP
|
||||
case UIP_PROTO_TCP:
|
||||
/* TCP, for both IPv4 and IPv6 */
|
||||
goto tcp_input;
|
||||
#endif /* UIP_TCP */
|
||||
#if UIP_UDP
|
||||
case UIP_PROTO_UDP:
|
||||
/* UDP, for both IPv4 and IPv6 */
|
||||
goto udp_input;
|
||||
#endif /* UIP_UDP */
|
||||
case UIP_PROTO_ICMP6:
|
||||
/* ICMPv6 */
|
||||
goto icmp6_input;
|
||||
/* IPv6 extension header processing: loop until reaching upper-layer protocol */
|
||||
uip_ext_bitmap = 0;
|
||||
for(next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
|
||||
next_header != NULL && uip_is_proto_ext_hdr(protocol);
|
||||
next_header = uipbuf_get_next_header(next_header, uip_len - (next_header - uip_buf), &protocol, false)) {
|
||||
|
||||
ext_ptr = (struct uip_ext_hdr *)next_header;
|
||||
switch(protocol) {
|
||||
case UIP_PROTO_HBHO:
|
||||
LOG_DBG("Processing hbh header\n");
|
||||
/* Hop by hop option header */
|
||||
|
@ -1286,145 +1277,140 @@ uip_process(uint8_t flag)
|
|||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS*/
|
||||
switch(ext_hdr_options_process()) {
|
||||
switch(ext_hdr_options_process(next_header)) {
|
||||
case 0:
|
||||
/*continue*/
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
break; /* done */
|
||||
case 1:
|
||||
/*silently discard*/
|
||||
goto drop;
|
||||
goto drop; /* silently discard */
|
||||
case 2:
|
||||
/* send icmp error message (created in ext_hdr_options_process)
|
||||
* and discard*/
|
||||
goto send;
|
||||
goto send; /* send icmp error message (created in
|
||||
ext_hdr_options_process) and discard */
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_DESTO:
|
||||
case UIP_PROTO_DESTO:
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
/* Destination option header. if we saw two already, drop */
|
||||
LOG_DBG("Processing desto header\n");
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO1) {
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO2) {
|
||||
goto bad_hdr;
|
||||
} else{
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO2;
|
||||
}
|
||||
} else {
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO1;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS*/
|
||||
switch(ext_hdr_options_process()) {
|
||||
case 0:
|
||||
/*continue*/
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
case 1:
|
||||
/*silently discard*/
|
||||
goto drop;
|
||||
case 2:
|
||||
/* send icmp error message (created in ext_hdr_options_process)
|
||||
* and discard*/
|
||||
goto send;
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_ROUTING:
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
/* Routing header. If we saw one already, drop */
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) {
|
||||
goto bad_hdr;
|
||||
} else {
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS*/
|
||||
/*
|
||||
* Routing Header length field is in units of 8 bytes, excluding
|
||||
* As per RFC2460 section 4.4, if routing type is unrecognized:
|
||||
* if segments left = 0, ignore the header
|
||||
* if segments left > 0, discard packet and send icmp error pointing
|
||||
* to the routing type
|
||||
*/
|
||||
|
||||
LOG_DBG("Processing Routing header\n");
|
||||
if(UIP_ROUTING_BUF->seg_left > 0) {
|
||||
if(NETSTACK_ROUTING.ext_header_srh_update()) {
|
||||
|
||||
/* With routing header, the detination address is us and will
|
||||
* be swapped later to the next hop. Because of this, the MTU
|
||||
* and TTL were not checked and updated yet. Do this now. */
|
||||
|
||||
/* Check MTU */
|
||||
if(uip_len > UIP_LINK_MTU) {
|
||||
uip_icmp6_error_output(ICMP6_PACKET_TOO_BIG, 0, UIP_LINK_MTU);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
goto send;
|
||||
}
|
||||
/* Check Hop Limit */
|
||||
if(UIP_IP_BUF->ttl <= 1) {
|
||||
uip_icmp6_error_output(ICMP6_TIME_EXCEEDED,
|
||||
ICMP6_TIME_EXCEED_TRANSIT, 0);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
goto send;
|
||||
}
|
||||
UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
|
||||
|
||||
LOG_INFO("Forwarding packet to next hop ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
UIP_STAT(++uip_stat.ip.forwarded);
|
||||
|
||||
goto send; /* Proceed to forwarding */
|
||||
}
|
||||
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, UIP_IPH_LEN + uip_ext_len + 2);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
LOG_ERR("unrecognized routing type");
|
||||
goto send;
|
||||
}
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
case UIP_PROTO_FRAG:
|
||||
/* Fragmentation header:call the reassembly function, then leave */
|
||||
#if UIP_CONF_IPV6_REASSEMBLY
|
||||
LOG_INFO("Processing fragmentation header\n");
|
||||
uip_len = uip_reass();
|
||||
if(uip_len == 0) {
|
||||
goto drop;
|
||||
}
|
||||
if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){
|
||||
/* we are not done with reassembly, this is an error message */
|
||||
goto send;
|
||||
}
|
||||
/*packet is reassembled, reset the next hdr to the beginning
|
||||
of the IP header and restart the parsing of the reassembled pkt*/
|
||||
LOG_INFO("Processing reassembled packet\n");
|
||||
uip_ext_len = 0;
|
||||
uip_ext_bitmap = 0;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
break;
|
||||
#else /* UIP_CONF_IPV6_REASSEMBLY */
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
UIP_STAT(++uip_stat.ip.fragerr);
|
||||
LOG_ERR("fragment dropped.");
|
||||
goto drop;
|
||||
#endif /* UIP_CONF_IPV6_REASSEMBLY */
|
||||
case UIP_PROTO_NONE:
|
||||
goto drop;
|
||||
default:
|
||||
/* Destination option header. if we saw two already, drop */
|
||||
LOG_DBG("Processing desto header\n");
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO1) {
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO2) {
|
||||
goto bad_hdr;
|
||||
} else{
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO2;
|
||||
}
|
||||
} else {
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO1;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS*/
|
||||
switch(ext_hdr_options_process(next_header)) {
|
||||
case 0:
|
||||
break; /* done */
|
||||
case 1:
|
||||
goto drop; /* silently discard */
|
||||
case 2:
|
||||
goto send; /* send icmp error message (created in
|
||||
ext_hdr_options_process) and discard */
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_ROUTING:
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
/* Routing header. If we saw one already, drop */
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) {
|
||||
goto bad_hdr;
|
||||
} else {
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS*/
|
||||
/*
|
||||
* Routing Header length field is in units of 8 bytes, excluding
|
||||
* As per RFC2460 section 4.4, if routing type is unrecognized:
|
||||
* if segments left = 0, ignore the header
|
||||
* if segments left > 0, discard packet and send icmp error pointing
|
||||
* to the routing type
|
||||
*/
|
||||
|
||||
LOG_DBG("Processing Routing header\n");
|
||||
if(((struct uip_routing_hdr *)ext_ptr)->seg_left > 0) {
|
||||
/* Process source routing header */
|
||||
if(NETSTACK_ROUTING.ext_header_srh_update()) {
|
||||
|
||||
/* The MTU and TTL were not checked and updated yet, because with
|
||||
* a routing header, the IPv6 destination address was set to us
|
||||
* even though we act only as forwarder. Check MTU and TTL now */
|
||||
if(!uip_check_mtu() || !uip_update_ttl()) {
|
||||
/* Send ICMPv6 error, prepared by the function that just returned false */
|
||||
goto send;
|
||||
}
|
||||
|
||||
LOG_INFO("Forwarding packet to next hop ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
UIP_STAT(++uip_stat.ip.forwarded);
|
||||
|
||||
goto send; /* Proceed to forwarding */
|
||||
} else {
|
||||
LOG_ERR("Unrecognized routing type\n");
|
||||
goto bad_hdr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_FRAG:
|
||||
/* Fragmentation header:call the reassembly function, then leave */
|
||||
#if UIP_CONF_IPV6_REASSEMBLY
|
||||
LOG_INFO("Processing fragmentation header\n");
|
||||
uip_len = uip_reass(&ext_ptr->next);
|
||||
if(uip_len == 0) {
|
||||
goto drop;
|
||||
}
|
||||
if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG) {
|
||||
/* we are not done with reassembly, this is an error message */
|
||||
goto send;
|
||||
}
|
||||
/* packet is reassembled. Restart the parsing of the reassembled pkt */
|
||||
LOG_INFO("Processing reassembled packet\n");
|
||||
uip_ext_bitmap = 0;
|
||||
next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
|
||||
break;
|
||||
#else /* UIP_CONF_IPV6_REASSEMBLY */
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
UIP_STAT(++uip_stat.ip.fragerr);
|
||||
LOG_ERR("fragment dropped.");
|
||||
goto drop;
|
||||
#endif /* UIP_CONF_IPV6_REASSEMBLY */
|
||||
case UIP_PROTO_NONE:
|
||||
goto drop;
|
||||
default:
|
||||
goto bad_hdr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process upper-layer input */
|
||||
if(next_header != NULL) {
|
||||
switch(protocol) {
|
||||
#if UIP_TCP
|
||||
case UIP_PROTO_TCP:
|
||||
/* TCP, for both IPv4 and IPv6 */
|
||||
goto tcp_input;
|
||||
#endif
|
||||
#if UIP_UDP
|
||||
case UIP_PROTO_UDP:
|
||||
/* UDP, for both IPv4 and IPv6 */
|
||||
goto udp_input;
|
||||
#endif
|
||||
case UIP_PROTO_ICMP6:
|
||||
/* ICMPv6 */
|
||||
goto icmp6_input;
|
||||
}
|
||||
}
|
||||
|
||||
bad_hdr:
|
||||
/*
|
||||
* RFC 2460 send error message parameterr problem, code unrecognized
|
||||
* next header, pointing to the next header field
|
||||
*/
|
||||
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, (uint32_t)(uip_next_hdr - (uint8_t *)UIP_IP_BUF));
|
||||
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, (uint32_t)(next_header - uip_buf));
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
UIP_STAT(++uip_stat.ip.protoerr);
|
||||
LOG_ERR("unrecognized header");
|
||||
LOG_ERR("unrecognized header\n");
|
||||
goto send;
|
||||
/* End of headers processing */
|
||||
|
||||
|
@ -1465,7 +1451,7 @@ uip_process(uint8_t flag)
|
|||
LOG_ERR("Unknown ICMPv6 message type/code %d\n", UIP_ICMP_BUF->type);
|
||||
UIP_STAT(++uip_stat.icmp.drop);
|
||||
UIP_STAT(++uip_stat.icmp.typeerr);
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
|
||||
if(uip_len > 0) {
|
||||
|
@ -1480,7 +1466,7 @@ uip_process(uint8_t flag)
|
|||
/* UDP input processing. */
|
||||
udp_input:
|
||||
|
||||
remove_ext_hdr();
|
||||
uip_remove_ext_hdr();
|
||||
|
||||
LOG_INFO("Receiving UDP packet\n");
|
||||
|
||||
|
@ -1540,10 +1526,10 @@ uip_process(uint8_t flag)
|
|||
UIP_STAT(++uip_stat.udp.recv);
|
||||
|
||||
uip_len = uip_len - UIP_IPUDPH_LEN;
|
||||
uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
|
||||
uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
|
||||
uip_conn = NULL;
|
||||
uip_flags = UIP_NEWDATA;
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
|
||||
uip_slen = 0;
|
||||
UIP_UDP_APPCALL();
|
||||
|
||||
|
@ -1557,8 +1543,7 @@ uip_process(uint8_t flag)
|
|||
|
||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
||||
length. */
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
UIP_IP_BUF->tcflow = 0x00;
|
||||
|
@ -1574,7 +1559,7 @@ uip_process(uint8_t flag)
|
|||
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_udp_conn->ripaddr);
|
||||
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
|
||||
|
||||
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
|
||||
uip_appdata = &uip_buf[UIP_IPTCPH_LEN];
|
||||
|
||||
#if UIP_UDP_CHECKSUMS
|
||||
/* Calculate UDP checksum. */
|
||||
|
@ -1592,7 +1577,7 @@ uip_process(uint8_t flag)
|
|||
/* TCP input processing. */
|
||||
tcp_input:
|
||||
|
||||
remove_ext_hdr();
|
||||
uip_remove_ext_hdr();
|
||||
|
||||
UIP_STAT(++uip_stat.tcp.recv);
|
||||
LOG_INFO("Receiving TCP packet\n");
|
||||
|
@ -1609,7 +1594,7 @@ uip_process(uint8_t flag)
|
|||
|
||||
/* Make sure that the TCP port number is not zero. */
|
||||
if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
|
||||
LOG_ERR("tcp: zero port.");
|
||||
LOG_ERR("tcp: zero port\n");
|
||||
goto drop;
|
||||
}
|
||||
|
||||
|
@ -1726,7 +1711,7 @@ uip_process(uint8_t flag)
|
|||
the remote end will retransmit the packet at a time when we
|
||||
have more spare connections. */
|
||||
UIP_STAT(++uip_stat.tcp.syndrop);
|
||||
LOG_ERR("tcp: found no unused connections.");
|
||||
LOG_ERR("tcp: found no unused connections\n");
|
||||
goto drop;
|
||||
}
|
||||
uip_conn = uip_connr;
|
||||
|
@ -1757,7 +1742,7 @@ uip_process(uint8_t flag)
|
|||
/* Parse the TCP MSS option, if present. */
|
||||
if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
|
||||
for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
|
||||
opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
|
||||
opt = uip_buf[UIP_IPTCPH_LEN + c];
|
||||
if(opt == TCP_OPT_END) {
|
||||
/* End of options. */
|
||||
break;
|
||||
|
@ -1765,10 +1750,10 @@ uip_process(uint8_t flag)
|
|||
++c;
|
||||
/* NOP option. */
|
||||
} else if(opt == TCP_OPT_MSS &&
|
||||
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
|
||||
uip_buf[UIP_IPTCPH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
|
||||
/* An MSS option with the right option length. */
|
||||
tmp16 = ((uint16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
|
||||
(uint16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
|
||||
tmp16 = ((uint16_t)uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
|
||||
(uint16_t)uip_buf[UIP_IPTCPH_LEN + 3 + c];
|
||||
uip_connr->initialmss = uip_connr->mss =
|
||||
tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
|
||||
|
||||
|
@ -1777,12 +1762,12 @@ uip_process(uint8_t flag)
|
|||
} else {
|
||||
/* All other options have a length field, so that we easily
|
||||
can skip past them. */
|
||||
if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
|
||||
if(uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
|
||||
/* If the length field is zero, the options are malformed
|
||||
and we don't process them further. */
|
||||
break;
|
||||
}
|
||||
c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
|
||||
c += uip_buf[UIP_IPTCPH_LEN + 1 + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1944,7 +1929,7 @@ uip_process(uint8_t flag)
|
|||
/* Parse the TCP MSS option, if present. */
|
||||
if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
|
||||
for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
|
||||
opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
|
||||
opt = uip_buf[UIP_IPTCPH_LEN + c];
|
||||
if(opt == TCP_OPT_END) {
|
||||
/* End of options. */
|
||||
break;
|
||||
|
@ -1952,10 +1937,10 @@ uip_process(uint8_t flag)
|
|||
++c;
|
||||
/* NOP option. */
|
||||
} else if(opt == TCP_OPT_MSS &&
|
||||
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
|
||||
uip_buf[UIP_IPTCPH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
|
||||
/* An MSS option with the right option length. */
|
||||
tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
|
||||
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
|
||||
tmp16 = (uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
|
||||
uip_buf[UIP_IPTCPH_LEN + 3 + c];
|
||||
uip_connr->initialmss =
|
||||
uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
|
||||
|
||||
|
@ -1964,12 +1949,12 @@ uip_process(uint8_t flag)
|
|||
} else {
|
||||
/* All other options have a length field, so that we easily
|
||||
can skip past them. */
|
||||
if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
|
||||
if(uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
|
||||
/* If the length field is zero, the options are malformed
|
||||
and we don't process them further. */
|
||||
break;
|
||||
}
|
||||
c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
|
||||
c += uip_buf[UIP_IPTCPH_LEN + 1 + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1981,7 +1966,7 @@ uip_process(uint8_t flag)
|
|||
uip_add_rcv_nxt(1);
|
||||
uip_flags = UIP_CONNECTED | UIP_NEWDATA;
|
||||
uip_connr->len = 0;
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
uip_slen = 0;
|
||||
UIP_APPCALL();
|
||||
goto appsend;
|
||||
|
@ -2083,7 +2068,7 @@ uip_process(uint8_t flag)
|
|||
When the application is called, the global variable uip_len
|
||||
contains the length of the incoming data. The application can
|
||||
access the incoming data through the global pointer
|
||||
uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
|
||||
uip_appdata, which usually points UIP_IPTCPH_LEN
|
||||
bytes into the uip_buf array.
|
||||
|
||||
If the application wishes to send any data, this data should be
|
||||
|
@ -2152,7 +2137,7 @@ uip_process(uint8_t flag)
|
|||
packet had new data in it, we must send out a packet. */
|
||||
if(uip_slen > 0 && uip_connr->len > 0) {
|
||||
/* Add the length of the IP and TCP headers. */
|
||||
uip_len = uip_connr->len + UIP_TCPIP_HLEN;
|
||||
uip_len = uip_connr->len + UIP_IPTCPH_LEN;
|
||||
/* We always set the ACK flag in response packets. */
|
||||
UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
|
||||
/* Send the packet. */
|
||||
|
@ -2161,7 +2146,7 @@ uip_process(uint8_t flag)
|
|||
/* If there is no data to send, just send out a pure ACK if
|
||||
there is newdata. */
|
||||
if(uip_flags & UIP_NEWDATA) {
|
||||
uip_len = UIP_TCPIP_HLEN;
|
||||
uip_len = UIP_IPTCPH_LEN;
|
||||
UIP_TCP_BUF->flags = TCP_ACK;
|
||||
goto tcp_send_noopts;
|
||||
}
|
||||
|
@ -2289,8 +2274,7 @@ uip_process(uint8_t flag)
|
|||
UIP_IP_BUF->proto = UIP_PROTO_TCP;
|
||||
|
||||
UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
|
||||
|
||||
|
@ -2305,8 +2289,7 @@ uip_process(uint8_t flag)
|
|||
#endif
|
||||
UIP_IP_BUF->flow = 0x00;
|
||||
send:
|
||||
LOG_INFO("Sending packet with length %d (%d)\n", uip_len,
|
||||
(UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]);
|
||||
LOG_INFO("Sending packet with length %d (%d)\n", uip_len, uipbuf_get_len_field(UIP_IP_BUF));
|
||||
|
||||
UIP_STAT(++uip_stat.ip.sent);
|
||||
/* Return and let the caller do the actual transmission. */
|
||||
|
@ -2314,7 +2297,7 @@ uip_process(uint8_t flag)
|
|||
return;
|
||||
|
||||
drop:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
uip_ext_bitmap = 0;
|
||||
uip_flags = 0;
|
||||
return;
|
||||
|
@ -2338,18 +2321,16 @@ uip_send(const void *data, int len)
|
|||
int copylen;
|
||||
|
||||
if(uip_sappdata != NULL) {
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
|
||||
(int)((char *)uip_sappdata -
|
||||
(char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]));
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_IPTCPH_LEN -
|
||||
(int)((char *)uip_sappdata - (char *)UIP_TCP_PAYLOAD));
|
||||
} else {
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN);
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_IPTCPH_LEN);
|
||||
}
|
||||
if(copylen > 0) {
|
||||
uip_slen = copylen;
|
||||
if(data != uip_sappdata) {
|
||||
if(uip_sappdata == NULL) {
|
||||
memcpy((char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN],
|
||||
(data), uip_slen);
|
||||
memcpy(UIP_TCP_PAYLOAD, (data), uip_slen);
|
||||
} else {
|
||||
memcpy(uip_sappdata, (data), uip_slen);
|
||||
}
|
||||
|
|
|
@ -30,53 +30,150 @@
|
|||
*
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "uip.h"
|
||||
#include "net/ipv6/uip.h"
|
||||
#include "net/ipv6/uipbuf.h"
|
||||
#include <string.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static uint16_t uipbuf_attrs[UIPBUF_ATTR_MAX];
|
||||
static uint16_t uipbuf_default_attrs[UIPBUF_ATTR_MAX];
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uipbuf_clear(void)
|
||||
{
|
||||
uip_len = 0;
|
||||
uip_ext_len = 0;
|
||||
uip_last_proto = 0;
|
||||
uipbuf_clear_attr();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
uipbuf_add_ext_hdr(int16_t len)
|
||||
{
|
||||
if(len + uip_len <= UIP_LINK_MTU && len + uip_len >= 0) {
|
||||
uip_ext_len += len;
|
||||
uip_len += len;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
uipbuf_set_len(uint16_t len)
|
||||
{
|
||||
if(len <= UIP_LINK_MTU) {
|
||||
uip_len = len;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uipbuf_set_len_field(struct uip_ip_hdr *hdr, uint16_t len)
|
||||
{
|
||||
hdr->len[0] = (len >> 8);
|
||||
hdr->len[1] = (len & 0xff);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint16_t
|
||||
uipbuf_get_len_field(struct uip_ip_hdr *hdr)
|
||||
{
|
||||
return ((uint16_t)(hdr->len[0]) << 8) + hdr->len[1];
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Get the next header given the buffer - start indicates that this is
|
||||
start of the IPv6 header - needs to be set to 0 when in an ext hdr */
|
||||
uint8_t*
|
||||
uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, uint8_t start)
|
||||
uint8_t *
|
||||
uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, bool start)
|
||||
{
|
||||
int ext_len = 0;
|
||||
struct uip_ip_hdr *ipbuf = (struct uip_ip_hdr *) buffer;
|
||||
struct uip_ext_hdr *ext = NULL;
|
||||
int curr_hdr_len = 0;
|
||||
int next_hdr_len = 0;
|
||||
uint8_t *next_header = NULL;
|
||||
struct uip_ip_hdr *ipbuf = NULL;
|
||||
struct uip_ext_hdr *curr_ext = NULL;
|
||||
struct uip_ext_hdr *next_ext = NULL;
|
||||
|
||||
if(start) {
|
||||
/* protocol in the IP buffer */
|
||||
ipbuf = (struct uip_ip_hdr *)buffer;
|
||||
*protocol = ipbuf->proto;
|
||||
return buffer + UIP_IPH_LEN;
|
||||
curr_hdr_len = UIP_IPH_LEN;
|
||||
} else {
|
||||
/* protocol in the Ext hdr */
|
||||
ext = (struct uip_ext_hdr *) buffer;
|
||||
*protocol = ext->next;
|
||||
curr_ext = (struct uip_ext_hdr *)buffer;
|
||||
*protocol = curr_ext->next;
|
||||
/* This is just an ext header */
|
||||
ext_len = (ext->len << 3) + 8;
|
||||
return buffer + ext_len;
|
||||
curr_hdr_len = (curr_ext->len << 3) + 8;
|
||||
}
|
||||
|
||||
/* Check first if enough space for current header */
|
||||
if(curr_hdr_len > size) {
|
||||
return NULL;
|
||||
}
|
||||
next_header = buffer + curr_hdr_len;
|
||||
|
||||
/* Check if the buffer is large enough for the next header */
|
||||
if(uip_is_proto_ext_hdr(*protocol)) {
|
||||
next_ext = (struct uip_ext_hdr *)next_header;
|
||||
next_hdr_len = (next_ext->len << 3) + 8;
|
||||
} else {
|
||||
if(*protocol == UIP_PROTO_TCP) {
|
||||
next_hdr_len = UIP_TCPH_LEN;
|
||||
} else if(*protocol == UIP_PROTO_UDP) {
|
||||
next_hdr_len = UIP_UDPH_LEN;
|
||||
} else if(*protocol == UIP_PROTO_ICMP6) {
|
||||
next_hdr_len = UIP_ICMPH_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Size must be enough to hold both the current and next header */
|
||||
if(next_hdr_len == 0 || curr_hdr_len + next_hdr_len > size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return next_header;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Get the final header given the buffer - that is assumed to be at start
|
||||
of an IPv6 header */
|
||||
uint8_t*
|
||||
uint8_t *
|
||||
uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol)
|
||||
{
|
||||
uint8_t *nbuf;
|
||||
|
||||
nbuf = uipbuf_get_next_header(buffer, size, protocol, 1);
|
||||
while(uip_is_proto_ext_hdr(*protocol)) {
|
||||
/* send in and move beyond the ext hdr */
|
||||
nbuf = uipbuf_get_next_header(nbuf, size - (nbuf - buffer), protocol, 0);
|
||||
nbuf = uipbuf_get_next_header(buffer, size, protocol, true);
|
||||
while(nbuf != NULL && uip_is_proto_ext_hdr(*protocol)) {
|
||||
/* move to the ext hdr */
|
||||
nbuf = uipbuf_get_next_header(nbuf, size - (nbuf - buffer), protocol, false);
|
||||
}
|
||||
|
||||
/* In case the buffer wasn't large enough for all headers, return NULL */
|
||||
return nbuf;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t *
|
||||
uipbuf_search_header(uint8_t *buffer, uint16_t size, uint8_t protocol)
|
||||
{
|
||||
uint8_t *nbuf;
|
||||
uint8_t next_proto;
|
||||
|
||||
nbuf = uipbuf_get_next_header(buffer, size, &next_proto, true);
|
||||
while(nbuf != NULL && next_proto != protocol && uip_is_proto_ext_hdr(next_proto)) {
|
||||
/* move to the ext hdr */
|
||||
nbuf = uipbuf_get_next_header(nbuf, size - (nbuf - buffer), &next_proto, false);
|
||||
}
|
||||
|
||||
if(next_proto == protocol) {
|
||||
return nbuf;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Common functions for uipbuf (attributes, etc).
|
||||
*
|
||||
|
@ -101,15 +198,21 @@ uipbuf_set_attr(uint8_t type, uint16_t value)
|
|||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
uipbuf_set_default_attr(uint8_t type, uint16_t value)
|
||||
{
|
||||
if(type < UIPBUF_ATTR_MAX) {
|
||||
uipbuf_default_attrs[type] = value;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uipbuf_clear_attr(void)
|
||||
{
|
||||
/* set everything to "zero" */
|
||||
memset(uipbuf_attrs, 0, sizeof(uipbuf_attrs));
|
||||
|
||||
/* And initialize anything that should be initialized */
|
||||
uipbuf_set_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS,
|
||||
UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED);
|
||||
/* set everything to "defaults" */
|
||||
memcpy(uipbuf_attrs, uipbuf_default_attrs, sizeof(uipbuf_attrs));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -131,3 +234,17 @@ uipbuf_is_attr_flag(uint16_t flag)
|
|||
return (uipbuf_attrs[UIPBUF_ATTR_FLAGS] & flag) == flag;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uipbuf_init(void)
|
||||
{
|
||||
memset(uipbuf_default_attrs, 0, sizeof(uipbuf_default_attrs));
|
||||
/* And initialize anything that should be initialized */
|
||||
uipbuf_set_default_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS,
|
||||
UIP_MAX_MAC_TRANSMISSIONS_UNDEFINED);
|
||||
/* set the not-set default value - this will cause the MAC layer to
|
||||
configure its default */
|
||||
uipbuf_set_default_attr(UIPBUF_ATTR_LLSEC_LEVEL,
|
||||
UIPBUF_ATTR_LLSEC_LEVEL_MAC_DEFAULT);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -34,6 +34,40 @@
|
|||
#define UIPBUF_H_
|
||||
|
||||
#include "contiki.h"
|
||||
struct uip_ip_hdr;
|
||||
|
||||
/**
|
||||
* \brief Resets uIP buffer
|
||||
*/
|
||||
void uipbuf_clear(void);
|
||||
|
||||
/**
|
||||
* \brief Update uip buffer length for addition of an extension header
|
||||
* \param len The length of the new extension header
|
||||
* \retval true if the length fields were successfully set, false otherwise
|
||||
*/
|
||||
bool uipbuf_add_ext_hdr(int16_t len);
|
||||
|
||||
/**
|
||||
* \brief Set the length of the uIP buffer
|
||||
* \param len The new length
|
||||
* \retval true if the len was successfully set, false otherwise
|
||||
*/
|
||||
bool uipbuf_set_len(uint16_t len);
|
||||
|
||||
/**
|
||||
* \brief Updates the length field in the uIP buffer
|
||||
* \param buffer The IPv6 header
|
||||
* \param len The new length value
|
||||
*/
|
||||
void uipbuf_set_len_field(struct uip_ip_hdr *hdr, uint16_t len);
|
||||
|
||||
/**
|
||||
* \brief Returns the value of the length field in the uIP buffer
|
||||
* \param buffer The IPv6 header
|
||||
* \retvel The length value
|
||||
*/
|
||||
uint16_t uipbuf_get_len_field(struct uip_ip_hdr *hdr);
|
||||
|
||||
/**
|
||||
* \brief Get the next IPv6 header.
|
||||
|
@ -41,11 +75,11 @@
|
|||
* \param size The size of the data in the buffer
|
||||
* \param protocol A pointer to a variable where the protocol of the header will be stored
|
||||
* \param start A flag that indicates if this is expected to be the IPv6 packet header or a later header (Extension header)
|
||||
* \retval returns address of the starting position of the next header
|
||||
* \retval returns address of the next header, or NULL in case of insufficient buffer space
|
||||
*
|
||||
* This function moves to the next header in a IPv6 packet.
|
||||
*/
|
||||
uint8_t* uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, uint8_t start);
|
||||
uint8_t *uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, bool start);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -53,12 +87,22 @@ uint8_t* uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protoco
|
|||
* \param buffer A pointer to the buffer holding the IPv6 packet
|
||||
* \param size The size of the data in the buffer
|
||||
* \param protocol A pointer to a variable where the protocol of the header will be stored
|
||||
* \retval returns address of the starting position of the next header
|
||||
* \retval returns address of the last header, or NULL in case of insufficient buffer space
|
||||
*
|
||||
* This function moves to the last header of the IPv6 packet.
|
||||
*/
|
||||
uint8_t* uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol);
|
||||
uint8_t *uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol);
|
||||
|
||||
/**
|
||||
* \brief Get an IPv6 header with a given protocol field.
|
||||
* \param buffer A pointer to the buffer holding the IPv6 packet
|
||||
* \param size The size of the data in the buffer
|
||||
* \param protocol The protocol we are looking for
|
||||
* \retval returns address of the header if found, else NULL
|
||||
*
|
||||
* This function moves to the last header of the IPv6 packet.
|
||||
*/
|
||||
uint8_t *uipbuf_search_header(uint8_t *buffer, uint16_t size, uint8_t protocol);
|
||||
|
||||
/**
|
||||
* \brief Get the value of the attribute
|
||||
|
@ -81,6 +125,17 @@ uint16_t uipbuf_get_attr(uint8_t type);
|
|||
*/
|
||||
int uipbuf_set_attr(uint8_t type, uint16_t value);
|
||||
|
||||
/**
|
||||
* \brief Set the default value of the attribute
|
||||
* \param type The attribute to set the default value of
|
||||
* \param value The value to set
|
||||
* \retval 0 - indicates failure of setting the value
|
||||
* \retval 1 - indicates success of setting the value
|
||||
*
|
||||
* This function sets the default value of a uipbuf attribute.
|
||||
*/
|
||||
int uipbuf_set_default_attr(uint8_t type, uint16_t value);
|
||||
|
||||
/**
|
||||
* \brief Set bits in the uipbuf attribute flags.
|
||||
* \param flag_bits The bits to set in the flag.
|
||||
|
@ -115,6 +170,14 @@ uint16_t uipbuf_is_attr_flag(uint16_t flag_bits);
|
|||
*/
|
||||
void uipbuf_clear_attr(void);
|
||||
|
||||
/**
|
||||
* \brief Initialize uipbuf attributes.
|
||||
*
|
||||
* This function initialize all attributes in the uipbuf
|
||||
* attributes including all flags.
|
||||
*/
|
||||
void uipbuf_init(void);
|
||||
|
||||
/**
|
||||
* \brief The bits defined for uipbuf attributes flag.
|
||||
*
|
||||
|
@ -124,6 +187,9 @@ void uipbuf_clear_attr(void);
|
|||
/* Avoid using prefix compression on the packet (6LoWPAN) */
|
||||
#define UIPBUF_ATTR_FLAGS_6LOWPAN_NO_PREFIX_COMPRESSION 0x02
|
||||
|
||||
/* MAC will set the default for this packet */
|
||||
#define UIPBUF_ATTR_LLSEC_LEVEL_MAC_DEFAULT 0xffff
|
||||
|
||||
/**
|
||||
* \brief The attributes defined for uipbuf attributes function.
|
||||
*
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
#define LOG_LEVEL LOG_LEVEL_NONE
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
int
|
||||
uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr)
|
||||
{
|
||||
|
@ -118,7 +117,6 @@ uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr)
|
|||
|
||||
return 1;
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Parse a IPv4-address from a string. Returns the number of characters read
|
||||
* for the address. */
|
||||
|
|
|
@ -68,11 +68,7 @@
|
|||
* \retval 0 If the IP address could not be parsed.
|
||||
* \retval Non-zero If the IP address was parsed.
|
||||
*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#define uiplib_ipaddrconv uiplib_ip6addrconv
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
#define uiplib_ipaddrconv uiplib_ip4addrconv
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
int uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *addr);
|
||||
int uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *addr);
|
||||
|
|
|
@ -121,26 +121,6 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The link level header length.
|
||||
*
|
||||
* This is the offset into the uip_buf where the IP header can be
|
||||
* found. For Ethernet, this should be set to 14. For SLIP, this
|
||||
* should be set to 0.
|
||||
*
|
||||
* \note we probably won't use this constant for other link layers than
|
||||
* ethernet as they have variable header length (this is due to variable
|
||||
* number and type of address fields and to optional security features)
|
||||
* E.g.: 802.15.4 -> 2 + (1/2*4/8) + 0/5/6/10/14
|
||||
* 802.11 -> 4 + (6*3/4) + 2
|
||||
* \hideinitializer
|
||||
*/
|
||||
#ifdef UIP_CONF_LLH_LEN
|
||||
#define UIP_LLH_LEN (UIP_CONF_LLH_LEN)
|
||||
#else /* UIP_LLH_LEN */
|
||||
#define UIP_LLH_LEN 0
|
||||
#endif /* UIP_CONF_LLH_LEN */
|
||||
|
||||
/**
|
||||
* The size of the uIP packet buffer.
|
||||
*
|
||||
|
@ -151,12 +131,11 @@
|
|||
* \hideinitializer
|
||||
*/
|
||||
#ifndef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_BUFSIZE (UIP_LINK_MTU + UIP_LLH_LEN)
|
||||
#define UIP_BUFSIZE (UIP_LINK_MTU)
|
||||
#else /* UIP_CONF_BUFFER_SIZE */
|
||||
#define UIP_BUFSIZE (UIP_CONF_BUFFER_SIZE)
|
||||
#endif /* UIP_CONF_BUFFER_SIZE */
|
||||
|
||||
|
||||
/**
|
||||
* Determines if statistics support should be compiled in.
|
||||
*
|
||||
|
@ -248,11 +227,6 @@ void uip_log(char *msg);
|
|||
/** The maximum transmission unit at the IP Layer*/
|
||||
#define UIP_LINK_MTU 1280
|
||||
|
||||
#ifndef NETSTACK_CONF_WITH_IPV6
|
||||
/** Do we use IPv6 or not (default: no) */
|
||||
#define NETSTACK_CONF_WITH_IPV6 0
|
||||
#endif
|
||||
|
||||
#ifndef UIP_CONF_IPV6_QUEUE_PKT
|
||||
/** Do we do per %neighbor queuing during address resolution (default: no) */
|
||||
#define UIP_CONF_IPV6_QUEUE_PKT 0
|
||||
|
@ -440,15 +414,15 @@ void uip_log(char *msg);
|
|||
* The TCP maximum segment size.
|
||||
*
|
||||
* This is should not be to set to more than
|
||||
* UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
|
||||
* UIP_BUFSIZE - UIP_IPTCPH_LEN.
|
||||
*/
|
||||
#ifdef UIP_CONF_TCP_MSS
|
||||
#if UIP_CONF_TCP_MSS > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
|
||||
#if UIP_CONF_TCP_MSS > (UIP_BUFSIZE - UIP_IPTCPH_LEN)
|
||||
#error UIP_CONF_TCP_MSS is too large for the current UIP_BUFSIZE
|
||||
#endif /* UIP_CONF_TCP_MSS > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) */
|
||||
#endif /* UIP_CONF_TCP_MSS > (UIP_BUFSIZE - UIP_IPTCPH_LEN) */
|
||||
#define UIP_TCP_MSS (UIP_CONF_TCP_MSS)
|
||||
#else /* UIP_CONF_TCP_MSS */
|
||||
#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
|
||||
#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_IPTCPH_LEN)
|
||||
#endif /* UIP_CONF_TCP_MSS */
|
||||
|
||||
/**
|
||||
|
|
|
@ -505,6 +505,12 @@ off(void)
|
|||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
max_payload(void)
|
||||
{
|
||||
return BLE_L2CAP_NODE_MTU;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct mac_driver ble_l2cap_driver = {
|
||||
"ble-l2cap",
|
||||
init,
|
||||
|
@ -512,6 +518,7 @@ const struct mac_driver ble_l2cap_driver = {
|
|||
input,
|
||||
on,
|
||||
off,
|
||||
max_payload,
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(ble_l2cap_tx_process, ev, data)
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 2014, Hasso-Plattner-Institut.
|
||||
* 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
|
||||
* Protects against replay attacks by comparing with the last
|
||||
* unicast or broadcast frame counter of the sender.
|
||||
* \author
|
||||
* Konrad Krentz <konrad.krentz@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup csma
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "net/mac/csma/anti-replay.h"
|
||||
#include "net/packetbuf.h"
|
||||
#include "net/mac/llsec802154.h"
|
||||
|
||||
#if LLSEC802154_USES_FRAME_COUNTER
|
||||
|
||||
/* This node's current frame counter value */
|
||||
static uint32_t counter;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
anti_replay_set_counter(void)
|
||||
{
|
||||
frame802154_frame_counter_t reordered_counter;
|
||||
|
||||
++counter;
|
||||
reordered_counter.u32 = LLSEC802154_HTONL(counter);
|
||||
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, reordered_counter.u16[0]);
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, reordered_counter.u16[1]);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint32_t
|
||||
anti_replay_get_counter(void)
|
||||
{
|
||||
frame802154_frame_counter_t disordered_counter;
|
||||
|
||||
disordered_counter.u16[0] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1);
|
||||
disordered_counter.u16[1] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3);
|
||||
|
||||
return LLSEC802154_HTONL(disordered_counter.u32);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
anti_replay_init_info(struct anti_replay_info *info)
|
||||
{
|
||||
info->last_broadcast_counter
|
||||
= info->last_unicast_counter
|
||||
= anti_replay_get_counter();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
anti_replay_was_replayed(struct anti_replay_info *info)
|
||||
{
|
||||
uint32_t received_counter;
|
||||
|
||||
received_counter = anti_replay_get_counter();
|
||||
|
||||
if(packetbuf_holds_broadcast()) {
|
||||
/* broadcast */
|
||||
if(received_counter <= info->last_broadcast_counter) {
|
||||
return 1;
|
||||
} else {
|
||||
info->last_broadcast_counter = received_counter;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
/* unicast */
|
||||
if(received_counter <= info->last_unicast_counter) {
|
||||
return 1;
|
||||
} else {
|
||||
info->last_unicast_counter = received_counter;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* LLSEC802154_USES_FRAME_COUNTER */
|
||||
|
||||
/** @} */
|
|
@ -1,6 +1,5 @@
|
|||
/* -*- C -*- */
|
||||
/*
|
||||
* Copyright (c) 2005, Swedish Institute of Computer Science
|
||||
* Copyright (c) 2014, Hasso-Plattner-Institut.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -31,62 +30,51 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef SLIP_H_
|
||||
#define SLIP_H_
|
||||
/**
|
||||
* \file
|
||||
* Interface to anti-replay mechanisms.
|
||||
* \author
|
||||
* Konrad Krentz <konrad.krentz@gmail.com>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup llsec802154
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef ANTI_REPLAY_H
|
||||
#define ANTI_REPLAY_H
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
PROCESS_NAME(slip_process);
|
||||
struct anti_replay_info {
|
||||
uint32_t last_broadcast_counter;
|
||||
uint32_t last_unicast_counter;
|
||||
};
|
||||
|
||||
/**
|
||||
* Send an IP packet from the uIP buffer with SLIP.
|
||||
* \brief Sets the frame counter packetbuf attributes.
|
||||
*/
|
||||
uint8_t slip_send(void);
|
||||
void anti_replay_set_counter(void);
|
||||
|
||||
/**
|
||||
* Input a SLIP byte.
|
||||
*
|
||||
* This function is called by the RS232/SIO device driver to pass
|
||||
* incoming bytes to the SLIP driver. The function can be called from
|
||||
* an interrupt context.
|
||||
*
|
||||
* For systems using low-power CPU modes, the return value of the
|
||||
* function can be used to determine if the CPU should be woken up or
|
||||
* not. If the function returns non-zero, the CPU should be powered
|
||||
* up. If the function returns zero, the CPU can continue to be
|
||||
* powered down.
|
||||
*
|
||||
* \param c The data that is to be passed to the SLIP driver
|
||||
*
|
||||
* \return Non-zero if the CPU should be powered up, zero otherwise.
|
||||
* \brief Gets the frame counter from packetbuf.
|
||||
*/
|
||||
int slip_input_byte(unsigned char c);
|
||||
|
||||
uint8_t slip_write(const void *ptr, int len);
|
||||
|
||||
/* Did we receive any bytes lately? */
|
||||
extern uint8_t slip_active;
|
||||
|
||||
/* Statistics. */
|
||||
extern uint16_t slip_rubbish, slip_twopackets, slip_overflow, slip_ip_drop;
|
||||
uint32_t anti_replay_get_counter(void);
|
||||
|
||||
/**
|
||||
* Set a function to be called when there is activity on the SLIP
|
||||
* interface; used for detecting if a node is a gateway node.
|
||||
* \brief Initializes the anti-replay information about the sender
|
||||
* \param info Anti-replay information about the sender
|
||||
*/
|
||||
void slip_set_input_callback(void (*callback)(void));
|
||||
void anti_replay_init_info(struct anti_replay_info *info);
|
||||
|
||||
/**
|
||||
* Set a function to be called when a packet has been received.
|
||||
* Default is tcpip_input().
|
||||
* \brief Checks if received frame was replayed
|
||||
* \param info Anti-replay information about the sender
|
||||
* \retval 0 <-> received frame was not replayed
|
||||
*/
|
||||
void slip_set_tcpip_input_callback(void (*callback)(void));
|
||||
int anti_replay_was_replayed(struct anti_replay_info *info);
|
||||
|
||||
/*
|
||||
* These machine dependent functions and an interrupt service routine
|
||||
* must be provided externally (slip_arch.c).
|
||||
*/
|
||||
void slip_arch_init(void);
|
||||
void slip_arch_writeb(unsigned char c);
|
||||
#endif /* ANTI_REPLAY_H */
|
||||
|
||||
#endif /* SLIP_H_ */
|
||||
/** @} */
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (c) 2013, Hasso-Plattner-Institut.
|
||||
* 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
|
||||
* CCM* convenience functions for LLSEC use
|
||||
* \author
|
||||
* Justin King-Lacroix <justin.kinglacroix@gmail.com>
|
||||
* Konrad Krentz <konrad.krentz@gmail.com>
|
||||
*/
|
||||
|
||||
#include "net/linkaddr.h"
|
||||
#include "net/packetbuf.h"
|
||||
#include "net/mac/llsec802154.h"
|
||||
#include <string.h>
|
||||
|
||||
#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static const uint8_t *
|
||||
get_extended_address(const linkaddr_t *addr)
|
||||
#if LINKADDR_SIZE == 2
|
||||
{
|
||||
/* workaround for short addresses: derive EUI64 as in RFC 6282 */
|
||||
static linkaddr_extended_t template = { { 0x00 , 0x00 , 0x00 ,
|
||||
0xFF , 0xFE , 0x00 , 0x00 , 0x00 } };
|
||||
template.u16[3] = LLSEC802154_HTONS(addr->u16);
|
||||
|
||||
return template.u8;
|
||||
}
|
||||
#else /* LINKADDR_SIZE == 2 */
|
||||
{
|
||||
return addr->u8;
|
||||
}
|
||||
#endif /* LINKADDR_SIZE == 2 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward)
|
||||
{
|
||||
const linkaddr_t *source_addr;
|
||||
|
||||
source_addr = forward ? &linkaddr_node_addr : packetbuf_addr(PACKETBUF_ADDR_SENDER);
|
||||
memcpy(nonce, get_extended_address(source_addr), 8);
|
||||
nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8;
|
||||
nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff;
|
||||
nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8;
|
||||
nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff;
|
||||
nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER */
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Swedish Institute of Computer Science.
|
||||
* Copyright (c) 2013, Hasso-Plattner-Institut.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
@ -26,24 +26,14 @@
|
|||
* 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
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
*/
|
||||
#ifndef CCM_STAR_PACKETBUF_H_
|
||||
#define CCM_STAR_PACKETBUF_H_
|
||||
|
||||
#ifndef BRIDGE_CONF_H_
|
||||
#define BRIDGE_CONF_H_
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void ccm_star_packetbuf_set_nonce(uint8_t *nonce, int forward);
|
||||
|
||||
#undef UIP_CONF_ROUTER
|
||||
|
||||
#undef UIP_CONF_LLH_LEN
|
||||
#define UIP_CONF_LLH_LEN 14
|
||||
|
||||
#undef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 256
|
||||
#endif /* BRIDGE_CONF_H_ */
|
||||
#endif /* CCM_STAR_PACKETBUF_H_ */
|
|
@ -40,6 +40,7 @@
|
|||
*/
|
||||
|
||||
#include "net/mac/csma/csma.h"
|
||||
#include "net/mac/csma/csma-security.h"
|
||||
#include "net/packetbuf.h"
|
||||
#include "net/queuebuf.h"
|
||||
#include "dev/watchdog.h"
|
||||
|
@ -169,9 +170,16 @@ send_one_packet(void *ptr)
|
|||
packetbuf_set_addr(PACKETBUF_ADDR_SENDER, &linkaddr_node_addr);
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_MAC_ACK, 1);
|
||||
|
||||
if(NETSTACK_FRAMER.create() < 0) {
|
||||
#if LLSEC802154_ENABLED
|
||||
#if LLSEC802154_USES_EXPLICIT_KEYS
|
||||
/* This should possibly be taken from upper layers in the future */
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_KEY_ID_MODE, CSMA_LLSEC_KEY_ID_MODE);
|
||||
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
|
||||
if(csma_security_create_frame() < 0) {
|
||||
/* Failed to allocate space for headers */
|
||||
LOG_ERR("failed to create packet\n");
|
||||
LOG_ERR("failed to create packet, seqno: %d\n", packetbuf_attr(PACKETBUF_ATTR_MAC_SEQNO));
|
||||
ret = MAC_TX_ERR_FATAL;
|
||||
} else {
|
||||
int is_broadcast;
|
||||
|
@ -539,5 +547,4 @@ csma_output_init(void)
|
|||
memb_init(&packet_memb);
|
||||
memb_init(&metadata_memb);
|
||||
memb_init(&neighbor_memb);
|
||||
queuebuf_init();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,308 @@
|
|||
/*
|
||||
* Copyright (c) 2017, RISE SICS
|
||||
* 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
|
||||
* CSMA security
|
||||
* \author
|
||||
* Joakim Eriksson <joakim.eriksson@ri.se>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup csma
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "net/mac/csma/csma.h"
|
||||
#include "net/mac/csma/anti-replay.h"
|
||||
#include "net/mac/csma/csma-security.h"
|
||||
#include "net/mac/framer/frame802154.h"
|
||||
#include "net/mac/framer/framer-802154.h"
|
||||
#include "net/mac/llsec802154.h"
|
||||
#include "net/netstack.h"
|
||||
#include "net/packetbuf.h"
|
||||
#include "lib/ccm-star.h"
|
||||
#include "lib/aes-128.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "ccm-star-packetbuf.h"
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "CSMA"
|
||||
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||
|
||||
#if LOG_LEVEL == LOG_LEVEL_DBG
|
||||
static const char * HEX = "0123456789ABCDEF";
|
||||
#endif
|
||||
|
||||
#if LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER
|
||||
|
||||
#define MIC_LEN(level) LLSEC802154_MIC_LEN(level)
|
||||
|
||||
#if LLSEC802154_USES_EXPLICIT_KEYS
|
||||
#define LLSEC_KEY_INDEX (FRAME802154_IMPLICIT_KEY == packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE) \
|
||||
? 0 \
|
||||
: packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX))
|
||||
#define LLSEC_KEY_MODE (packetbuf_attr(PACKETBUF_ATTR_KEY_ID_MODE))
|
||||
#else
|
||||
#define LLSEC_KEY_INDEX (0)
|
||||
#define LLSEC_KEY_MODE (FRAME802154_IMPLICIT_KEY)
|
||||
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
|
||||
|
||||
/**
|
||||
* The keys for LLSEC for CSMA
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t u8[16];
|
||||
} aes_key_t;
|
||||
static aes_key_t keys[CSMA_LLSEC_MAXKEYS];
|
||||
|
||||
/* assumed to be 16 bytes */
|
||||
int
|
||||
csma_security_set_key(uint8_t index, const uint8_t *key)
|
||||
{
|
||||
if(key != NULL && index < CSMA_LLSEC_MAXKEYS) {
|
||||
memcpy(keys[index].u8, key, 16);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define N_KEYS (sizeof(keys) / sizeof(aes_key))
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
aead(uint8_t hdrlen, int forward)
|
||||
{
|
||||
uint8_t totlen;
|
||||
uint8_t nonce[CCM_STAR_NONCE_LENGTH];
|
||||
uint8_t *m;
|
||||
uint8_t m_len;
|
||||
uint8_t *a;
|
||||
uint8_t a_len;
|
||||
uint8_t *result;
|
||||
/* Allocate for MAX level */
|
||||
uint8_t generated_mic[MIC_LEN(7)];
|
||||
uint8_t *mic;
|
||||
uint8_t key_index;
|
||||
aes_key_t *key;
|
||||
uint8_t with_encryption;
|
||||
|
||||
key_index = LLSEC_KEY_INDEX;
|
||||
if(key_index >= CSMA_LLSEC_MAXKEYS) {
|
||||
LOG_ERR("Key not available: %u\n", key_index);
|
||||
return 0;
|
||||
}
|
||||
|
||||
key = &keys[key_index];
|
||||
|
||||
ccm_star_packetbuf_set_nonce(nonce, forward);
|
||||
totlen = packetbuf_totlen();
|
||||
a = packetbuf_hdrptr();
|
||||
|
||||
with_encryption =
|
||||
(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x4) ? 1 : 0;
|
||||
|
||||
if(with_encryption) {
|
||||
a_len = hdrlen;
|
||||
m = a + a_len;
|
||||
m_len = totlen - hdrlen;
|
||||
} else {
|
||||
a_len = totlen;
|
||||
m = NULL;
|
||||
m_len = 0;
|
||||
}
|
||||
|
||||
mic = a + totlen;
|
||||
result = forward ? mic : generated_mic;
|
||||
|
||||
CCM_STAR.set_key(key->u8);
|
||||
CCM_STAR.aead(nonce,
|
||||
m, m_len,
|
||||
a, a_len,
|
||||
result, MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07),
|
||||
forward);
|
||||
|
||||
if(forward) {
|
||||
packetbuf_set_datalen(packetbuf_datalen() + MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07));
|
||||
return 1;
|
||||
} else {
|
||||
return (memcmp(generated_mic, mic, MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07)) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
csma_security_create_frame(void)
|
||||
{
|
||||
int hdr_len;
|
||||
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
|
||||
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0 &&
|
||||
LLSEC_KEY_INDEX != 0xffff) {
|
||||
anti_replay_set_counter();
|
||||
}
|
||||
|
||||
hdr_len = NETSTACK_FRAMER.create();
|
||||
if(hdr_len < 0) {
|
||||
return hdr_len;
|
||||
}
|
||||
|
||||
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0) {
|
||||
#if LOG_LEVEL == LOG_LEVEL_DBG
|
||||
int i = 0;
|
||||
uint8_t *p;
|
||||
LOG_DBG(" Payload before (%d):", packetbuf_totlen());
|
||||
p = packetbuf_hdrptr();
|
||||
for(i = 0; i < packetbuf_totlen(); i++) {
|
||||
LOG_DBG_("%c%c", HEX[(p[i] >> 4) & 0x0f], HEX[p[i] & 0x0f]);
|
||||
}
|
||||
LOG_DBG("\n");
|
||||
#endif
|
||||
|
||||
if(!aead(hdr_len, 1)) {
|
||||
LOG_ERR("failed to encrypt packet to ");
|
||||
LOG_ERR_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
LOG_ERR_("\n");
|
||||
return FRAMER_FAILED;
|
||||
}
|
||||
LOG_INFO("LLSEC-OUT:");
|
||||
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
LOG_INFO_(" ");
|
||||
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
LOG_INFO_(" %u (%u) LV:%d, KEY:0x%02x\n", packetbuf_datalen(), packetbuf_totlen(),
|
||||
packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL), LLSEC_KEY_INDEX);
|
||||
|
||||
#if LOG_LEVEL == LOG_LEVEL_DBG
|
||||
LOG_DBG(" Payload after: (%d)", packetbuf_totlen());
|
||||
p = packetbuf_hdrptr();
|
||||
for(i = 0; i < packetbuf_totlen(); i++) {
|
||||
LOG_DBG_("%c%c", HEX[(p[i] >> 4) & 0x0f], HEX[p[i] & 0x0f]);
|
||||
}
|
||||
LOG_DBG_("\n");
|
||||
#endif
|
||||
|
||||
}
|
||||
return hdr_len;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
csma_security_frame_len(void)
|
||||
{
|
||||
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) > 0 &&
|
||||
LLSEC_KEY_INDEX != 0xffff) {
|
||||
return NETSTACK_FRAMER.length() +
|
||||
MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07);
|
||||
}
|
||||
return NETSTACK_FRAMER.length();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
csma_security_parse_frame(void)
|
||||
{
|
||||
int hdr_len;
|
||||
|
||||
hdr_len = NETSTACK_FRAMER.parse();
|
||||
if(hdr_len < 0) {
|
||||
return hdr_len;
|
||||
}
|
||||
|
||||
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) == 0) {
|
||||
/* No security - no more processing required */
|
||||
return hdr_len;
|
||||
}
|
||||
|
||||
LOG_INFO("LLSEC-IN: ");
|
||||
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
LOG_INFO_(" ");
|
||||
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
LOG_INFO_(" %d %u (%u) LV:%d KM:%d KEY:0x%02x\n", hdr_len, packetbuf_datalen(),
|
||||
packetbuf_totlen(), packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL),
|
||||
LLSEC_KEY_MODE,
|
||||
LLSEC_KEY_INDEX);
|
||||
|
||||
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != CSMA_LLSEC_SECURITY_LEVEL) {
|
||||
LOG_INFO("received frame with wrong security level (%u) from ",
|
||||
packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
|
||||
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
LOG_INFO_("\n");
|
||||
return FRAMER_FAILED;
|
||||
}
|
||||
|
||||
if(LLSEC_KEY_MODE != CSMA_LLSEC_KEY_ID_MODE) {
|
||||
LOG_INFO("received frame with wrong key id mode (%u) from ", LLSEC_KEY_MODE);
|
||||
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
LOG_INFO("\n");
|
||||
return FRAMER_FAILED;
|
||||
}
|
||||
|
||||
if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_SENDER), &linkaddr_node_addr)) {
|
||||
LOG_INFO("frame from ourselves\n");
|
||||
return FRAMER_FAILED;
|
||||
}
|
||||
|
||||
if(packetbuf_datalen() <= MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07)) {
|
||||
LOG_ERR("MIC error - too little data in frame!\n");
|
||||
return FRAMER_FAILED;
|
||||
}
|
||||
|
||||
packetbuf_set_datalen(packetbuf_datalen() - MIC_LEN(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & 0x07));
|
||||
if(!aead(hdr_len, 0)) {
|
||||
LOG_INFO("received unauthentic frame %u from ",
|
||||
(unsigned int) anti_replay_get_counter());
|
||||
LOG_INFO_LLADDR(packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
LOG_INFO_("\n");
|
||||
return FRAMER_FAILED;
|
||||
}
|
||||
|
||||
/* TODO anti-reply protection */
|
||||
return hdr_len;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#else
|
||||
/* The "unsecure" version of the create frame / parse frame */
|
||||
int
|
||||
csma_security_create_frame(void)
|
||||
{
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
|
||||
return NETSTACK_FRAMER.create();
|
||||
}
|
||||
int
|
||||
csma_security_parse_frame(void)
|
||||
{
|
||||
return NETSTACK_FRAMER.parse();
|
||||
}
|
||||
|
||||
#endif /* LLSEC802154_USES_AUX_HEADER && LLSEC802154_USES_FRAME_COUNTER */
|
||||
|
||||
/** @} */
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Tiny Mesh AS
|
||||
* 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
|
||||
* LLSEC802154 Security related configuration
|
||||
* \author
|
||||
* Olav Frengstad <olav@tiny-mesh.com>
|
||||
*/
|
||||
|
||||
#ifndef CSMA_SECURITY_H_
|
||||
#define CSMA_SECURITY_H_
|
||||
|
||||
|
||||
#ifdef CSMA_CONF_LLSEC_DEFAULT_KEY0
|
||||
#define CSMA_LLSEC_DEFAULT_KEY0 CSMA_CONF_LLSEC_DEFAULT_KEY0
|
||||
#else
|
||||
#define CSMA_LLSEC_DEFAULT_KEY0 {0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f}
|
||||
#endif
|
||||
|
||||
#ifdef CSMA_CONF_LLSEC_SECURITY_LEVEL
|
||||
#define CSMA_LLSEC_SECURITY_LEVEL CSMA_CONF_LLSEC_SECURITY_LEVEL
|
||||
#else
|
||||
#define CSMA_LLSEC_SECURITY_LEVEL 5
|
||||
#endif /* CSMA_CONF_LLSEC_SECURITY_LEVEL */
|
||||
|
||||
#ifdef CSMA_CONF_LLSEC_KEY_ID_MODE
|
||||
#define CSMA_LLSEC_KEY_ID_MODE CSMA_CONF_LLSEC_KEY_ID_MODE
|
||||
#else
|
||||
#define CSMA_LLSEC_KEY_ID_MODE FRAME802154_IMPLICIT_KEY
|
||||
#endif /* CSMA_CONF_LLSEC_KEY_ID_MODE */
|
||||
|
||||
#ifdef CSMA_CONF_LLSEC_KEY_INDEX
|
||||
#define CSMA_LLSEC_KEY_INDEX CSMA_CONF_LLSEC_KEY_INDEX
|
||||
#else
|
||||
#define CSMA_LLSEC_KEY_INDEX 0
|
||||
#endif /* CSMA_CONF_LLSEC_KEY_INDEX */
|
||||
|
||||
#ifdef CSMA_CONF_LLSEC_MAXKEYS
|
||||
#define CSMA_LLSEC_MAXKEYS CSMA_CONF_LLSEC_MAXKEYS
|
||||
#else
|
||||
#define CSMA_LLSEC_MAXKEYS 1
|
||||
#endif
|
||||
|
||||
#endif /* CSMA_SECURITY_H_ */
|
|
@ -49,10 +49,25 @@
|
|||
#define LOG_MODULE "CSMA"
|
||||
#define LOG_LEVEL LOG_LEVEL_MAC
|
||||
|
||||
|
||||
static void
|
||||
init_sec(void)
|
||||
{
|
||||
#if LLSEC802154_USES_AUX_HEADER
|
||||
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) ==
|
||||
PACKETBUF_ATTR_SECURITY_LEVEL_DEFAULT) {
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
|
||||
CSMA_LLSEC_SECURITY_LEVEL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
send_packet(mac_callback_t sent, void *ptr)
|
||||
{
|
||||
|
||||
init_sec();
|
||||
|
||||
csma_output_packet(sent, ptr);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -70,7 +85,7 @@ input_packet(void)
|
|||
if(packetbuf_datalen() == CSMA_ACK_LEN) {
|
||||
/* Ignore ack packets */
|
||||
LOG_DBG("ignored ack\n");
|
||||
} else if(NETSTACK_FRAMER.parse() < 0) {
|
||||
} else if(csma_security_parse_frame() < 0) {
|
||||
LOG_ERR("failed to parse %u\n", packetbuf_datalen());
|
||||
} else if(!linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_RECEIVER),
|
||||
&linkaddr_node_addr) &&
|
||||
|
@ -131,16 +146,41 @@ off(void)
|
|||
static void
|
||||
init(void)
|
||||
{
|
||||
|
||||
#if LLSEC802154_USES_AUX_HEADER
|
||||
#ifdef CSMA_LLSEC_DEFAULT_KEY0
|
||||
uint8_t key[16] = CSMA_LLSEC_DEFAULT_KEY0;
|
||||
csma_security_set_key(0, key);
|
||||
#endif
|
||||
#endif /* LLSEC802154_USES_AUX_HEADER */
|
||||
csma_output_init();
|
||||
on();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
max_payload(void)
|
||||
{
|
||||
int framer_hdrlen;
|
||||
|
||||
init_sec();
|
||||
|
||||
framer_hdrlen = NETSTACK_FRAMER.length();
|
||||
|
||||
if(framer_hdrlen < 0) {
|
||||
/* Framing failed, we assume the maximum header length */
|
||||
framer_hdrlen = CSMA_MAC_MAX_HEADER;
|
||||
}
|
||||
|
||||
return CSMA_MAC_LEN - framer_hdrlen;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct mac_driver csma_driver = {
|
||||
"CSMA",
|
||||
init,
|
||||
send_packet,
|
||||
input_packet,
|
||||
on,
|
||||
off
|
||||
off,
|
||||
max_payload,
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -65,6 +65,25 @@
|
|||
|
||||
#define CSMA_ACK_LEN 3
|
||||
|
||||
/* Default MAC len for 802.15.4 classic */
|
||||
#ifdef CSMA_MAC_CONF_LEN
|
||||
#define CSMA_MAC_LEN CSMA_MAC_CONF_LEN
|
||||
#else
|
||||
#define CSMA_MAC_LEN 127 - 2
|
||||
#endif
|
||||
|
||||
/* just a default - with LLSEC, etc */
|
||||
#define CSMA_MAC_MAX_HEADER 21
|
||||
|
||||
|
||||
extern const struct mac_driver csma_driver;
|
||||
|
||||
/* CSMA security framer functions */
|
||||
int csma_security_create_frame(void);
|
||||
int csma_security_parse_frame(void);
|
||||
|
||||
/* key management for CSMA */
|
||||
int csma_security_set_key(uint8_t index, const uint8_t *key);
|
||||
|
||||
|
||||
#endif /* CSMA_H_ */
|
||||
|
|
|
@ -74,6 +74,12 @@
|
|||
#define LLSEC802154_USES_AUX_HEADER LLSEC802154_ENABLED
|
||||
#endif /* LLSEC802154_CONF_USES_AUX_HEADER */
|
||||
|
||||
#ifdef LLSEC802154_CONF_USES_FRAME_COUNTER
|
||||
#define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_CONF_USES_FRAME_COUNTER
|
||||
#else
|
||||
#define LLSEC802154_USES_FRAME_COUNTER LLSEC802154_ENABLED
|
||||
#endif /* LLSEC802154_CONF_USES_FRAME_COUNTER */
|
||||
|
||||
#if UIP_BYTE_ORDER == UIP_LITTLE_ENDIAN
|
||||
#define LLSEC802154_HTONS(n) (n)
|
||||
#define LLSEC802154_HTONL(n) (n)
|
||||
|
|
|
@ -76,6 +76,9 @@ struct mac_driver {
|
|||
|
||||
/** Turn the MAC layer off. */
|
||||
int (* off)(void);
|
||||
|
||||
/** Read out estimated max payload size based on payload in packetbuf */
|
||||
int (* max_payload)(void);
|
||||
};
|
||||
|
||||
/* Generic MAC return values. */
|
||||
|
|
|
@ -67,6 +67,12 @@ off(void)
|
|||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
max_payload(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
init(void)
|
||||
{
|
||||
|
@ -78,6 +84,7 @@ const struct mac_driver nullmac_driver = {
|
|||
send_packet,
|
||||
packet_input,
|
||||
on,
|
||||
off
|
||||
off,
|
||||
max_payload,
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -66,8 +66,8 @@
|
|||
/* 1 channel, sequence length 1 */
|
||||
#define TSCH_HOPPING_SEQUENCE_1_1 (uint8_t[]){ 20 }
|
||||
|
||||
/* Max TSCH packet lenght */
|
||||
#define TSCH_PACKET_MAX_LEN MIN(127, PACKETBUF_SIZE)
|
||||
/* Max TSCH packet lenght - last bytes are CRC in default 802.15.4 packets */
|
||||
#define TSCH_PACKET_MAX_LEN MIN(127 - 2, PACKETBUF_SIZE)
|
||||
|
||||
/* The jitter to remove in ticks.
|
||||
* This should be the sum of measurement errors on Tx and Rx nodes.
|
||||
|
|
|
@ -972,8 +972,7 @@ tsch_init(void)
|
|||
return;
|
||||
}
|
||||
|
||||
/* Init the queuebuf and TSCH sub-modules */
|
||||
queuebuf_init();
|
||||
/* Init TSCH sub-modules */
|
||||
tsch_reset();
|
||||
tsch_queue_init();
|
||||
tsch_schedule_init();
|
||||
|
@ -1152,13 +1151,21 @@ turn_off(void)
|
|||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
max_payload(void)
|
||||
{
|
||||
/* Setup security... before. */
|
||||
return TSCH_PACKET_MAX_LEN - NETSTACK_FRAMER.length();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct mac_driver tschmac_driver = {
|
||||
"TSCH",
|
||||
tsch_init,
|
||||
send_packet,
|
||||
packet_input,
|
||||
turn_on,
|
||||
turn_off
|
||||
turn_off,
|
||||
max_payload,
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/** @} */
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "contiki.h"
|
||||
#include "net/linkaddr.h"
|
||||
#include "net/mac/llsec802154.h"
|
||||
#include "net/mac/csma/csma-security.h"
|
||||
#include "net/mac/tsch/tsch-conf.h"
|
||||
|
||||
/**
|
||||
|
@ -238,6 +239,11 @@ enum {
|
|||
PACKETBUF_ATTR_KEY_INDEX,
|
||||
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
|
||||
|
||||
#if LLSEC802154_USES_FRAME_COUNTER
|
||||
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1,
|
||||
PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3,
|
||||
#endif /* LLSEC802154_USES_FRAME_COUNTER */
|
||||
|
||||
/* Scope 2 attributes: used between end-to-end nodes. */
|
||||
/* These must be last */
|
||||
PACKETBUF_ADDR_SENDER,
|
||||
|
@ -277,6 +283,8 @@ void packetbuf_attr_copyfrom(struct packetbuf_attr *attrs,
|
|||
#define PACKETBUF_ATTR_BYTE 8
|
||||
#define PACKETBUF_ADDRSIZE (LINKADDR_SIZE * PACKETBUF_ATTR_BYTE)
|
||||
|
||||
#define PACKETBUF_ATTR_SECURITY_LEVEL_DEFAULT 0xffff
|
||||
|
||||
struct packetbuf_attrlist {
|
||||
uint8_t type;
|
||||
uint8_t len;
|
||||
|
|
|
@ -55,6 +55,12 @@
|
|||
|
||||
#include "net/packetbuf.h"
|
||||
|
||||
#ifdef QUEUEBUF_CONF_ENABLED
|
||||
#define QUEUEBUF_ENABLED QUEUEBUF_CONF_ENABLED
|
||||
#else /* QUEUEBUF_CONF_ENABLED */
|
||||
#define QUEUEBUF_ENABLED 1
|
||||
#endif /* QUEUEBUF_CONF_ENABLED */
|
||||
|
||||
/* QUEUEBUF_NUM is the total number of queuebuf */
|
||||
#ifdef QUEUEBUF_CONF_NUM
|
||||
#define QUEUEBUF_NUM QUEUEBUF_CONF_NUM
|
||||
|
|
|
@ -107,7 +107,7 @@ static void
|
|||
ext_header_remove(void)
|
||||
{
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
uip_ext_len = 0;
|
||||
uip_remove_ext_hdr();
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -118,7 +118,7 @@ ext_header_update(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
ext_header_hbh_update(int uip_ext_opt_offset)
|
||||
ext_header_hbh_update(uint8_t *ext_buf, int opt_offset)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -131,12 +131,13 @@ struct routing_driver {
|
|||
* Process and update the routing protocol hob-by-hop
|
||||
* extention headers of the current uIP packet.
|
||||
*
|
||||
* \param uip_ext_opt_offset The offset within the uIP packet where
|
||||
* extension headers start
|
||||
* \param ext_buf A pointer to the ext header buffer
|
||||
* \param opt_offset The offset within the extension header where
|
||||
* the option starts
|
||||
* \return 1 in case the packet is valid and to be processed further,
|
||||
* 0 in case the packet must be dropped.
|
||||
*/
|
||||
int (* ext_header_hbh_update)(int uip_ext_opt_offset);
|
||||
int (* ext_header_hbh_update)(uint8_t *ext_buf, int opt_offset);
|
||||
/**
|
||||
* Process and update SRH in-place,
|
||||
* i.e. internal address swapping as per RFC6554
|
||||
|
|
|
@ -126,7 +126,7 @@ rpl_get_nbr(rpl_parent_t *parent)
|
|||
{
|
||||
const linkaddr_t *lladdr = rpl_get_parent_lladdr(parent);
|
||||
if(lladdr != NULL) {
|
||||
return nbr_table_get_from_lladdr(ds6_neighbors, lladdr);
|
||||
return uip_ds6_nbr_ll_lookup((const uip_lladdr_t *)lladdr);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -145,9 +145,9 @@ rpl_dag_init(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rpl_parent_t *
|
||||
rpl_get_parent(uip_lladdr_t *addr)
|
||||
rpl_get_parent(const uip_lladdr_t *addr)
|
||||
{
|
||||
rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (linkaddr_t *)addr);
|
||||
rpl_parent_t *p = nbr_table_get_from_lladdr(rpl_parents, (const linkaddr_t *)addr);
|
||||
return p;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -60,46 +60,35 @@
|
|||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_NEXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_HOP_BY_HOP_LEN])
|
||||
#define UIP_RH_BUF ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_RPL_SRH_BUF ((struct uip_rpl_srh_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_RH_LEN])
|
||||
#define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
||||
rpl_ext_header_hbh_update(uint8_t *ext_buf, int opt_offset)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
int down;
|
||||
uint16_t sender_rank;
|
||||
uint8_t sender_closer;
|
||||
uip_ds6_route_t *route;
|
||||
rpl_parent_t *sender = NULL;
|
||||
rpl_parent_t *sender;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)ext_buf;
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(ext_buf + opt_offset);
|
||||
|
||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL
|
||||
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||
if(hbh_hdr->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| rpl_opt->opt_type != UIP_EXT_HDR_OPT_RPL
|
||||
|| rpl_opt->opt_len != RPL_HDR_OPT_LEN) {
|
||||
|
||||
LOG_ERR("Hop-by-hop extension header has wrong size or type (%u %u %u)\n",
|
||||
UIP_HBHO_BUF->len,
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_type,
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len);
|
||||
hbh_hdr->len, rpl_opt->opt_type, rpl_opt->opt_len);
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||
instance = rpl_get_instance(rpl_opt->instance);
|
||||
if(instance == NULL) {
|
||||
LOG_ERR("Unknown instance: %u\n",
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||
LOG_ERR("Unknown instance: %u\n", rpl_opt->instance);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||
if(rpl_opt->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||
LOG_ERR("Forward error!\n");
|
||||
/* We should try to repair it by removing the neighbor that caused
|
||||
the packet to be forwareded in the first place. We drop any
|
||||
|
@ -123,14 +112,14 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
return 0;
|
||||
}
|
||||
down = 0;
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN) {
|
||||
if(rpl_opt->flags & RPL_HDR_OPT_DOWN) {
|
||||
down = 1;
|
||||
}
|
||||
|
||||
sender_rank = UIP_HTONS(UIP_EXT_HDR_OPT_RPL_BUF->senderrank);
|
||||
sender_rank = UIP_HTONS(rpl_opt->senderrank);
|
||||
sender = nbr_table_get_from_lladdr(rpl_parents, packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
|
||||
if(sender != NULL && (UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR)) {
|
||||
if(sender != NULL && (rpl_opt->flags & RPL_HDR_OPT_RANK_ERR)) {
|
||||
/* A rank error was signalled, attempt to repair it by updating
|
||||
* the sender's rank from ext header */
|
||||
sender->rank = sender_rank;
|
||||
|
@ -160,7 +149,7 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
instance->unicast_dio_target = sender;
|
||||
rpl_schedule_unicast_dio_immediately(instance);
|
||||
}
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) {
|
||||
if(rpl_opt->flags & RPL_HDR_OPT_RANK_ERR) {
|
||||
RPL_STAT(rpl_stats.loop_errors++);
|
||||
LOG_ERR(" Rank error signalled in RPL option!\n");
|
||||
/* Packet must be dropped and dio trickle timer reset, see RFC6550 - 11.2.2.2 */
|
||||
|
@ -169,7 +158,7 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
}
|
||||
LOG_WARN("Single error tolerated\n");
|
||||
RPL_STAT(rpl_stats.loop_warnings++);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||
rpl_opt->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -181,41 +170,19 @@ int
|
|||
rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
#if RPL_WITH_NON_STORING
|
||||
uint8_t *uip_next_hdr;
|
||||
int last_uip_ext_len = uip_ext_len;
|
||||
struct uip_routing_hdr *rh_header;
|
||||
rpl_dag_t *dag;
|
||||
uip_sr_node_t *dest_node;
|
||||
uip_sr_node_t *root_node;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
|
||||
/* Look for routing header */
|
||||
while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, only the Hop-by-Hop Options header and
|
||||
* Destination Options header can appear before the Routing
|
||||
* header.
|
||||
*/
|
||||
/* Move to next header */
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
uip_next_hdr = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Look for routing ext header */
|
||||
rh_header = (struct uip_routing_hdr *)uipbuf_search_header(uip_buf, uip_len, UIP_PROTO_ROUTING);
|
||||
|
||||
dag = rpl_get_dag(&UIP_IP_BUF->destipaddr);
|
||||
root_node = uip_sr_get_node(dag, &dag->dag_id);
|
||||
dest_node = uip_sr_get_node(dag, &UIP_IP_BUF->destipaddr);
|
||||
|
||||
if((uip_next_hdr != NULL && *uip_next_hdr == UIP_PROTO_ROUTING
|
||||
&& UIP_RH_BUF->routing_type == RPL_RH_TYPE_SRH) ||
|
||||
if((rh_header != NULL && rh_header->routing_type == RPL_RH_TYPE_SRH) ||
|
||||
(dest_node != NULL && root_node != NULL &&
|
||||
dest_node->parent == root_node)) {
|
||||
/* Routing header found or the packet destined for a direct child of the root.
|
||||
|
@ -224,11 +191,9 @@ rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
|
|||
* forwarding to next hop */
|
||||
uip_ipaddr_copy(ipaddr, &UIP_IP_BUF->destipaddr);
|
||||
uip_create_linklocal_prefix(ipaddr);
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
#else /* RPL_WITH_NON_STORING */
|
||||
return 0; /* SRH not found */
|
||||
|
@ -239,34 +204,13 @@ int
|
|||
rpl_ext_header_srh_update(void)
|
||||
{
|
||||
#if RPL_WITH_NON_STORING
|
||||
uint8_t *uip_next_hdr;
|
||||
int last_uip_ext_len = uip_ext_len;
|
||||
struct uip_routing_hdr *rh_header;
|
||||
struct uip_rpl_srh_hdr *srh_header;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
/* Look for routing ext header */
|
||||
rh_header = (struct uip_routing_hdr *)uipbuf_search_header(uip_buf, uip_len, UIP_PROTO_ROUTING);
|
||||
|
||||
/* Look for routing header */
|
||||
while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, only the Hop-by-Hop Options header and
|
||||
* Destination Options header can appear before the Routing
|
||||
* header.
|
||||
*/
|
||||
/* Move to next header */
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
uip_next_hdr = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(uip_next_hdr != NULL && *uip_next_hdr == UIP_PROTO_ROUTING
|
||||
&& UIP_RH_BUF->routing_type == RPL_RH_TYPE_SRH) {
|
||||
if(rh_header != NULL && rh_header->routing_type == RPL_RH_TYPE_SRH) {
|
||||
/* SRH found, now look for next hop */
|
||||
uint8_t cmpri, cmpre;
|
||||
uint8_t ext_len;
|
||||
|
@ -275,11 +219,12 @@ rpl_ext_header_srh_update(void)
|
|||
uint8_t segments_left;
|
||||
uip_ipaddr_t current_dest_addr;
|
||||
|
||||
segments_left = UIP_RH_BUF->seg_left;
|
||||
ext_len = (UIP_RH_BUF->len * 8) + 8;
|
||||
cmpri = UIP_RPL_SRH_BUF->cmpr >> 4;
|
||||
cmpre = UIP_RPL_SRH_BUF->cmpr & 0x0f;
|
||||
padding = UIP_RPL_SRH_BUF->pad >> 4;
|
||||
srh_header = (struct uip_rpl_srh_hdr *)(((uint8_t *)rh_header) + RPL_RH_LEN);
|
||||
segments_left = rh_header->seg_left;
|
||||
ext_len = rh_header->len * 8 + 8;
|
||||
cmpri = srh_header->cmpr >> 4;
|
||||
cmpre = srh_header->cmpr & 0x0f;
|
||||
padding = srh_header->pad >> 4;
|
||||
path_len = ((ext_len - padding - RPL_RH_LEN - RPL_SRH_LEN - (16 - cmpre)) / (16 - cmpri)) + 1;
|
||||
(void)path_len;
|
||||
|
||||
|
@ -290,7 +235,7 @@ rpl_ext_header_srh_update(void)
|
|||
/* We are the final destination, do nothing */
|
||||
} else {
|
||||
uint8_t i = path_len - segments_left; /* The index of the next address to be visited */
|
||||
uint8_t *addr_ptr = ((uint8_t *)UIP_RH_BUF) + RPL_RH_LEN + RPL_SRH_LEN + (i * (16 - cmpri));
|
||||
uint8_t *addr_ptr = ((uint8_t *)rh_header) + RPL_RH_LEN + RPL_SRH_LEN + (i * (16 - cmpri));
|
||||
uint8_t cmpr = segments_left == 1 ? cmpre : cmpri;
|
||||
|
||||
/* As per RFC6554: swap the IPv6 destination address and address[i] */
|
||||
|
@ -303,17 +248,15 @@ rpl_ext_header_srh_update(void)
|
|||
memcpy(addr_ptr, ((uint8_t *)¤t_dest_addr) + cmpr, 16 - cmpr);
|
||||
|
||||
/* Update segments left field */
|
||||
UIP_RH_BUF->seg_left--;
|
||||
rh_header->seg_left--;
|
||||
|
||||
LOG_INFO("SRH next hop ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
}
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
#else /* RPL_WITH_NON_STORING */
|
||||
return 0; /* SRH not found */
|
||||
|
@ -336,7 +279,6 @@ static int
|
|||
insert_srh_header(void)
|
||||
{
|
||||
/* Implementation of RFC6554 */
|
||||
uint8_t temp_len;
|
||||
uint8_t path_len;
|
||||
uint8_t ext_len;
|
||||
uint8_t cmpri, cmpre; /* ComprI and ComprE fields of the RPL Source Routing Header */
|
||||
|
@ -348,6 +290,10 @@ insert_srh_header(void)
|
|||
rpl_dag_t *dag;
|
||||
uip_ipaddr_t node_addr;
|
||||
|
||||
/* Always insest SRH as first extension header */
|
||||
struct uip_routing_hdr *rh_hdr = (struct uip_routing_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_rpl_srh_hdr *srh_hdr = (struct uip_rpl_srh_hdr *)(UIP_IP_PAYLOAD(0) + RPL_RH_LEN);
|
||||
|
||||
LOG_INFO("SRH creating source routing header with destination ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
|
@ -418,33 +364,33 @@ insert_srh_header(void)
|
|||
path_len, cmpri, cmpre, ext_len, padding);
|
||||
|
||||
/* Check if there is enough space to store the extension header */
|
||||
if(uip_len + ext_len > UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
if(uip_len + ext_len > UIP_LINK_MTU) {
|
||||
LOG_ERR("Packet too long: impossible to add source routing header (%u bytes)\n", ext_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move existing ext headers and payload uip_ext_len further */
|
||||
memmove(uip_buf + uip_l2_l3_hdr_len + ext_len,
|
||||
uip_buf + uip_l2_l3_hdr_len, uip_len - UIP_IPH_LEN);
|
||||
memset(uip_buf + uip_l2_l3_hdr_len, 0, ext_len);
|
||||
/* Move existing ext headers and payload ext_len further */
|
||||
memmove(uip_buf + UIP_IPH_LEN + uip_ext_len + ext_len,
|
||||
uip_buf + UIP_IPH_LEN + uip_ext_len, uip_len - UIP_IPH_LEN);
|
||||
memset(uip_buf + UIP_IPH_LEN + uip_ext_len, 0, ext_len);
|
||||
|
||||
/* Insert source routing header */
|
||||
UIP_RH_BUF->next = UIP_IP_BUF->proto;
|
||||
/* Insert source routing header (as first ext header) */
|
||||
rh_hdr->next = UIP_IP_BUF->proto;
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ROUTING;
|
||||
|
||||
/* Initialize IPv6 Routing Header */
|
||||
UIP_RH_BUF->len = (ext_len - 8) / 8;
|
||||
UIP_RH_BUF->routing_type = RPL_RH_TYPE_SRH;
|
||||
UIP_RH_BUF->seg_left = path_len;
|
||||
rh_hdr->len = (ext_len - 8) / 8;
|
||||
rh_hdr->routing_type = RPL_RH_TYPE_SRH;
|
||||
rh_hdr->seg_left = path_len;
|
||||
|
||||
/* Initialize RPL Source Routing Header */
|
||||
UIP_RPL_SRH_BUF->cmpr = (cmpri << 4) + cmpre;
|
||||
UIP_RPL_SRH_BUF->pad = padding << 4;
|
||||
srh_hdr->cmpr = (cmpri << 4) + cmpre;
|
||||
srh_hdr->pad = padding << 4;
|
||||
|
||||
/* Initialize addresses field (the actual source route).
|
||||
* From last to first. */
|
||||
node = dest_node;
|
||||
hop_ptr = ((uint8_t *)UIP_RH_BUF) + ext_len - padding; /* Pointer where to write the next hop compressed address */
|
||||
hop_ptr = ((uint8_t *)rh_hdr) + ext_len - padding; /* Pointer where to write the next hop compressed address */
|
||||
|
||||
while(node != NULL && node->parent != root_node) {
|
||||
NETSTACK_ROUTING.get_sr_node_ipaddr(&node_addr, node);
|
||||
|
@ -459,15 +405,9 @@ insert_srh_header(void)
|
|||
NETSTACK_ROUTING.get_sr_node_ipaddr(&node_addr, node);
|
||||
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &node_addr);
|
||||
|
||||
/* In-place update of IPv6 length field */
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
UIP_IP_BUF->len[1] += ext_len;
|
||||
if(UIP_IP_BUF->len[1] < temp_len) {
|
||||
UIP_IP_BUF->len[0]++;
|
||||
}
|
||||
|
||||
uip_ext_len += ext_len;
|
||||
uip_len += ext_len;
|
||||
/* Update the IPv6 length field */
|
||||
uipbuf_add_ext_hdr(ext_len);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -476,44 +416,37 @@ static int
|
|||
update_hbh_header(void)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
int uip_ext_opt_offset;
|
||||
int last_uip_ext_len;
|
||||
rpl_parent_t *parent;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(UIP_IP_PAYLOAD(0) + 2);
|
||||
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO && rpl_opt->opt_type == UIP_EXT_HDR_OPT_RPL) {
|
||||
if(hbh_hdr->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| rpl_opt->opt_len != RPL_HDR_OPT_LEN) {
|
||||
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO && UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL) {
|
||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||
|
||||
LOG_ERR("Hop-by-hop extension header has wrong size (%u %u)\n",
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len,
|
||||
uip_ext_len);
|
||||
LOG_ERR("Hop-by-hop extension header has wrong size (%u)\n", rpl_opt->opt_len);
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||
instance = rpl_get_instance(rpl_opt->instance);
|
||||
if(instance == NULL || !instance->used || !instance->current_dag->joined) {
|
||||
LOG_ERR("Unable to add/update hop-by-hop extension header: incorrect instance\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
LOG_INFO("Updating RPL option\n");
|
||||
/* Update sender rank and instance, will update flags next */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = instance->instance_id;
|
||||
rpl_opt->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||
rpl_opt->instance = instance->instance_id;
|
||||
|
||||
if(RPL_IS_STORING(instance)) { /* In non-storing mode, downwards traffic does not have the HBH option */
|
||||
/* Check the direction of the down flag, as per Section 11.2.2.3,
|
||||
which states that if a packet is going down it should in
|
||||
general not go back up again. If this happens, a
|
||||
RPL_HDR_OPT_FWD_ERR should be flagged. */
|
||||
if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) {
|
||||
if((rpl_opt->flags & RPL_HDR_OPT_DOWN)) {
|
||||
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
|
||||
rpl_opt->flags |= RPL_HDR_OPT_FWD_ERR;
|
||||
LOG_WARN("RPL forwarding error\n");
|
||||
/* We should send back the packet to the originating parent,
|
||||
but it is not feasible yet, so we send a No-Path DAO instead */
|
||||
|
@ -532,63 +465,51 @@ update_hbh_header(void)
|
|||
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||
/* No route was found, so this packet will go towards the RPL
|
||||
root. If so, we should not set the down flag. */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN;
|
||||
rpl_opt->flags &= ~RPL_HDR_OPT_DOWN;
|
||||
LOG_DBG("RPL option going up\n");
|
||||
} else {
|
||||
/* A DAO route was found so we set the down flag. */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN;
|
||||
rpl_opt->flags |= RPL_HDR_OPT_DOWN;
|
||||
LOG_DBG("RPL option going down\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
insert_hbh_header(const rpl_instance_t *instance)
|
||||
{
|
||||
int uip_ext_opt_offset;
|
||||
int last_uip_ext_len;
|
||||
uint8_t temp_len;
|
||||
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(UIP_IP_PAYLOAD(2));
|
||||
|
||||
/* Insert hop-by-hop header */
|
||||
LOG_DBG("Creating hop-by-hop option\n");
|
||||
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_LINK_MTU) {
|
||||
LOG_ERR("Packet too long: impossible to add hop-by-hop option\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move existing ext headers and payload UIP_EXT_BUF further */
|
||||
memmove(UIP_HBHO_NEXT_BUF, UIP_EXT_BUF, uip_len - UIP_IPH_LEN);
|
||||
memset(UIP_HBHO_BUF, 0, RPL_HOP_BY_HOP_LEN);
|
||||
/* Move existing ext headers and payload RPL_HOP_BY_HOP_LEN further */
|
||||
memmove(UIP_IP_PAYLOAD(RPL_HOP_BY_HOP_LEN), UIP_IP_PAYLOAD(0), uip_len - UIP_IPH_LEN);
|
||||
memset(UIP_IP_PAYLOAD(0), 0, RPL_HOP_BY_HOP_LEN);
|
||||
|
||||
/* Update IP and HBH protocol and fields */
|
||||
UIP_HBHO_BUF->next = UIP_IP_BUF->proto;
|
||||
/* Insert HBH header (as first ext header) */
|
||||
hbh_hdr->next = UIP_IP_BUF->proto;
|
||||
UIP_IP_BUF->proto = UIP_PROTO_HBHO;
|
||||
|
||||
/* Initialize HBH option */
|
||||
UIP_HBHO_BUF->len = (RPL_HOP_BY_HOP_LEN - 8) / 8;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags = 0;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = instance->instance_id;
|
||||
uip_len += RPL_HOP_BY_HOP_LEN;
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
UIP_IP_BUF->len[1] += RPL_HOP_BY_HOP_LEN;
|
||||
if(UIP_IP_BUF->len[1] < temp_len) {
|
||||
UIP_IP_BUF->len[0]++;
|
||||
}
|
||||
hbh_hdr->len = (RPL_HOP_BY_HOP_LEN - 8) / 8;
|
||||
rpl_opt->opt_type = UIP_EXT_HDR_OPT_RPL;
|
||||
rpl_opt->opt_len = RPL_HDR_OPT_LEN;
|
||||
rpl_opt->flags = 0;
|
||||
rpl_opt->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||
rpl_opt->instance = instance->instance_id;
|
||||
|
||||
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
||||
uipbuf_add_ext_hdr(RPL_HOP_BY_HOP_LEN);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
/* Update header before returning */
|
||||
return update_hbh_header();
|
||||
|
@ -597,52 +518,33 @@ insert_hbh_header(const rpl_instance_t *instance)
|
|||
void
|
||||
rpl_ext_header_remove(void)
|
||||
{
|
||||
uint8_t temp_len;
|
||||
uint8_t rpl_ext_hdr_len;
|
||||
int uip_ext_opt_offset;
|
||||
uint8_t *uip_next_hdr;
|
||||
uint8_t *prev_proto_ptr;
|
||||
uint8_t protocol;
|
||||
uint8_t ext_len;
|
||||
uint8_t *next_header;
|
||||
struct uip_ext_hdr *ext_ptr;
|
||||
struct uip_ext_hdr_opt *opt_ptr;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
|
||||
/* Look for hop-by-hop and routing headers */
|
||||
while(uip_next_hdr != NULL) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_ROUTING:
|
||||
if((*uip_next_hdr != UIP_PROTO_HBHO || UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL)) {
|
||||
/* Remove hop-by-hop and routing headers */
|
||||
*uip_next_hdr = UIP_EXT_BUF->next;
|
||||
rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8;
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
uip_len -= rpl_ext_hdr_len;
|
||||
UIP_IP_BUF->len[1] -= rpl_ext_hdr_len;
|
||||
if(UIP_IP_BUF->len[1] > temp_len) {
|
||||
UIP_IP_BUF->len[0]--;
|
||||
}
|
||||
LOG_DBG("Removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len);
|
||||
memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN);
|
||||
} else {
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, any header other than the Destination
|
||||
* Options header does not appear between the Hop-by-Hop
|
||||
* Options header and the Routing header.
|
||||
*
|
||||
* We're moving to the next header only if uip_next_hdr has
|
||||
* UIP_PROTO_DESTO. Otherwise, we'll return.
|
||||
*/
|
||||
/* Move to next header */
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
|
||||
ext_ptr = (struct uip_ext_hdr *)next_header;
|
||||
prev_proto_ptr = &UIP_IP_BUF->proto;
|
||||
while(next_header != NULL && uip_is_proto_ext_hdr(protocol)) {
|
||||
opt_ptr = (struct uip_ext_hdr_opt *)(next_header + 2);
|
||||
if(protocol == UIP_PROTO_ROUTING || (protocol == UIP_PROTO_HBHO && opt_ptr->type == UIP_EXT_HDR_OPT_RPL)) {
|
||||
/* Remove ext header */
|
||||
*prev_proto_ptr = ext_ptr->next;
|
||||
ext_len = ext_ptr->len * 8 + 8;
|
||||
uipbuf_add_ext_hdr(-ext_len);
|
||||
/* Update length field and rest of packer to the "left" */
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
memmove(next_header, next_header + ext_len, uip_len - (next_header - uip_buf));
|
||||
/* Update loop variables */
|
||||
protocol = *prev_proto_ptr;
|
||||
} else {
|
||||
/* move to the ext hdr */
|
||||
next_header = uipbuf_get_next_header(next_header, uip_len - (next_header - uip_buf), &protocol, false);
|
||||
ext_ptr = (struct uip_ext_hdr *)next_header;
|
||||
prev_proto_ptr = &ext_ptr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,9 +70,6 @@
|
|||
#define RPL_DIO_MOP_MASK 0x38
|
||||
#define RPL_DIO_PREFERENCE_MASK 0x07
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void dis_input(void);
|
||||
static void dio_input(void);
|
||||
|
@ -251,7 +248,7 @@ dis_input(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -471,7 +468,7 @@ dio_input(void)
|
|||
rpl_process_dio(&from, &dio);
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -810,7 +807,7 @@ dao_input_storing(void)
|
|||
/* independent if we remove or not - ACK the request */
|
||||
if(flags & RPL_DAO_K_FLAG) {
|
||||
/* indicate that we accepted the no-path DAO */
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
dao_ack_output(instance, &dao_sender_addr, sequence,
|
||||
RPL_DAO_ACK_UNCONDITIONAL_ACCEPT);
|
||||
}
|
||||
|
@ -900,7 +897,7 @@ fwd_dao:
|
|||
}
|
||||
if(should_ack) {
|
||||
LOG_DBG("Sending DAO ACK\n");
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
dao_ack_output(instance, &dao_sender_addr, sequence,
|
||||
RPL_DAO_ACK_UNCONDITIONAL_ACCEPT);
|
||||
}
|
||||
|
@ -1014,7 +1011,7 @@ dao_input_nonstoring(void)
|
|||
|
||||
if(flags & RPL_DAO_K_FLAG) {
|
||||
LOG_DBG("Sending DAO ACK\n");
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
dao_ack_output(instance, &dao_sender_addr, sequence,
|
||||
RPL_DAO_ACK_UNCONDITIONAL_ACCEPT);
|
||||
}
|
||||
|
@ -1047,7 +1044,7 @@ dao_input(void)
|
|||
}
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if RPL_WITH_DAO_ACK
|
||||
|
@ -1286,7 +1283,7 @@ dao_ack_input(void)
|
|||
|
||||
instance = rpl_get_instance(instance_id);
|
||||
if(instance == NULL) {
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1294,7 +1291,7 @@ dao_ack_input(void)
|
|||
parent = rpl_find_parent(instance->current_dag, &UIP_IP_BUF->srcipaddr);
|
||||
if(parent == NULL) {
|
||||
/* not a known instance - drop the packet and ignore */
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -1303,7 +1300,7 @@ dao_ack_input(void)
|
|||
|
||||
if(instance->current_dag->rank == ROOT_RANK(instance)) {
|
||||
LOG_DBG("DODAG root received a DAO ACK, ignoring it\n");
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1363,7 +1360,7 @@ dao_ack_input(void)
|
|||
}
|
||||
}
|
||||
#endif /* RPL_WITH_DAO_ACK */
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
@ -65,12 +65,11 @@
|
|||
* neighbors and are not only MAC neighbors.
|
||||
*/
|
||||
#define MAX_CHILDREN (NBR_TABLE_MAX_NEIGHBORS - 2)
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
static int num_parents; /* any node that are possible parents */
|
||||
static int num_children; /* all children that we have as nexthop */
|
||||
static int num_free;
|
||||
static linkaddr_t *worst_rank_nbr; /* the parent that has the worst rank */
|
||||
static const linkaddr_t *worst_rank_nbr; /* the parent that has the worst rank */
|
||||
static rpl_rank_t worst_rank;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if LOG_DBG_ENABLED
|
||||
|
@ -112,9 +111,9 @@ update_nbr(void)
|
|||
num_parents = 0;
|
||||
num_children = 0;
|
||||
|
||||
nbr = nbr_table_head(ds6_neighbors);
|
||||
nbr = uip_ds6_nbr_head();
|
||||
while(nbr != NULL) {
|
||||
linkaddr_t *lladdr = nbr_table_get_lladdr(ds6_neighbors, nbr);
|
||||
const linkaddr_t *lladdr = (const linkaddr_t *)uip_ds6_nbr_get_ll(nbr);
|
||||
is_used = 0;
|
||||
|
||||
/*
|
||||
|
@ -127,7 +126,7 @@ update_nbr(void)
|
|||
num_children++;
|
||||
}
|
||||
|
||||
parent = rpl_get_parent((uip_lladdr_t *)lladdr);
|
||||
parent = rpl_get_parent((const uip_lladdr_t *)lladdr);
|
||||
if(parent != NULL) {
|
||||
num_parents++;
|
||||
|
||||
|
@ -159,7 +158,7 @@ update_nbr(void)
|
|||
LOG_DBG_("\n");
|
||||
}
|
||||
|
||||
nbr = nbr_table_next(ds6_neighbors, nbr);
|
||||
nbr = uip_ds6_nbr_next(nbr);
|
||||
num_used++;
|
||||
}
|
||||
/* how many more IP neighbors can be have? */
|
||||
|
|
|
@ -275,7 +275,7 @@ rpl_dag_t *rpl_get_dag(const uip_ipaddr_t *addr);
|
|||
rpl_dag_t *rpl_get_any_dag(void);
|
||||
rpl_instance_t *rpl_get_instance(uint8_t instance_id);
|
||||
int rpl_ext_header_update(void);
|
||||
int rpl_ext_header_hbh_update(int);
|
||||
int rpl_ext_header_hbh_update(uint8_t *, int);
|
||||
void rpl_insert_header(void);
|
||||
void rpl_ext_header_remove(void);
|
||||
const struct link_stats *rpl_get_parent_link_stats(rpl_parent_t *p);
|
||||
|
@ -285,7 +285,7 @@ uint16_t rpl_get_parent_link_metric(rpl_parent_t *p);
|
|||
rpl_rank_t rpl_rank_via_parent(rpl_parent_t *p);
|
||||
const linkaddr_t *rpl_get_parent_lladdr(rpl_parent_t *p);
|
||||
uip_ipaddr_t *rpl_parent_get_ipaddr(rpl_parent_t *nbr);
|
||||
rpl_parent_t *rpl_get_parent(uip_lladdr_t *addr);
|
||||
rpl_parent_t *rpl_get_parent(const uip_lladdr_t *addr);
|
||||
rpl_rank_t rpl_get_parent_rank(uip_lladdr_t *addr);
|
||||
void rpl_dag_init(void);
|
||||
uip_ds6_nbr_t *rpl_get_nbr(rpl_parent_t *parent);
|
||||
|
|
|
@ -53,46 +53,16 @@
|
|||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_NEXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_HOP_BY_HOP_LEN])
|
||||
#define UIP_RH_BUF ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_RPL_SRH_BUF ((struct uip_rpl_srh_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_RH_LEN])
|
||||
#define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
uint8_t *uip_next_hdr;
|
||||
int last_uip_ext_len = uip_ext_len;
|
||||
struct uip_routing_hdr *rh_header;
|
||||
uip_sr_node_t *dest_node;
|
||||
uip_sr_node_t *root_node;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
|
||||
/* Look for routing header */
|
||||
while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, only the Hop-by-Hop Options header and
|
||||
* Destination Options header can appear before the Routing header.
|
||||
*/
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
uip_next_hdr = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Look for routing ext header */
|
||||
rh_header = (struct uip_routing_hdr *)uipbuf_search_header(uip_buf, uip_len, UIP_PROTO_ROUTING);
|
||||
|
||||
if(!rpl_is_addr_in_our_dag(&UIP_IP_BUF->destipaddr)) {
|
||||
return 0;
|
||||
|
@ -101,8 +71,7 @@ rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
|
|||
root_node = uip_sr_get_node(NULL, &curr_instance.dag.dag_id);
|
||||
dest_node = uip_sr_get_node(NULL, &UIP_IP_BUF->destipaddr);
|
||||
|
||||
if((uip_next_hdr != NULL && *uip_next_hdr == UIP_PROTO_ROUTING
|
||||
&& UIP_RH_BUF->routing_type == RPL_RH_TYPE_SRH) ||
|
||||
if((rh_header != NULL && rh_header->routing_type == RPL_RH_TYPE_SRH) ||
|
||||
(dest_node != NULL && root_node != NULL &&
|
||||
dest_node->parent == root_node)) {
|
||||
/* Routing header found or the packet destined for a direct child of the root.
|
||||
|
@ -111,20 +80,18 @@ rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
|
|||
* forwarding to next hop */
|
||||
uip_ipaddr_copy(ipaddr, &UIP_IP_BUF->destipaddr);
|
||||
uip_create_linklocal_prefix(ipaddr);
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
LOG_DBG("no SRH found\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_ext_header_srh_update(void)
|
||||
{
|
||||
uint8_t *uip_next_hdr;
|
||||
int last_uip_ext_len = uip_ext_len;
|
||||
struct uip_routing_hdr *rh_header;
|
||||
struct uip_rpl_srh_hdr *srh_header;
|
||||
uint8_t cmpri, cmpre;
|
||||
uint8_t ext_len;
|
||||
uint8_t padding;
|
||||
|
@ -132,40 +99,21 @@ rpl_ext_header_srh_update(void)
|
|||
uint8_t segments_left;
|
||||
uip_ipaddr_t current_dest_addr;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
/* Look for routing ext header */
|
||||
rh_header = (struct uip_routing_hdr *)uipbuf_search_header(uip_buf, uip_len, UIP_PROTO_ROUTING);
|
||||
|
||||
/* Look for routing header */
|
||||
while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, only the Hop-by-Hop Options header and
|
||||
* Destination Options header can appear before the Routing header.
|
||||
*/
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
uip_next_hdr = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(uip_next_hdr == NULL || *uip_next_hdr != UIP_PROTO_ROUTING
|
||||
|| UIP_RH_BUF->routing_type != RPL_RH_TYPE_SRH) {
|
||||
if(rh_header == NULL || rh_header->routing_type != RPL_RH_TYPE_SRH) {
|
||||
LOG_INFO("SRH not found\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse SRH */
|
||||
segments_left = UIP_RH_BUF->seg_left;
|
||||
ext_len = (UIP_RH_BUF->len * 8) + 8;
|
||||
cmpri = UIP_RPL_SRH_BUF->cmpr >> 4;
|
||||
cmpre = UIP_RPL_SRH_BUF->cmpr & 0x0f;
|
||||
padding = UIP_RPL_SRH_BUF->pad >> 4;
|
||||
srh_header = (struct uip_rpl_srh_hdr *)(((uint8_t *)rh_header) + RPL_RH_LEN);
|
||||
segments_left = rh_header->seg_left;
|
||||
ext_len = rh_header->len * 8 + 8;
|
||||
cmpri = srh_header->cmpr >> 4;
|
||||
cmpre = srh_header->cmpr & 0x0f;
|
||||
padding = srh_header->pad >> 4;
|
||||
path_len = ((ext_len - padding - RPL_RH_LEN - RPL_SRH_LEN - (16 - cmpre)) / (16 - cmpri)) + 1;
|
||||
(void)path_len;
|
||||
|
||||
|
@ -177,7 +125,7 @@ rpl_ext_header_srh_update(void)
|
|||
/* We are the final destination, do nothing */
|
||||
} else {
|
||||
uint8_t i = path_len - segments_left; /* The index of the next address to be visited */
|
||||
uint8_t *addr_ptr = ((uint8_t *)UIP_RH_BUF) + RPL_RH_LEN + RPL_SRH_LEN + (i * (16 - cmpri));
|
||||
uint8_t *addr_ptr = ((uint8_t *)rh_header) + RPL_RH_LEN + RPL_SRH_LEN + (i * (16 - cmpri));
|
||||
uint8_t cmpr = segments_left == 1 ? cmpre : cmpri;
|
||||
|
||||
/* As per RFC6554: swap the IPv6 destination address with address[i] */
|
||||
|
@ -190,14 +138,13 @@ rpl_ext_header_srh_update(void)
|
|||
memcpy(addr_ptr, ((uint8_t *)¤t_dest_addr) + cmpr, 16 - cmpr);
|
||||
|
||||
/* Update segments left field */
|
||||
UIP_RH_BUF->seg_left--;
|
||||
rh_header->seg_left--;
|
||||
|
||||
LOG_INFO("SRH next hop ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
}
|
||||
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -223,7 +170,6 @@ static int
|
|||
insert_srh_header(void)
|
||||
{
|
||||
/* Implementation of RFC6554 */
|
||||
uint8_t temp_len;
|
||||
uint8_t path_len;
|
||||
uint8_t ext_len;
|
||||
uint8_t cmpri, cmpre; /* ComprI and ComprE fields of the RPL Source Routing Header */
|
||||
|
@ -234,6 +180,10 @@ insert_srh_header(void)
|
|||
uip_sr_node_t *node;
|
||||
uip_ipaddr_t node_addr;
|
||||
|
||||
/* Always insest SRH as first extension header */
|
||||
struct uip_routing_hdr *rh_hdr = (struct uip_routing_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_rpl_srh_hdr *srh_hdr = (struct uip_rpl_srh_hdr *)(UIP_IP_PAYLOAD(0) + RPL_RH_LEN);
|
||||
|
||||
LOG_INFO("SRH creating source routing header with destination ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_(" \n");
|
||||
|
@ -304,33 +254,33 @@ insert_srh_header(void)
|
|||
path_len, cmpri, cmpre, ext_len, padding);
|
||||
|
||||
/* Check if there is enough space to store the extension header */
|
||||
if(uip_len + ext_len > UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
if(uip_len + ext_len > UIP_LINK_MTU) {
|
||||
LOG_ERR("packet too long: impossible to add source routing header (%u bytes)\n", ext_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move existing ext headers and payload uip_ext_len further */
|
||||
memmove(uip_buf + uip_l2_l3_hdr_len + ext_len,
|
||||
uip_buf + uip_l2_l3_hdr_len, uip_len - UIP_IPH_LEN);
|
||||
memset(uip_buf + uip_l2_l3_hdr_len, 0, ext_len);
|
||||
/* Move existing ext headers and payload ext_len further */
|
||||
memmove(uip_buf + UIP_IPH_LEN + uip_ext_len + ext_len,
|
||||
uip_buf + UIP_IPH_LEN + uip_ext_len, uip_len - UIP_IPH_LEN);
|
||||
memset(uip_buf + UIP_IPH_LEN + uip_ext_len, 0, ext_len);
|
||||
|
||||
/* Insert source routing header */
|
||||
UIP_RH_BUF->next = UIP_IP_BUF->proto;
|
||||
/* Insert source routing header (as first ext header) */
|
||||
rh_hdr->next = UIP_IP_BUF->proto;
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ROUTING;
|
||||
|
||||
/* Initialize IPv6 Routing Header */
|
||||
UIP_RH_BUF->len = (ext_len - 8) / 8;
|
||||
UIP_RH_BUF->routing_type = RPL_RH_TYPE_SRH;
|
||||
UIP_RH_BUF->seg_left = path_len;
|
||||
rh_hdr->len = (ext_len - 8) / 8;
|
||||
rh_hdr->routing_type = RPL_RH_TYPE_SRH;
|
||||
rh_hdr->seg_left = path_len;
|
||||
|
||||
/* Initialize RPL Source Routing Header */
|
||||
UIP_RPL_SRH_BUF->cmpr = (cmpri << 4) + cmpre;
|
||||
UIP_RPL_SRH_BUF->pad = padding << 4;
|
||||
srh_hdr->cmpr = (cmpri << 4) + cmpre;
|
||||
srh_hdr->pad = padding << 4;
|
||||
|
||||
/* Initialize addresses field (the actual source route).
|
||||
* From last to first. */
|
||||
node = dest_node;
|
||||
hop_ptr = ((uint8_t *)UIP_RH_BUF) + ext_len - padding; /* Pointer where to write the next hop compressed address */
|
||||
hop_ptr = ((uint8_t *)rh_hdr) + ext_len - padding; /* Pointer where to write the next hop compressed address */
|
||||
|
||||
while(node != NULL && node->parent != root_node) {
|
||||
NETSTACK_ROUTING.get_sr_node_ipaddr(&node_addr, node);
|
||||
|
@ -345,21 +295,15 @@ insert_srh_header(void)
|
|||
NETSTACK_ROUTING.get_sr_node_ipaddr(&node_addr, node);
|
||||
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &node_addr);
|
||||
|
||||
/* In-place update of IPv6 length field */
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
UIP_IP_BUF->len[1] += ext_len;
|
||||
if(UIP_IP_BUF->len[1] < temp_len) {
|
||||
UIP_IP_BUF->len[0]++;
|
||||
}
|
||||
|
||||
uip_ext_len += ext_len;
|
||||
uip_len += ext_len;
|
||||
/* Update the IPv6 length field */
|
||||
uipbuf_add_ext_hdr(ext_len);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
||||
rpl_ext_header_hbh_update(uint8_t *ext_buf, int opt_offset)
|
||||
{
|
||||
int down;
|
||||
int rank_error_signaled;
|
||||
|
@ -367,32 +311,31 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
uint16_t sender_rank;
|
||||
uint8_t sender_closer;
|
||||
rpl_nbr_t *sender;
|
||||
uint8_t opt_type = UIP_EXT_HDR_OPT_RPL_BUF->opt_type;
|
||||
uint8_t opt_len = UIP_EXT_HDR_OPT_RPL_BUF->opt_len;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)ext_buf;
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(ext_buf + opt_offset);
|
||||
|
||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| opt_type != UIP_EXT_HDR_OPT_RPL
|
||||
|| opt_len != RPL_HDR_OPT_LEN) {
|
||||
if(hbh_hdr->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| rpl_opt->opt_type != UIP_EXT_HDR_OPT_RPL
|
||||
|| rpl_opt->opt_len != RPL_HDR_OPT_LEN) {
|
||||
LOG_ERR("hop-by-hop extension header has wrong size or type (%u %u %u)\n",
|
||||
UIP_HBHO_BUF->len, opt_type, opt_len);
|
||||
hbh_hdr->len, rpl_opt->opt_type, rpl_opt->opt_len);
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
if(!curr_instance.used || curr_instance.instance_id != UIP_EXT_HDR_OPT_RPL_BUF->instance) {
|
||||
LOG_ERR("unknown instance: %u\n",
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||
if(!curr_instance.used || curr_instance.instance_id != rpl_opt->instance) {
|
||||
LOG_ERR("unknown instance: %u\n", rpl_opt->instance);
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||
if(rpl_opt->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||
LOG_ERR("forward error!\n");
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
down = (UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN) ? 1 : 0;
|
||||
sender_rank = UIP_HTONS(UIP_EXT_HDR_OPT_RPL_BUF->senderrank);
|
||||
down = (rpl_opt->flags & RPL_HDR_OPT_DOWN) ? 1 : 0;
|
||||
sender_rank = UIP_HTONS(rpl_opt->senderrank);
|
||||
sender = nbr_table_get_from_lladdr(rpl_neighbors, packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
rank_error_signaled = (UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) ? 1 : 0;
|
||||
rank_error_signaled = (rpl_opt->flags & RPL_HDR_OPT_RANK_ERR) ? 1 : 0;
|
||||
sender_closer = sender_rank < curr_instance.dag.rank;
|
||||
loop_detected = (down && !sender_closer) || (!down && sender_closer);
|
||||
|
||||
|
@ -406,7 +349,7 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
|
||||
if(loop_detected) {
|
||||
/* Set forward error flag */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||
rpl_opt->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||
}
|
||||
|
||||
return rpl_process_hbh(sender, sender_rank, loop_detected, rank_error_signaled);
|
||||
|
@ -418,34 +361,27 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
static int
|
||||
update_hbh_header(void)
|
||||
{
|
||||
int uip_ext_opt_offset;
|
||||
int last_uip_ext_len;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(UIP_IP_PAYLOAD(2));
|
||||
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO && rpl_opt->opt_type == UIP_EXT_HDR_OPT_RPL) {
|
||||
if(hbh_hdr->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| rpl_opt->opt_len != RPL_HDR_OPT_LEN) {
|
||||
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO && UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL) {
|
||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||
|
||||
LOG_ERR("hop-by-hop extension header has wrong size (%u %u)\n",
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len, uip_ext_len);
|
||||
LOG_ERR("hop-by-hop extension header has wrong size (%u)\n", rpl_opt->opt_len);
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
if(!curr_instance.used || curr_instance.instance_id != UIP_EXT_HDR_OPT_RPL_BUF->instance) {
|
||||
if(!curr_instance.used || curr_instance.instance_id != rpl_opt->instance) {
|
||||
LOG_ERR("unable to add/update hop-by-hop extension header: incorrect instance\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
/* Update sender rank and instance, will update flags next */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(curr_instance.dag.rank);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = curr_instance.instance_id;
|
||||
rpl_opt->senderrank = UIP_HTONS(curr_instance.dag.rank);
|
||||
rpl_opt->instance = curr_instance.instance_id;
|
||||
}
|
||||
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -456,45 +392,34 @@ update_hbh_header(void)
|
|||
static int
|
||||
insert_hbh_header(void)
|
||||
{
|
||||
int uip_ext_opt_offset;
|
||||
int last_uip_ext_len;
|
||||
uint8_t temp_len;
|
||||
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(UIP_IP_PAYLOAD(2));
|
||||
|
||||
/* Insert hop-by-hop header */
|
||||
LOG_INFO("creating hop-by-hop option\n");
|
||||
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_LINK_MTU) {
|
||||
LOG_ERR("packet too long: impossible to add hop-by-hop option\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move existing ext headers and payload UIP_EXT_BUF further */
|
||||
memmove(UIP_HBHO_NEXT_BUF, UIP_EXT_BUF, uip_len - UIP_IPH_LEN);
|
||||
memset(UIP_HBHO_BUF, 0, RPL_HOP_BY_HOP_LEN);
|
||||
/* Move existing ext headers and payload RPL_HOP_BY_HOP_LEN further */
|
||||
memmove(UIP_IP_PAYLOAD(RPL_HOP_BY_HOP_LEN), UIP_IP_PAYLOAD(0), uip_len - UIP_IPH_LEN);
|
||||
memset(UIP_IP_PAYLOAD(0), 0, RPL_HOP_BY_HOP_LEN);
|
||||
|
||||
/* Update IP and HBH protocol and fields */
|
||||
UIP_HBHO_BUF->next = UIP_IP_BUF->proto;
|
||||
/* Insert HBH header (as first ext header) */
|
||||
hbh_hdr->next = UIP_IP_BUF->proto;
|
||||
UIP_IP_BUF->proto = UIP_PROTO_HBHO;
|
||||
|
||||
/* Initialize HBH option */
|
||||
UIP_HBHO_BUF->len = (RPL_HOP_BY_HOP_LEN - 8) / 8;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags = 0;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(curr_instance.dag.rank);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = curr_instance.instance_id;
|
||||
uip_len += RPL_HOP_BY_HOP_LEN;
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
UIP_IP_BUF->len[1] += RPL_HOP_BY_HOP_LEN;
|
||||
if(UIP_IP_BUF->len[1] < temp_len) {
|
||||
UIP_IP_BUF->len[0]++;
|
||||
}
|
||||
hbh_hdr->len = (RPL_HOP_BY_HOP_LEN - 8) / 8;
|
||||
rpl_opt->opt_type = UIP_EXT_HDR_OPT_RPL;
|
||||
rpl_opt->opt_len = RPL_HDR_OPT_LEN;
|
||||
rpl_opt->flags = 0;
|
||||
rpl_opt->senderrank = UIP_HTONS(curr_instance.dag.rank);
|
||||
rpl_opt->instance = curr_instance.instance_id;
|
||||
|
||||
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
||||
uipbuf_add_ext_hdr(RPL_HOP_BY_HOP_LEN);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
/* Update header before returning */
|
||||
return update_hbh_header();
|
||||
|
@ -531,54 +456,34 @@ rpl_ext_header_update(void)
|
|||
void
|
||||
rpl_ext_header_remove(void)
|
||||
{
|
||||
uint8_t temp_len;
|
||||
uint8_t rpl_ext_hdr_len;
|
||||
int uip_ext_opt_offset;
|
||||
uint8_t *uip_next_hdr;
|
||||
uint8_t *prev_proto_ptr;
|
||||
uint8_t protocol;
|
||||
uint8_t ext_len;
|
||||
uint8_t *next_header;
|
||||
struct uip_ext_hdr *ext_ptr;
|
||||
struct uip_ext_hdr_opt *opt_ptr;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
|
||||
/* Look for hop-by-hop and routing headers */
|
||||
while(uip_next_hdr != NULL) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_ROUTING:
|
||||
if((*uip_next_hdr != UIP_PROTO_HBHO || UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL)) {
|
||||
/* Remove hop-by-hop and routing headers */
|
||||
*uip_next_hdr = UIP_EXT_BUF->next;
|
||||
rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8;
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
uip_len -= rpl_ext_hdr_len;
|
||||
UIP_IP_BUF->len[1] -= rpl_ext_hdr_len;
|
||||
if(UIP_IP_BUF->len[1] > temp_len) {
|
||||
UIP_IP_BUF->len[0]--;
|
||||
}
|
||||
LOG_INFO("removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len);
|
||||
memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN);
|
||||
} else {
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, any header other than the Destination
|
||||
* Options header does not appear between the Hop-by-Hop
|
||||
* Options header and the Routing header.
|
||||
*
|
||||
* We're moving to the next header only if uip_next_hdr has
|
||||
* UIP_PROTO_DESTO. Otherwise, we'll return.
|
||||
*/
|
||||
/* Move to next header */
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
|
||||
ext_ptr = (struct uip_ext_hdr *)next_header;
|
||||
prev_proto_ptr = &UIP_IP_BUF->proto;
|
||||
while(next_header != NULL && uip_is_proto_ext_hdr(protocol)) {
|
||||
opt_ptr = (struct uip_ext_hdr_opt *)(next_header + 2);
|
||||
if(protocol == UIP_PROTO_ROUTING || (protocol == UIP_PROTO_HBHO && opt_ptr->type == UIP_EXT_HDR_OPT_RPL)) {
|
||||
/* Remove ext header */
|
||||
*prev_proto_ptr = ext_ptr->next;
|
||||
ext_len = ext_ptr->len * 8 + 8;
|
||||
uipbuf_add_ext_hdr(-ext_len);
|
||||
/* Update length field and move rest of packet to the "left" */
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
memmove(next_header, next_header + ext_len, uip_len - (next_header - uip_buf));
|
||||
/* Update loop variables */
|
||||
protocol = *prev_proto_ptr;
|
||||
} else {
|
||||
/* move to the ext hdr */
|
||||
next_header = uipbuf_get_next_header(next_header, uip_len - (next_header - uip_buf), &protocol, false);
|
||||
ext_ptr = (struct uip_ext_hdr *)next_header;
|
||||
prev_proto_ptr = &ext_ptr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
|
|
|
@ -63,12 +63,13 @@ int rpl_ext_header_srh_update(void);
|
|||
* Process and update the RPL hop-by-hop extension headers of
|
||||
* the current uIP packet.
|
||||
*
|
||||
* \param uip_ext_opt_offset The offset within the uIP packet where
|
||||
* extension headers start
|
||||
* \param ext_buf A pointer to the ext header buffer
|
||||
* \param opt_offset The offset within the extension header where
|
||||
* the option starts
|
||||
* \return 1 in case the packet is valid and to be processed further,
|
||||
* 0 in case the packet must be dropped.
|
||||
*/
|
||||
int rpl_ext_header_hbh_update(int uip_ext_opt_offset);
|
||||
int rpl_ext_header_hbh_update(uint8_t *ext_buf, int opt_offset);
|
||||
|
||||
/**
|
||||
* Adds/updates all RPL extension headers to current uIP packet.
|
||||
|
|
|
@ -62,10 +62,6 @@
|
|||
#define RPL_DIO_MOP_MASK 0x38
|
||||
#define RPL_DIO_PREFERENCE_MASK 0x07
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void dis_input(void);
|
||||
static void dio_input(void);
|
||||
|
@ -147,7 +143,7 @@ dis_input(void)
|
|||
rpl_process_dis(&UIP_IP_BUF->srcipaddr, uip_is_addr_mcast(&UIP_IP_BUF->destipaddr));
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -329,7 +325,7 @@ dio_input(void)
|
|||
rpl_process_dio(&from, &dio);
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -540,7 +536,7 @@ dao_input(void)
|
|||
rpl_process_dao(&from, &dao);
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -651,7 +647,7 @@ dao_ack_input(void)
|
|||
rpl_process_dao_ack(sequence, status);
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
@ -59,11 +59,10 @@
|
|||
* NOTE: this policy assumes that all neighbors end up being IPv6
|
||||
* neighbors and are not only MAC neighbors.
|
||||
*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
static int num_parents; /* all nodes that are possible parents */
|
||||
static int num_free;
|
||||
static linkaddr_t *worst_rank_nbr_lladdr; /* lladdr of the the neighbor with the worst rank */
|
||||
static const linkaddr_t *worst_rank_nbr_lladdr; /* lladdr of the the neighbor with the worst rank */
|
||||
static rpl_rank_t worst_rank;
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -79,10 +78,10 @@ update_state(void)
|
|||
worst_rank_nbr_lladdr = NULL;
|
||||
num_parents = 0;
|
||||
|
||||
ds6_nbr = nbr_table_head(ds6_neighbors);
|
||||
ds6_nbr = uip_ds6_nbr_head();
|
||||
while(ds6_nbr != NULL) {
|
||||
|
||||
linkaddr_t *nbr_lladdr = nbr_table_get_lladdr(ds6_neighbors, ds6_nbr);
|
||||
const linkaddr_t *nbr_lladdr = (const linkaddr_t *)uip_ds6_nbr_get_ll(ds6_nbr);
|
||||
rpl_nbr = rpl_neighbor_get_from_lladdr((uip_lladdr_t *)nbr_lladdr);
|
||||
|
||||
if(rpl_nbr != NULL && rpl_neighbor_is_parent(rpl_nbr)) {
|
||||
|
@ -98,7 +97,7 @@ update_state(void)
|
|||
worst_rank_nbr_lladdr = nbr_lladdr;
|
||||
}
|
||||
|
||||
ds6_nbr = nbr_table_next(ds6_neighbors, ds6_nbr);
|
||||
ds6_nbr = uip_ds6_nbr_next(ds6_nbr);
|
||||
num_used++;
|
||||
}
|
||||
/* how many more IP neighbors can be have? */
|
||||
|
|
|
@ -181,9 +181,9 @@ rpl_neighbor_count(void)
|
|||
static uip_ds6_nbr_t *
|
||||
rpl_get_ds6_nbr(rpl_nbr_t *nbr)
|
||||
{
|
||||
const linkaddr_t *lladdr = rpl_neighbor_get_lladdr(nbr);
|
||||
const uip_lladdr_t *lladdr = (const uip_lladdr_t *)rpl_neighbor_get_lladdr(nbr);
|
||||
if(lladdr != NULL) {
|
||||
return nbr_table_get_from_lladdr(ds6_neighbors, lladdr);
|
||||
return uip_ds6_nbr_ll_lookup(lladdr);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -139,7 +139,7 @@ ip64_arp_timer(void)
|
|||
{
|
||||
struct arp_entry *tabptr;
|
||||
int i;
|
||||
|
||||
|
||||
++arptime;
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
tabptr = &arp_table[i];
|
||||
|
@ -157,7 +157,7 @@ arp_update(uip_ip4addr_t *ipaddr, struct uip_eth_addr *ethaddr)
|
|||
{
|
||||
register struct arp_entry *tabptr = arp_table;
|
||||
int i, c;
|
||||
|
||||
|
||||
/* 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. */
|
||||
|
@ -170,7 +170,7 @@ arp_update(uip_ip4addr_t *ipaddr, struct uip_eth_addr *ethaddr)
|
|||
/* Check if the source IP address of the incoming packet matches
|
||||
the IP address in this ARP table entry. */
|
||||
if(uip_ip4addr_cmp(ipaddr, &tabptr->ipaddr)) {
|
||||
|
||||
|
||||
/* An old entry found, update this and return. */
|
||||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
||||
tabptr->time = arptime;
|
||||
|
@ -239,7 +239,7 @@ ip64_arp_arp_input(const uint8_t *packet, uint16_t packet_len)
|
|||
table, since it is likely that we will do more communication
|
||||
with this host in the future. */
|
||||
arp_update(&arphdr->sipaddr, &arphdr->shwaddr);
|
||||
|
||||
|
||||
arphdr->opcode = UIP_HTONS(ARP_REPLY);
|
||||
|
||||
memcpy(arphdr->dhwaddr.addr, arphdr->shwaddr.addr, 6);
|
||||
|
@ -275,7 +275,7 @@ ip64_arp_check_cache(const uint8_t *nlhdr)
|
|||
|
||||
printf("check cache %d.%d.%d.%d\n",
|
||||
uip_ipaddr_to_quad(&ipv4_hdr->destipaddr));
|
||||
|
||||
|
||||
/* First check if destination is a local broadcast. */
|
||||
uip_ipaddr(&broadcast_addr, 255,255,255,255);
|
||||
if(uip_ip4addr_cmp(&ipv4_hdr->destipaddr, &broadcast_addr)) {
|
||||
|
@ -321,7 +321,7 @@ ip64_arp_create_ethhdr(uint8_t *llhdr, const uint8_t *nlhdr)
|
|||
struct ipv4_hdr *ipv4_hdr = (struct ipv4_hdr *)nlhdr;
|
||||
struct ip64_eth_hdr *ethhdr = (struct ip64_eth_hdr *)llhdr;
|
||||
uip_ip4addr_t broadcast_addr;
|
||||
|
||||
|
||||
/* 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.
|
||||
|
@ -371,7 +371,7 @@ ip64_arp_create_ethhdr(uint8_t *llhdr, const uint8_t *nlhdr)
|
|||
|
||||
}
|
||||
memcpy(ethhdr->src.addr, ip64_eth_addr.addr, 6);
|
||||
|
||||
|
||||
ethhdr->type = UIP_HTONS(IP64_ETH_TYPE_IP);
|
||||
return sizeof(struct ip64_eth_hdr);
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ ip64_arp_create_arp_request(uint8_t *llhdr, const uint8_t *nlhdr)
|
|||
struct ipv4_hdr *ipv4_hdr = (struct ipv4_hdr *)nlhdr;
|
||||
struct arp_hdr *arp_hdr = (struct arp_hdr *)llhdr;
|
||||
uip_ip4addr_t ipaddr;
|
||||
|
||||
|
||||
if(!uip_ipaddr_maskcmp(&ipv4_hdr->destipaddr,
|
||||
ip64_get_hostaddr(),
|
||||
ip64_get_netmask())) {
|
||||
|
@ -394,7 +394,7 @@ ip64_arp_create_arp_request(uint8_t *llhdr, const uint8_t *nlhdr)
|
|||
/* Else, we use the destination IP address. */
|
||||
uip_ip4addr_copy(&ipaddr, &ipv4_hdr->destipaddr);
|
||||
}
|
||||
|
||||
|
||||
memset(arp_hdr->ethhdr.dest.addr, 0xff, 6);
|
||||
memset(arp_hdr->dhwaddr.addr, 0x00, 6);
|
||||
memcpy(arp_hdr->ethhdr.src.addr, ip64_eth_addr.addr, 6);
|
||||
|
@ -408,8 +408,8 @@ ip64_arp_create_arp_request(uint8_t *llhdr, const uint8_t *nlhdr)
|
|||
arp_hdr->hwlen = 6;
|
||||
arp_hdr->protolen = 4;
|
||||
arp_hdr->ethhdr.type = UIP_HTONS(IP64_ETH_TYPE_ARP);
|
||||
|
||||
uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
|
||||
|
||||
uip_appdata = &uip_buf[UIP_IPTCPH_LEN];
|
||||
|
||||
return sizeof(struct arp_hdr);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ struct dhcp_msg {
|
|||
uint8_t options[312];
|
||||
};
|
||||
|
||||
#if (UIP_BUFSIZE - UIP_LLH_LEN - UIP_UDPIP_HLEN) < 548
|
||||
#if (UIP_BUFSIZE - UIP_UDPIP_HLEN) < 548
|
||||
#error UIP_CONF_BUFFER_SIZE may be too small to accomodate DHCPv4 packets
|
||||
#error Increase UIP_CONF_BUFFER_SIZE in your project-conf.h, or contiki-conf.h
|
||||
#error A good size is 600 bytes
|
||||
|
@ -191,12 +191,12 @@ send_request(void)
|
|||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
|
||||
create_msg(m);
|
||||
|
||||
|
||||
end = add_msg_type(&m->options[4], DHCPREQUEST);
|
||||
end = add_server_id(end);
|
||||
end = add_req_ipaddr(end);
|
||||
end = add_end(end);
|
||||
|
||||
|
||||
uip_send(uip_appdata, (int)(end - (uint8_t *)uip_appdata));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -239,7 +239,7 @@ static uint8_t
|
|||
parse_msg(void)
|
||||
{
|
||||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
|
||||
|
||||
if(m->op == DHCP_REPLY &&
|
||||
memcmp(m->xid, &xid, sizeof(xid)) == 0 &&
|
||||
memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
|
||||
|
@ -258,7 +258,7 @@ msg_for_me(void)
|
|||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
uint8_t *optptr = &m->options[4];
|
||||
uint8_t *end = (uint8_t*)uip_appdata + uip_datalen();
|
||||
|
||||
|
||||
if(m->op == DHCP_REPLY &&
|
||||
memcmp(m->xid, &xid, sizeof(xid)) == 0 &&
|
||||
memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
|
||||
|
@ -280,7 +280,7 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
clock_time_t ticks;
|
||||
|
||||
PT_BEGIN(&s.pt);
|
||||
|
||||
|
||||
init:
|
||||
xid++;
|
||||
s.state = STATE_SENDING;
|
||||
|
@ -305,7 +305,7 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
s.ticks *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
selecting:
|
||||
s.ticks = CLOCK_SECOND;
|
||||
do {
|
||||
|
@ -330,7 +330,7 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
goto init;
|
||||
}
|
||||
} while(s.state != STATE_CONFIG_RECEIVED);
|
||||
|
||||
|
||||
bound:
|
||||
#if 0
|
||||
printf("Got IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.ipaddr));
|
||||
|
@ -343,7 +343,7 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
#endif
|
||||
|
||||
ip64_dhcpc_configured(&s);
|
||||
|
||||
|
||||
#define MAX_TICKS (~((clock_time_t)0) / 2)
|
||||
#define MAX_TICKS32 (~((uint32_t)0))
|
||||
#define IMIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
@ -407,12 +407,12 @@ ip64_dhcpc_init(const void *mac_addr, int mac_len)
|
|||
uip_ip6addr_t v6addr;
|
||||
uip_ip4addr_t v4addr;
|
||||
struct uip_udp_conn *conn2;
|
||||
|
||||
|
||||
s.mac_addr = mac_addr;
|
||||
s.mac_len = mac_len;
|
||||
|
||||
s.state = STATE_INITIAL;
|
||||
uip_ipaddr(&v4addr, 255,255,255,255);
|
||||
uip_ipaddr(&v4addr, 255,255,255,255);
|
||||
ip64_addr_4to6(&v4addr, &v6addr);
|
||||
s.conn = udp_new(&v6addr, UIP_HTONS(IP64_DHCPC_SERVER_PORT), NULL);
|
||||
conn2 = udp_new(NULL, UIP_HTONS(IP64_DHCPC_SERVER_PORT), NULL);
|
||||
|
@ -437,7 +437,7 @@ void
|
|||
ip64_dhcpc_request(void)
|
||||
{
|
||||
uip_ipaddr_t ipaddr;
|
||||
|
||||
|
||||
if(s.state == STATE_INITIAL) {
|
||||
uip_ipaddr(&ipaddr, 0,0,0,0);
|
||||
uip_sethostaddr(&ipaddr);
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/ipv6/uip-debug.h"
|
||||
#define printf(...)
|
||||
|
@ -62,7 +60,7 @@ ip64_eth_interface_input(uint8_t *packet, uint16_t len)
|
|||
printf("-------------->\n");
|
||||
uip_len = ip64_4to6(&packet[sizeof(struct ip64_eth_hdr)],
|
||||
len - sizeof(struct ip64_eth_hdr),
|
||||
&uip_buf[UIP_LLH_LEN]);
|
||||
uip_buf);
|
||||
if(uip_len > 0) {
|
||||
printf("ip64_interface_process: converted %d bytes\n", uip_len);
|
||||
|
||||
|
@ -96,7 +94,7 @@ output(void)
|
|||
PRINTF("\n");
|
||||
|
||||
printf("<--------------\n");
|
||||
len = ip64_6to4(&uip_buf[UIP_LLH_LEN], uip_len,
|
||||
len = ip64_6to4(uip_buf, uip_len,
|
||||
&ip64_packet_buffer[sizeof(struct ip64_eth_hdr)]);
|
||||
|
||||
printf("ip64-interface: output len %d\n", len);
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/ipv6/uip-debug.h"
|
||||
|
||||
|
@ -57,24 +55,24 @@ static void
|
|||
input_callback(void)
|
||||
{
|
||||
/*PRINTF("SIN: %u\n", uip_len);*/
|
||||
if(uip_buf[UIP_LLH_LEN] == '!') {
|
||||
PRINTF("Got configuration message of type %c\n", uip_buf[UIP_LLH_LEN + 1]);
|
||||
uip_clear_buf();
|
||||
if(uip_buf[0] == '!') {
|
||||
PRINTF("Got configuration message of type %c\n", uip_buf[1]);
|
||||
uipbuf_clear();
|
||||
#if 0
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'P') {
|
||||
if(uip_buf[1] == 'P') {
|
||||
uip_ipaddr_t prefix;
|
||||
/* Here we set a prefix !!! */
|
||||
memset(&prefix, 0, 16);
|
||||
memcpy(&prefix, &uip_buf[UIP_LLH_LEN + 2], 8);
|
||||
memcpy(&prefix, &uip_buf[2], 8);
|
||||
PRINTF("Setting prefix ");
|
||||
PRINT6ADDR(&prefix);
|
||||
PRINTF("\n");
|
||||
set_prefix_64(&prefix);
|
||||
}
|
||||
#endif
|
||||
} else if(uip_buf[UIP_LLH_LEN] == '?') {
|
||||
PRINTF("Got request message of type %c\n", uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'M') {
|
||||
} else if(uip_buf[0] == '?') {
|
||||
PRINTF("Got request message of type %c\n", uip_buf[1]);
|
||||
if(uip_buf[1] == 'M') {
|
||||
const char *hexchar = "0123456789abcdef";
|
||||
int j;
|
||||
/* this is just a test so far... just to see if it works */
|
||||
|
@ -86,21 +84,21 @@ input_callback(void)
|
|||
uip_len = 18;
|
||||
slip_write(uip_buf, uip_len);
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
} else {
|
||||
|
||||
|
||||
/* Save the last sender received over SLIP to avoid bouncing the
|
||||
packet back if no route is found */
|
||||
uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr);
|
||||
|
||||
uint16_t len = ip64_4to6(&uip_buf[UIP_LLH_LEN], uip_len,
|
||||
|
||||
uint16_t len = ip64_4to6(uip_buf, uip_len,
|
||||
ip64_packet_buffer);
|
||||
if(len > 0) {
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], ip64_packet_buffer, len);
|
||||
memcpy(uip_buf, ip64_packet_buffer, len);
|
||||
uip_len = len;
|
||||
/* PRINTF("send len %d\n", len); */
|
||||
} else {
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,11 +127,11 @@ output(void)
|
|||
if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) {
|
||||
PRINTF("ip64-interface: output, not sending bounced message\n");
|
||||
} else {
|
||||
len = ip64_6to4(&uip_buf[UIP_LLH_LEN], uip_len,
|
||||
len = ip64_6to4(uip_buf, uip_len,
|
||||
ip64_packet_buffer);
|
||||
PRINTF("ip64-interface: output len %d\n", len);
|
||||
if(len > 0) {
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], ip64_packet_buffer, len);
|
||||
memcpy(uip_buf, ip64_packet_buffer, len);
|
||||
uip_len = len;
|
||||
slip_send();
|
||||
return len;
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
#include "dev/slip.h"
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "SLIP"
|
||||
|
@ -63,34 +61,34 @@ request_prefix(void)
|
|||
uip_buf[1] = 'P';
|
||||
uip_len = 2;
|
||||
slip_write(uip_buf, uip_len);
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
slip_input_callback(void)
|
||||
{
|
||||
LOG_DBG("SIN: %u\n", uip_len);
|
||||
if(uip_buf[UIP_LLH_LEN] == '!') {
|
||||
if(uip_buf[0] == '!') {
|
||||
LOG_INFO("Got configuration message of type %c\n",
|
||||
uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'P') {
|
||||
uip_buf[1]);
|
||||
if(uip_buf[1] == 'P') {
|
||||
uip_ipaddr_t prefix;
|
||||
/* Here we set a prefix !!! */
|
||||
memset(&prefix, 0, 16);
|
||||
memcpy(&prefix, &uip_buf[UIP_LLH_LEN + 2], 8);
|
||||
memcpy(&prefix, &uip_buf[2], 8);
|
||||
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
|
||||
LOG_INFO("Setting prefix ");
|
||||
LOG_INFO_6ADDR(&prefix);
|
||||
LOG_INFO_("\n");
|
||||
set_prefix_64(&prefix);
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
|
||||
} else if(uip_buf[UIP_LLH_LEN] == '?') {
|
||||
LOG_INFO("Got request message of type %c\n", uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'M') {
|
||||
} else if(uip_buf[0] == '?') {
|
||||
LOG_INFO("Got request message of type %c\n", uip_buf[1]);
|
||||
if(uip_buf[1] == 'M') {
|
||||
char *hexchar = "0123456789abcdef";
|
||||
int j;
|
||||
/* this is just a test so far... just to see if it works */
|
||||
|
@ -102,7 +100,7 @@ slip_input_callback(void)
|
|||
uip_len = 18;
|
||||
slip_write(uip_buf, uip_len);
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
} else {
|
||||
/* Save the last sender received over SLIP to avoid bouncing the
|
||||
packet back if no route is found */
|
||||
|
|
|
@ -64,6 +64,20 @@ struct tx_callback {
|
|||
/*---------------------------------------------------------------------------*/
|
||||
static struct tx_callback callbacks[MAX_CALLBACKS];
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
init_sec(void)
|
||||
{
|
||||
/* use the CSMA LLSEC config parameter */
|
||||
#if LLSEC802154_USES_AUX_HEADER
|
||||
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) ==
|
||||
PACKETBUF_ATTR_SECURITY_LEVEL_DEFAULT) {
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
|
||||
CSMA_LLSEC_SECURITY_LEVEL);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
void
|
||||
packet_sent(uint8_t sessionid, uint8_t status, uint8_t tx)
|
||||
{
|
||||
|
@ -164,6 +178,13 @@ off()
|
|||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
max_payload()
|
||||
{
|
||||
init_sec();
|
||||
return 127 - NETSTACK_FRAMER.length();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
init(void)
|
||||
{
|
||||
|
@ -176,6 +197,7 @@ const struct mac_driver border_router_mac_driver = {
|
|||
send_packet,
|
||||
packet_input,
|
||||
on,
|
||||
off
|
||||
off,
|
||||
max_payload,
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -256,7 +256,7 @@ output(void)
|
|||
{
|
||||
LOG_DBG("SUT: %u\n", uip_len);
|
||||
if(uip_len > 0) {
|
||||
return tun_output(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
return tun_output(uip_buf, uip_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ handle_fd(fd_set *rset, fd_set *wset)
|
|||
int size;
|
||||
|
||||
if(FD_ISSET(tunfd, rset)) {
|
||||
size = tun_input(&uip_buf[UIP_LLH_LEN], sizeof(uip_buf));
|
||||
size = tun_input(uip_buf, sizeof(uip_buf));
|
||||
/* printf("TUN data incoming read:%d\n", size); */
|
||||
uip_len = size;
|
||||
tcpip_input();
|
||||
|
|
|
@ -55,6 +55,9 @@
|
|||
#if MAC_CONF_WITH_TSCH
|
||||
#include "net/mac/tsch/tsch.h"
|
||||
#endif /* MAC_CONF_WITH_TSCH */
|
||||
#if MAC_CONF_WITH_CSMA
|
||||
#include "net/mac/csma/csma.h"
|
||||
#endif
|
||||
#include "net/routing/routing.h"
|
||||
#include "net/mac/llsec802154.h"
|
||||
|
||||
|
@ -424,7 +427,7 @@ PT_THREAD(cmd_rpl_global_repair(struct pt *pt, shell_output_func output, char *a
|
|||
{
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_OUTPUT(output, "Triggering routing global repair\n")
|
||||
SHELL_OUTPUT(output, "Triggering routing global repair\n");
|
||||
NETSTACK_ROUTING.global_repair("Shell");
|
||||
|
||||
PT_END(pt);
|
||||
|
@ -447,7 +450,7 @@ PT_THREAD(cmd_rpl_refresh_routes(struct pt *pt, shell_output_func output, char *
|
|||
{
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_OUTPUT(output, "Triggering routes refresh\n")
|
||||
SHELL_OUTPUT(output, "Triggering routes refresh\n");
|
||||
rpl_refresh_routes("Shell");
|
||||
|
||||
PT_END(pt);
|
||||
|
@ -729,6 +732,73 @@ PT_THREAD(cmd_6top(struct pt *pt, shell_output_func output, char *args))
|
|||
}
|
||||
#endif /* TSCH_WITH_SIXTOP */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if LLSEC802154_ENABLED
|
||||
static
|
||||
PT_THREAD(cmd_llsec_setlv(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
|
||||
PT_BEGIN(pt);
|
||||
|
||||
if(args == NULL) {
|
||||
SHELL_OUTPUT(output, "Default LLSEC level is %d\n",
|
||||
uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
|
||||
PT_EXIT(pt);
|
||||
} else {
|
||||
int lv = atoi(args);
|
||||
if(lv < 0 || lv > 7) {
|
||||
SHELL_OUTPUT(output, "Illegal LLSEC Level %d\n", lv);
|
||||
PT_EXIT(pt);
|
||||
} else {
|
||||
uipbuf_set_default_attr(UIPBUF_ATTR_LLSEC_LEVEL, lv);
|
||||
uipbuf_clear_attr();
|
||||
SHELL_OUTPUT(output, "LLSEC default level set %d\n", lv);
|
||||
}
|
||||
}
|
||||
|
||||
PT_END(pt);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static
|
||||
PT_THREAD(cmd_llsec_setkey(struct pt *pt, shell_output_func output, char *args))
|
||||
{
|
||||
char *next_args;
|
||||
|
||||
PT_BEGIN(pt);
|
||||
|
||||
SHELL_ARGS_INIT(args, next_args);
|
||||
|
||||
if(args == NULL) {
|
||||
SHELL_OUTPUT(output, "Provide an index and a 16-char string for the key\n");
|
||||
PT_EXIT(pt);
|
||||
} else {
|
||||
int key;
|
||||
SHELL_ARGS_NEXT(args, next_args);
|
||||
key = atoi(args);
|
||||
if(key < 0) {
|
||||
SHELL_OUTPUT(output, "Illegal LLSEC Key index %d\n", key);
|
||||
PT_EXIT(pt);
|
||||
} else {
|
||||
#if MAC_CONF_WITH_CSMA
|
||||
/* Get next arg (key-string) */
|
||||
SHELL_ARGS_NEXT(args, next_args);
|
||||
if(args == NULL) {
|
||||
SHELL_OUTPUT(output, "Provide both an index and a key\n");
|
||||
} else if(strlen(args) == 16) {
|
||||
csma_security_set_key(key, (const uint8_t *) args);
|
||||
SHELL_OUTPUT(output, "Set key for index %d\n", key);
|
||||
} else {
|
||||
SHELL_OUTPUT(output, "Wrong length of key: '%s' (%d)\n", args, strlen(args));
|
||||
}
|
||||
#else
|
||||
SHELL_OUTPUT(output, "Set key not supported.\n");
|
||||
PT_EXIT(pt);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
PT_END(pt);
|
||||
}
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
shell_commands_init(void)
|
||||
{
|
||||
|
@ -801,6 +871,10 @@ const struct shell_command_t builtin_shell_commands[] = {
|
|||
#if TSCH_WITH_SIXTOP
|
||||
{ "6top", cmd_6top, "'> 6top help': Shows 6top command usage" },
|
||||
#endif /* TSCH_WITH_SIXTOP */
|
||||
#if LLSEC802154_ENABLED
|
||||
{ "llsec-set-level", cmd_llsec_setlv, "'> llsec-set-level <lv>': Set the level of link layer security (show if no lv argument)"},
|
||||
{ "llsec-set-key", cmd_llsec_setkey, "'> llsec-set-key <id> <key>': Set the key of link layer security"},
|
||||
#endif /* LLSEC802154_ENABLED */
|
||||
{ NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<speedlimit>1.0</speedlimit>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.contikimote.ContikiMoteType
|
||||
<identifier>mtype787</identifier>
|
||||
<description>Cooja Mote Type #1</description>
|
||||
<source>[CONTIKI_DIR]/tests/09-ipv6/code/node.c</source>
|
||||
<commands>make clean
|
||||
make WITH_ULA=1 WITH_CSMA=1 node.cooja</commands>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<symbols>false</symbols>
|
||||
</motetype>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>14.03051207883138</x>
|
||||
<y>82.02801380504546</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRS232
|
||||
<history>ip-nbr~;ping fe80::202:2:2:2~;ip-nbr~;help~;je;p~;ping da~;ping~;help~;</history>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype787</motetype_identifier>
|
||||
</mote>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>28.22612889898729</x>
|
||||
<y>43.60027658221718</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>2</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype787</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONTIKI_DIR]/tests/09-ipv6/js/ping-test-lla-ula.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>495</width>
|
||||
<z>0</z>
|
||||
<height>525</height>
|
||||
<location_x>190</location_x>
|
||||
<location_y>18</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
|
@ -0,0 +1,108 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<speedlimit>1.0</speedlimit>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.contikimote.ContikiMoteType
|
||||
<identifier>mtype787</identifier>
|
||||
<description>Cooja Mote Type #1</description>
|
||||
<source>[CONTIKI_DIR]/tests/09-ipv6/code/node.c</source>
|
||||
<commands>make clean
|
||||
make WITH_ULA=1 WITH_TSCH=1 node.cooja</commands>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<symbols>false</symbols>
|
||||
</motetype>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>14.03051207883138</x>
|
||||
<y>82.02801380504546</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRS232
|
||||
<history>ip-nbr~;ping fe80::202:2:2:2~;ip-nbr~;help~;je;p~;ping da~;ping~;help~;</history>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype787</motetype_identifier>
|
||||
</mote>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>28.22612889898729</x>
|
||||
<y>43.60027658221718</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>2</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype787</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONTIKI_DIR]/tests/09-ipv6/js/ping-test-lla-ula.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>495</width>
|
||||
<z>0</z>
|
||||
<height>525</height>
|
||||
<location_x>190</location_x>
|
||||
<location_y>18</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
|
@ -0,0 +1,108 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<speedlimit>1.0</speedlimit>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.contikimote.ContikiMoteType
|
||||
<identifier>mtype787</identifier>
|
||||
<description>Cooja Mote Type #1</description>
|
||||
<source>[CONTIKI_DIR]/tests/09-ipv6/code/node.c</source>
|
||||
<commands>make clean
|
||||
make WITH_NBR_MULTI_IPV6_ADDRS=1 WITH_ULA=1 WITH_CSMA=1 WITHOUT_RPL=1 node.cooja</commands>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<symbols>false</symbols>
|
||||
</motetype>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>14.03051207883138</x>
|
||||
<y>82.02801380504546</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRS232
|
||||
<history>ip-nbr~;ping fe80::202:2:2:2~;ip-nbr~;help~;je;p~;ping da~;ping~;help~;</history>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype787</motetype_identifier>
|
||||
</mote>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>28.22612889898729</x>
|
||||
<y>43.60027658221718</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>2</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype787</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONTIKI_DIR]/tests/09-ipv6/js/ping-test-lla-ula.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>495</width>
|
||||
<z>0</z>
|
||||
<height>525</height>
|
||||
<location_x>190</location_x>
|
||||
<location_y>18</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
|
@ -0,0 +1,108 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<simconf>
|
||||
<project EXPORT="discard">[APPS_DIR]/mrm</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/mspsim</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/avrora</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/serial_socket</project>
|
||||
<project EXPORT="discard">[APPS_DIR]/powertracker</project>
|
||||
<simulation>
|
||||
<title>My simulation</title>
|
||||
<speedlimit>1.0</speedlimit>
|
||||
<randomseed>123456</randomseed>
|
||||
<motedelay_us>1000000</motedelay_us>
|
||||
<radiomedium>
|
||||
org.contikios.cooja.radiomediums.UDGM
|
||||
<transmitting_range>50.0</transmitting_range>
|
||||
<interference_range>100.0</interference_range>
|
||||
<success_ratio_tx>1.0</success_ratio_tx>
|
||||
<success_ratio_rx>1.0</success_ratio_rx>
|
||||
</radiomedium>
|
||||
<events>
|
||||
<logoutput>40000</logoutput>
|
||||
</events>
|
||||
<motetype>
|
||||
org.contikios.cooja.contikimote.ContikiMoteType
|
||||
<identifier>mtype787</identifier>
|
||||
<description>Cooja Mote Type #1</description>
|
||||
<source>[CONTIKI_DIR]/tests/09-ipv6/code/node.c</source>
|
||||
<commands>make clean
|
||||
make WITH_NBR_MULTI_IPV6_ADDRS=1 WITH_ULA=1 WITH_TSCH=1 WITHOUT_RPL=1 node.cooja</commands>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Position</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Battery</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiVib</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiMoteID</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRS232</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiBeeper</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.RimeAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiIPAddress</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiRadio</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiButton</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiPIR</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiClock</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiLED</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiCFS</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.contikimote.interfaces.ContikiEEPROM</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.Mote2MoteRelations</moteinterface>
|
||||
<moteinterface>org.contikios.cooja.interfaces.MoteAttributes</moteinterface>
|
||||
<symbols>false</symbols>
|
||||
</motetype>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>14.03051207883138</x>
|
||||
<y>82.02801380504546</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>1</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRS232
|
||||
<history>ip-nbr~;ping fe80::202:2:2:2~;ip-nbr~;help~;je;p~;ping da~;ping~;help~;</history>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype787</motetype_identifier>
|
||||
</mote>
|
||||
<mote>
|
||||
<interface_config>
|
||||
org.contikios.cooja.interfaces.Position
|
||||
<x>28.22612889898729</x>
|
||||
<y>43.60027658221718</y>
|
||||
<z>0.0</z>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiMoteID
|
||||
<id>2</id>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiRadio
|
||||
<bitrate>250.0</bitrate>
|
||||
</interface_config>
|
||||
<interface_config>
|
||||
org.contikios.cooja.contikimote.interfaces.ContikiEEPROM
|
||||
<eeprom>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==</eeprom>
|
||||
</interface_config>
|
||||
<motetype_identifier>mtype787</motetype_identifier>
|
||||
</mote>
|
||||
</simulation>
|
||||
<plugin>
|
||||
org.contikios.cooja.plugins.ScriptRunner
|
||||
<plugin_config>
|
||||
<scriptfile>[CONTIKI_DIR]/tests/09-ipv6/js/ping-test-lla-ula.js</scriptfile>
|
||||
<active>true</active>
|
||||
</plugin_config>
|
||||
<width>495</width>
|
||||
<z>0</z>
|
||||
<height>525</height>
|
||||
<location_x>190</location_x>
|
||||
<location_y>18</location_y>
|
||||
</plugin>
|
||||
</simconf>
|
|
@ -28,6 +28,10 @@ ifeq ($(WITH_TSCH),1)
|
|||
CFLAGS += -DTSCH_CONF_DEFAULT_HOPPING_SEQUENCE=TSCH_HOPPING_SEQUENCE_1_1
|
||||
endif
|
||||
|
||||
ifeq ($(WITH_NBR_MULTI_IPV6_ADDRS),1)
|
||||
CFLAGS += -DUIP_DS6_NBR_CONF_MULTI_IPV6_ADDRS=1
|
||||
endif
|
||||
|
||||
PLATFORM_ONLY = cooja
|
||||
TARGET = cooja
|
||||
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
TIMEOUT(20000, log.testFailed());
|
||||
|
||||
dst_lla = "fe80::202:2:2:2";
|
||||
dst_ula = "fd00::202:2:2:2";
|
||||
dst_mac = "0002.0002.0002.0002";
|
||||
step = 0;
|
||||
rpl_is_enabled = false;
|
||||
|
||||
while(1) {
|
||||
YIELD();
|
||||
log.log(time + " " + id + " "+ msg + "\n");
|
||||
|
||||
if(msg.contains("Node ID: ")) {
|
||||
if(id == 1) {
|
||||
write(sim.getMoteWithID(1), "rpl-set-root 1");
|
||||
}
|
||||
step += 1;
|
||||
}
|
||||
|
||||
if(msg.contains("Setting as DAG root")) {
|
||||
rpl_is_enabled = true;
|
||||
}
|
||||
|
||||
if(step == 2 && time > 15000000) {
|
||||
write(sim.getMoteWithID(1), "ping " + dst_lla);
|
||||
step += 1;
|
||||
}
|
||||
|
||||
if(step == 4 && time > 15000000) {
|
||||
write(sim.getMoteWithID(1), "ping " + dst_ula);
|
||||
step += 1;
|
||||
}
|
||||
|
||||
if(msg.contains("Received ping reply")) {
|
||||
if(step == 3) {
|
||||
step += 1;
|
||||
} else {
|
||||
step += 1;
|
||||
write(sim.getMoteWithID(1), "ip-nbr");
|
||||
}
|
||||
}
|
||||
|
||||
if(step == 6 && rpl_is_enabled) {
|
||||
/* when RPL is enabled, we skip examining ip-nbr results */
|
||||
log.testOK();
|
||||
}
|
||||
|
||||
if(msg.contains("<->")) {
|
||||
re = /-- | <-> |, router|, state /;
|
||||
nc = msg.split(re);
|
||||
ip_addr = nc[1];
|
||||
ll_addr = nc[2];
|
||||
is_router = nc[3];
|
||||
state = nc[4].trim();
|
||||
if(ll_addr == dst_mac &&
|
||||
state == "Reachable") {
|
||||
if(step == 6 && ip_addr == dst_lla) {
|
||||
step += 1;
|
||||
} else if(step == 7 && ip_addr == dst_ula) {
|
||||
log.testOK();
|
||||
} else {
|
||||
/* unexpected case */
|
||||
log.testFailed();
|
||||
}
|
||||
} else {
|
||||
log.log(ip_addr + "\n");
|
||||
log.log(ll_addr + "\n");
|
||||
log.log(state + "\n");
|
||||
log.testFailed();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/sh
|
||||
|
||||
TEST_NAME=01-test-nbr-multi-addrs
|
||||
|
||||
if [ $# -eq 1 ]; then
|
||||
# a (relative) path to CONTIKI_DIR is supposed to be given as $1
|
||||
TEST_DIR=$1/tests/10-ipv6-nbr
|
||||
else
|
||||
TEST_DIR=.//tests/10-ipv6-nbr
|
||||
fi
|
||||
SRC_DIR=${TEST_DIR}/nbr-multi-addrs
|
||||
EXEC_FILE_NAME=test.native
|
||||
|
||||
make -C ${SRC_DIR} clean
|
||||
|
||||
echo "build the test program"...
|
||||
make -C ${SRC_DIR} > ${TEST_NAME}.log
|
||||
|
||||
echo "run the test..."
|
||||
${TEST_DIR}/${SRC_DIR}/${EXEC_FILE_NAME} | tee ${TEST_NAME}.log | \
|
||||
grep -vE '^\[' >> ${TEST_NAME}.testlog
|
|
@ -0,0 +1 @@
|
|||
include ../Makefile.script-test
|
|
@ -0,0 +1,14 @@
|
|||
CONTIKI_PROJECT = test
|
||||
all: $(CONTIKI_PROJECT)
|
||||
|
||||
CFLAGS += -DUNIT_TEST_PRINT_FUNCTION=my_test_print
|
||||
CFLAGS += -DLOG_CONF_LEVEL_IPV6=LOG_LEVEL_DBG
|
||||
CFLAGS += -DNBR_TABLE_FIND_REMOVABLE=my_always_return_null
|
||||
CFLAGS += -DUIP_DS6_NBR_CONF_MULTI_IPV6_ADDRS=1
|
||||
|
||||
PLATFORM_ONLY = native
|
||||
TARGET = native
|
||||
MODULES += os/sys/log os/services/unit-test
|
||||
|
||||
CONTIKI = ../../../
|
||||
include $(CONTIKI)/Makefile.include
|
|
@ -0,0 +1,260 @@
|
|||
/*
|
||||
* Copyright (c) 2018, Yasuyuki Tanaka
|
||||
* 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.h>
|
||||
#include <sys/log.h>
|
||||
#include <lib/random.h>
|
||||
#include <net/nbr-table.h>
|
||||
#include <net/ipv6/uip-ds6-nbr.h>
|
||||
#include <unit-test/unit-test.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LOG_MODULE "test"
|
||||
#define LOG_LEVEL LOG_LEVEL_DBG
|
||||
|
||||
/* report function defined in unit-test.c */
|
||||
void unit_test_print_report(const unit_test_t *utp);
|
||||
|
||||
static const uint8_t is_router = 1;
|
||||
static const uint8_t state = NBR_INCOMPLETE;
|
||||
static const nbr_table_reason_t reason = NBR_TABLE_REASON_UNDEFINED;
|
||||
|
||||
static void remove_all_entries_in_neighbor_cache(void);
|
||||
|
||||
PROCESS(node_process, "Node");
|
||||
AUTOSTART_PROCESSES(&node_process);
|
||||
|
||||
void
|
||||
my_test_print(const unit_test_t *utp)
|
||||
{
|
||||
unit_test_print_report(utp);
|
||||
if(utp->result == unit_test_failure) {
|
||||
printf("\nTEST FAILED\n");
|
||||
exit(1); /* exit by failure */
|
||||
}
|
||||
}
|
||||
|
||||
/* my_always_return_null() is set to NBR_TABLE_FIND_REMOVABLE */
|
||||
const linkaddr_t *
|
||||
my_always_return_null(nbr_table_reason_t reason, void *data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
remove_all_entries_in_neighbor_cache(void)
|
||||
{
|
||||
uip_ds6_nbr_t *nbr, *next_nbr;
|
||||
for(nbr = uip_ds6_nbr_head(); nbr != NULL; nbr = next_nbr) {
|
||||
next_nbr = uip_ds6_nbr_next(nbr);
|
||||
uip_ds6_nbr_rm(nbr);
|
||||
}
|
||||
/*
|
||||
* uip_ds6_nbr_rm() cannot free the memory for an entry in nbr-table. There is
|
||||
* no API to free or deallocate unused nbr-table entry. Because of that,
|
||||
* nbr-table has some link-layer addresses even though this function removes
|
||||
* all the neighbor cache entries.
|
||||
*/
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(add_v6addrs_to_neighbor,
|
||||
"add IPv6 addresses to a single neighbor");
|
||||
UNIT_TEST(add_v6addrs_to_neighbor)
|
||||
{
|
||||
uip_ipaddr_t ipaddr;
|
||||
uip_lladdr_t lladdr;
|
||||
uip_ds6_nbr_t *nbr;
|
||||
const uip_lladdr_t *ret_lladdr;
|
||||
|
||||
memset(&ipaddr, 0, sizeof(ipaddr));
|
||||
memset(&lladdr, 0, sizeof(lladdr));
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
|
||||
/* make sure the neighbor cache table is empty */
|
||||
remove_all_entries_in_neighbor_cache();
|
||||
UNIT_TEST_ASSERT(uip_ds6_nbr_head() == NULL);
|
||||
UNIT_TEST_ASSERT(uip_ds6_nbr_num() == 0);
|
||||
|
||||
/* prepare a link-layer address */
|
||||
LOG_DBG("link-layer addr: ");
|
||||
LOG_DBG_LLADDR((const linkaddr_t *)&lladdr);
|
||||
LOG_DBG_("\n");
|
||||
|
||||
for(int i = 0; i <= UIP_DS6_NBR_MAX_6ADDRS_PER_NBR; i++) {
|
||||
ipaddr.u8[0] = i;
|
||||
LOG_DBG("adding ipv6 addr (");
|
||||
LOG_DBG_6ADDR(&ipaddr);
|
||||
LOG_DBG_("[i=%u])\n", i);
|
||||
|
||||
/* add a binding of the IPv6 address and the MAC address */
|
||||
nbr = uip_ds6_nbr_add(&ipaddr, &lladdr, is_router, state, reason, NULL);
|
||||
if(i < UIP_DS6_NBR_MAX_6ADDRS_PER_NBR) {
|
||||
UNIT_TEST_ASSERT(nbr != NULL);
|
||||
UNIT_TEST_ASSERT(memcmp(&nbr->ipaddr, &ipaddr, sizeof(ipaddr)) == 0);
|
||||
UNIT_TEST_ASSERT(nbr->state == state);
|
||||
UNIT_TEST_ASSERT(uip_ds6_nbr_num() == (i + 1));
|
||||
/*
|
||||
* for some reason, nbr->isrouter is not set if both UIP_ND6_SEND_RA and
|
||||
* !UIP_CONF_ROUTER is 0 (see uip-ds6-nbr.c)
|
||||
*/
|
||||
// UNIT_TEST_ASSERT(nbr->isrouter == is_router);
|
||||
ret_lladdr = uip_ds6_nbr_lladdr_from_ipaddr((const uip_ipaddr_t *)&ipaddr);
|
||||
UNIT_TEST_ASSERT(ret_lladdr != NULL);
|
||||
UNIT_TEST_ASSERT(memcmp(ret_lladdr, &lladdr, sizeof(lladdr)) == 0);
|
||||
|
||||
} else {
|
||||
/* i == UIP_DS6_NBR_MAX_6ADDRS_PER_NBR; the address shouldn't be added */
|
||||
UNIT_TEST_ASSERT(nbr == NULL);
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(remove_v6addrs_of_neighbor,
|
||||
"remove IPv6 addresses associated with a single neighbor");
|
||||
UNIT_TEST(remove_v6addrs_of_neighbor)
|
||||
{
|
||||
uip_ipaddr_t ipaddr;
|
||||
uip_lladdr_t lladdr;
|
||||
uip_ds6_nbr_t *nbr, *next_nbr;
|
||||
|
||||
memset(&ipaddr, 0, sizeof(ipaddr));
|
||||
memset(&lladdr, 0, sizeof(lladdr));
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
|
||||
/* make sure the neighbor cache table is empty */
|
||||
remove_all_entries_in_neighbor_cache();
|
||||
UNIT_TEST_ASSERT(uip_ds6_nbr_head() == NULL);
|
||||
UNIT_TEST_ASSERT(uip_ds6_nbr_num() == 0);
|
||||
|
||||
/* prepare a link-layer address */
|
||||
LOG_DBG("link-layer addr: ");
|
||||
LOG_DBG_LLADDR((const linkaddr_t *)&lladdr);
|
||||
LOG_DBG_("\n");
|
||||
|
||||
/* fill the neighbor entry associated with the link-layer address */
|
||||
for(int i = 0; i < UIP_DS6_NBR_MAX_6ADDRS_PER_NBR; i++) {
|
||||
ipaddr.u8[0] = i;
|
||||
nbr = uip_ds6_nbr_add(&ipaddr, &lladdr, is_router, state, reason, NULL);
|
||||
UNIT_TEST_ASSERT(nbr != NULL);
|
||||
UNIT_TEST_ASSERT(uip_ds6_nbr_num() == (i + 1));
|
||||
}
|
||||
|
||||
/* remove IPv6 addresses for the link-layer address one by one */
|
||||
for(nbr = uip_ds6_nbr_head(); nbr != NULL; nbr = next_nbr) {
|
||||
LOG_DBG("removing nbr:%p\n", nbr);
|
||||
next_nbr = uip_ds6_nbr_next(nbr);
|
||||
UNIT_TEST_ASSERT(uip_ds6_nbr_rm(nbr) == 1);
|
||||
}
|
||||
UNIT_TEST_ASSERT(uip_ds6_nbr_num() == 0);
|
||||
UNIT_TEST_ASSERT(uip_ds6_nbr_head() == NULL);
|
||||
|
||||
UNIT_TEST_END();
|
||||
|
||||
}
|
||||
|
||||
UNIT_TEST_REGISTER(fill_neighbor_cache_table,
|
||||
"fill the neighbor cache table");
|
||||
UNIT_TEST(fill_neighbor_cache_table)
|
||||
{
|
||||
/*
|
||||
* We should be able to add the same number of link-layer addresses as
|
||||
* NBR_TABLE_MAX_NEIGHBORS. In addition, we should be add the same number of
|
||||
* IPv6 addresses per link-layer address as
|
||||
* UIP_DS6_NBR_CONF_MAX_6ADDRS_PER_NBR.
|
||||
*/
|
||||
uip_ipaddr_t ipaddr;
|
||||
uip_lladdr_t lladdr;
|
||||
uip_ds6_nbr_t *nbr;
|
||||
|
||||
memset(&ipaddr, 0, sizeof(ipaddr));
|
||||
memset(&lladdr, 0, sizeof(lladdr));
|
||||
|
||||
UNIT_TEST_BEGIN();
|
||||
|
||||
/* make sure the neighbor cache table is empty */
|
||||
remove_all_entries_in_neighbor_cache();
|
||||
UNIT_TEST_ASSERT(uip_ds6_nbr_head() == NULL);
|
||||
UNIT_TEST_ASSERT(uip_ds6_nbr_num() == 0);
|
||||
|
||||
for(int i = 0; i <= NBR_TABLE_MAX_NEIGHBORS; i++) {
|
||||
lladdr.addr[0] = i & 0xFF;
|
||||
lladdr.addr[1] = i >> 8;
|
||||
for(int j = 0; j <= UIP_DS6_NBR_MAX_6ADDRS_PER_NBR; j++) {
|
||||
ipaddr.u8[0] = i & 0xFF;
|
||||
ipaddr.u8[1] = i >> 8;
|
||||
ipaddr.u8[2] = j;
|
||||
LOG_DBG("adding ipv6 addr (");
|
||||
LOG_DBG_6ADDR(&ipaddr);
|
||||
LOG_DBG_(") to link-layer addr (");
|
||||
LOG_DBG_LLADDR((const linkaddr_t *)&lladdr);
|
||||
LOG_DBG_(") [i=%u,j=%u]\n", i, j);
|
||||
|
||||
nbr = uip_ds6_nbr_add(&ipaddr, &lladdr, is_router, state, reason, NULL);
|
||||
if((i < NBR_TABLE_MAX_NEIGHBORS) &&
|
||||
(j < UIP_DS6_NBR_MAX_6ADDRS_PER_NBR)) {
|
||||
UNIT_TEST_ASSERT(nbr != NULL);
|
||||
} else if(i == NBR_TABLE_MAX_NEIGHBORS) {
|
||||
/* we should not be able to add a link-layer address any more */
|
||||
UNIT_TEST_ASSERT(j == 0);
|
||||
UNIT_TEST_ASSERT(nbr == NULL);
|
||||
break;
|
||||
} else if(j == UIP_DS6_NBR_MAX_6ADDRS_PER_NBR) {
|
||||
/* we should not be able to add an IPv6 address any more */
|
||||
UNIT_TEST_ASSERT(i < NBR_TABLE_MAX_NEIGHBORS);
|
||||
UNIT_TEST_ASSERT(nbr == NULL);
|
||||
break;
|
||||
} else {
|
||||
/* shouldn't come here */
|
||||
UNIT_TEST_ASSERT(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UNIT_TEST_END();
|
||||
}
|
||||
|
||||
PROCESS_THREAD(node_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
UNIT_TEST_RUN(add_v6addrs_to_neighbor);
|
||||
UNIT_TEST_RUN(remove_v6addrs_of_neighbor);
|
||||
UNIT_TEST_RUN(fill_neighbor_cache_table);
|
||||
|
||||
printf("\nTEST SUCCEEDED\n");
|
||||
exit(0); /* success: all the test passed */
|
||||
|
||||
PROCESS_END();
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
ifdef CONTIKI_HOME
|
||||
CONTIKI = $(CONTIKI_HOME)
|
||||
else
|
||||
ifndef CONTIKI
|
||||
CONTIKI=../../..
|
||||
endif
|
||||
endif
|
||||
|
||||
DEFINES=WITH_SLIP=1
|
||||
|
||||
ifndef TARGET
|
||||
TARGET=sky
|
||||
endif
|
||||
|
||||
MODULES_REL += dev
|
||||
PROJECT_SOURCEFILES = fakeuip.c sicslow_ethernet.c
|
||||
|
||||
all: uip6-bridge-tap.sky
|
||||
|
||||
upload: uip6-bridge-tap.ihex
|
||||
cp $< $(IHEXFILE)
|
||||
$(MAKE) sky-u.$(subst /,-,$(word $(MOTE), $(MOTES)))
|
||||
|
||||
include $(CONTIKI)/Makefile.include
|
||||
|
||||
../../tapslip6: ../../tapslip6.c
|
||||
(cd ../../; $(MAKE) tapslip6)
|
||||
|
||||
ifndef MOTE
|
||||
MOTE=1
|
||||
endif
|
||||
|
||||
connect: ../../tapslip6
|
||||
sudo ../../tapslip6 -t tap0 -s $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES)) 127.0.0.1 255.0.0.0
|
||||
|
||||
bridge:
|
||||
@sudo service radvd restart || echo radvd could not be restarted
|
||||
sudo route add -6 fd00::/64 tap0
|
||||
sudo ip -6 address add fd00::1/64 dev tap0
|
|
@ -1,323 +0,0 @@
|
|||
/* -*- 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 "dev/ds2411/ds2411.h"
|
||||
#include "contiki.h"
|
||||
|
||||
#include "net/ipv6/uip.h"
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#include "dev/slip.h"
|
||||
|
||||
#define SLIP_END 0300
|
||||
#define SLIP_ESC 0333
|
||||
#define SLIP_ESC_END 0334
|
||||
#define SLIP_ESC_ESC 0335
|
||||
|
||||
PROCESS(slip_process, "SLIP driver");
|
||||
|
||||
uint8_t slip_active;
|
||||
|
||||
#if 1
|
||||
#define SLIP_STATISTICS(statement)
|
||||
#else
|
||||
uint16_t slip_rubbish, slip_twopackets, slip_overflow, slip_ip_drop;
|
||||
#define SLIP_STATISTICS(statement) statement
|
||||
#endif
|
||||
|
||||
/* Must be at least one byte larger than UIP_BUFSIZE! */
|
||||
#define RX_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN + 16)
|
||||
|
||||
enum {
|
||||
STATE_TWOPACKETS = 0, /* We have 2 packets and drop incoming data. */
|
||||
STATE_OK = 1,
|
||||
STATE_ESC = 2,
|
||||
STATE_RUBBISH = 3,
|
||||
};
|
||||
|
||||
/*
|
||||
* Variables begin and end manage the buffer space in a cyclic
|
||||
* fashion. The first used byte is at begin and end is one byte past
|
||||
* the last. I.e. [begin, end) is the actively used space.
|
||||
*
|
||||
* If begin != pkt_end we have a packet at [begin, pkt_end),
|
||||
* furthermore, if state == STATE_TWOPACKETS we have one more packet at
|
||||
* [pkt_end, end). If more bytes arrive in state STATE_TWOPACKETS
|
||||
* they are discarded.
|
||||
*/
|
||||
|
||||
static uint8_t state = STATE_TWOPACKETS;
|
||||
static uint16_t begin, end;
|
||||
static uint8_t rxbuf[RX_BUFSIZE];
|
||||
static uint16_t pkt_end; /* SLIP_END tracker. */
|
||||
|
||||
static void (* input_callback)(void) = NULL;
|
||||
static void (* tcpip_input_callback)(void) = NULL;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
slip_set_input_callback(void (*c)(void))
|
||||
{
|
||||
input_callback = c;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
slip_set_tcpip_input_callback(void (*c)(void))
|
||||
{
|
||||
tcpip_input_callback = c;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
slip_write(const void *_ptr, int len)
|
||||
{
|
||||
const uint8_t *ptr = _ptr;
|
||||
uint16_t i;
|
||||
uint8_t c;
|
||||
|
||||
slip_arch_writeb(SLIP_END);
|
||||
|
||||
for(i = 0; i < 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 len;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
rxbuf_init(void)
|
||||
{
|
||||
begin = end = pkt_end = 0;
|
||||
state = STATE_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Upper half does the polling. */
|
||||
static uint16_t
|
||||
slip_poll_handler(uint8_t *outbuf, uint16_t blen)
|
||||
{
|
||||
/* This is a hack and won't work across buffer edge! */
|
||||
if(rxbuf[begin] == 'C') {
|
||||
int i;
|
||||
if(begin < end && (end - begin) >= 6
|
||||
&& memcmp(&rxbuf[begin], "CLIENT", 6) == 0) {
|
||||
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
|
||||
memset(&rxbuf[begin], 0x0, 6);
|
||||
|
||||
rxbuf_init();
|
||||
|
||||
for(i = 0; i < 13; i++) {
|
||||
slip_arch_writeb("CLIENTSERVER\300"[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else if(rxbuf[begin] == '?') {
|
||||
int i, j;
|
||||
char* hexchar = "0123456789abcdef";
|
||||
if(begin < end && (end - begin) >= 2
|
||||
&& rxbuf[begin + 1] == 'M') {
|
||||
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
|
||||
rxbuf[begin] = 0;
|
||||
rxbuf[begin + 1] = 0;
|
||||
|
||||
rxbuf_init();
|
||||
|
||||
/* this is just a test so far... just to see if it works */
|
||||
slip_arch_writeb('!');
|
||||
slip_arch_writeb('M');
|
||||
for(j = 0; j < 8; j++) {
|
||||
slip_arch_writeb(hexchar[ds2411_id[j] >> 4]);
|
||||
slip_arch_writeb(hexchar[ds2411_id[j] & 15]);
|
||||
}
|
||||
slip_arch_writeb(SLIP_END);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt can not change begin but may change pkt_end.
|
||||
* If pkt_end != begin it will not change again.
|
||||
*/
|
||||
if(begin != pkt_end) {
|
||||
uint16_t len;
|
||||
|
||||
if(begin < pkt_end) {
|
||||
len = pkt_end - begin;
|
||||
if(len > blen) {
|
||||
len = 0;
|
||||
} else {
|
||||
memcpy(outbuf, &rxbuf[begin], len);
|
||||
}
|
||||
} else {
|
||||
len = (RX_BUFSIZE - begin) + (pkt_end - 0);
|
||||
if(len > blen) {
|
||||
len = 0;
|
||||
} else {
|
||||
unsigned i;
|
||||
for(i = begin; i < RX_BUFSIZE; i++) {
|
||||
*outbuf++ = rxbuf[i];
|
||||
}
|
||||
for(i = 0; i < pkt_end; i++) {
|
||||
*outbuf++ = rxbuf[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove data from buffer together with the copied packet. */
|
||||
begin = pkt_end;
|
||||
if(state == STATE_TWOPACKETS) {
|
||||
pkt_end = end;
|
||||
state = STATE_OK; /* Assume no bytes where lost! */
|
||||
|
||||
/* One more packet is buffered, need to be polled again! */
|
||||
process_poll(&slip_process);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(slip_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
rxbuf_init();
|
||||
|
||||
while(1) {
|
||||
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
|
||||
|
||||
slip_active = 1;
|
||||
|
||||
/* Move packet from rxbuf to buffer provided by uIP. */
|
||||
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
||||
UIP_BUFSIZE - UIP_LLH_LEN);
|
||||
if(uip_len > 0) {
|
||||
if(tcpip_input_callback) {
|
||||
tcpip_input_callback();
|
||||
} else {
|
||||
tcpip_input();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
slip_input_byte(unsigned char c)
|
||||
{
|
||||
switch(state) {
|
||||
case STATE_RUBBISH:
|
||||
if(c == SLIP_END) {
|
||||
state = STATE_OK;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case STATE_TWOPACKETS: /* Two packets are already buffered! */
|
||||
return 0;
|
||||
|
||||
case STATE_ESC:
|
||||
if(c == SLIP_ESC_END) {
|
||||
c = SLIP_END;
|
||||
} else if(c == SLIP_ESC_ESC) {
|
||||
c = SLIP_ESC;
|
||||
} else {
|
||||
state = STATE_RUBBISH;
|
||||
SLIP_STATISTICS(slip_rubbish++);
|
||||
end = pkt_end; /* remove rubbish */
|
||||
return 0;
|
||||
}
|
||||
state = STATE_OK;
|
||||
break;
|
||||
|
||||
case STATE_OK:
|
||||
if(c == SLIP_ESC) {
|
||||
state = STATE_ESC;
|
||||
return 0;
|
||||
} else if(c == SLIP_END) {
|
||||
/*
|
||||
* We have a new packet, possibly of zero length.
|
||||
*
|
||||
* There may already be one packet buffered.
|
||||
*/
|
||||
if(end != pkt_end) { /* Non zero length. */
|
||||
if(begin == pkt_end) { /* None buffered. */
|
||||
pkt_end = end;
|
||||
} else {
|
||||
state = STATE_TWOPACKETS;
|
||||
SLIP_STATISTICS(slip_twopackets++);
|
||||
}
|
||||
process_poll(&slip_process);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* add_char: */
|
||||
{
|
||||
unsigned next;
|
||||
next = end + 1;
|
||||
if(next == RX_BUFSIZE) {
|
||||
next = 0;
|
||||
}
|
||||
if(next == begin) { /* rxbuf is full */
|
||||
state = STATE_RUBBISH;
|
||||
SLIP_STATISTICS(slip_overflow++);
|
||||
end = pkt_end; /* remove rubbish */
|
||||
return 0;
|
||||
}
|
||||
rxbuf[end] = c;
|
||||
end = next;
|
||||
}
|
||||
|
||||
/* There could be a separate poll routine for this. */
|
||||
if(c == 'T' && rxbuf[begin] == 'C') {
|
||||
process_poll(&slip_process);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -1,136 +0,0 @@
|
|||
|
||||
/* Various stub functions and uIP variables other code might need to
|
||||
* compile. Allows you to save needing to compile all of uIP in just
|
||||
* to get a few things */
|
||||
|
||||
|
||||
#include "net/ipv6/uip.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include <string.h>
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
uip_buf_t uip_aligned_buf;
|
||||
|
||||
uint16_t uip_len;
|
||||
|
||||
struct uip_stats uip_stat;
|
||||
|
||||
uip_lladdr_t uip_lladdr;
|
||||
|
||||
uint16_t uip_htons(uint16_t val) { return UIP_HTONS(val);}
|
||||
|
||||
uip_ds6_netif_t uip_ds6_if;
|
||||
|
||||
/********** UIP_DS6.c **********/
|
||||
|
||||
void
|
||||
uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
|
||||
{
|
||||
/* We consider only links with IEEE EUI-64 identifier or
|
||||
IEEE 48-bit MAC addresses */
|
||||
#if (UIP_LLADDR_LEN == 8)
|
||||
memcpy(ipaddr->u8 + 8, lladdr, UIP_LLADDR_LEN);
|
||||
ipaddr->u8[8] ^= 0x02;
|
||||
#elif (UIP_LLADDR_LEN == 6)
|
||||
memcpy(ipaddr->u8 + 8, lladdr, 3);
|
||||
ipaddr->u8[11] = 0xff;
|
||||
ipaddr->u8[12] = 0xfe;
|
||||
memcpy(ipaddr->u8 + 13, lladdr + 3, 3);
|
||||
ipaddr->u8[8] ^= 0x02;
|
||||
#else
|
||||
#error fakeuip.c cannot build interface address when UIP_LLADDR_LEN is not 6 or 8
|
||||
#endif
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* get a link local address -
|
||||
* state = -1 => any address is ok. Otherwise state = desired state of addr.
|
||||
* (TENTATIVE, PREFERRED, DEPRECATED)
|
||||
*/
|
||||
uip_ds6_addr_t *
|
||||
uip_ds6_get_link_local(int8_t state) {
|
||||
uip_ds6_addr_t *locaddr;
|
||||
for(locaddr = uip_ds6_if.addr_list;
|
||||
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
|
||||
if((locaddr->isused) && (state == - 1 || locaddr->state == state)
|
||||
&& (uip_is_addr_linklocal(&locaddr->ipaddr))) {
|
||||
return locaddr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uip_ds6_addr_t *
|
||||
uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/********** UIP.c ****************/
|
||||
|
||||
static uint16_t
|
||||
chksum(uint16_t sum, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
uint16_t t;
|
||||
const uint8_t *dataptr;
|
||||
const uint8_t *last_byte;
|
||||
|
||||
dataptr = data;
|
||||
last_byte = data + len - 1;
|
||||
|
||||
while(dataptr < last_byte) { /* At least two more bytes */
|
||||
t = (dataptr[0] << 8) + dataptr[1];
|
||||
sum += t;
|
||||
if(sum < t) {
|
||||
sum++; /* carry */
|
||||
}
|
||||
dataptr += 2;
|
||||
}
|
||||
|
||||
if(dataptr == last_byte) {
|
||||
t = (dataptr[0] << 8) + 0;
|
||||
sum += t;
|
||||
if(sum < t) {
|
||||
sum++; /* carry */
|
||||
}
|
||||
}
|
||||
|
||||
/* Return sum in host byte order. */
|
||||
return sum;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
upper_layer_chksum(uint8_t proto)
|
||||
{
|
||||
uint16_t upper_layer_len;
|
||||
uint16_t sum;
|
||||
|
||||
upper_layer_len = (((uint16_t)(UIP_IP_BUF->len[0]) << 8) + UIP_IP_BUF->len[1]) ;
|
||||
|
||||
/* First sum pseudoheader. */
|
||||
/* IP protocol and length fields. This addition cannot carry. */
|
||||
sum = upper_layer_len + proto;
|
||||
/* Sum IP source and destination addresses. */
|
||||
sum = chksum(sum, (uint8_t *)&UIP_IP_BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
|
||||
|
||||
/* Sum TCP header and data. */
|
||||
sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
|
||||
upper_layer_len);
|
||||
|
||||
return (sum == 0) ? 0xffff : uip_htons(sum);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint16_t
|
||||
uip_icmp6chksum(void)
|
||||
{
|
||||
return upper_layer_chksum(UIP_PROTO_ICMP6);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_ds6_link_callback(int status, int numtx)
|
||||
{
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
interface tap0 {
|
||||
AdvSendAdvert on;
|
||||
AdvLinkMTU 1280;
|
||||
AdvCurHopLimit 128;
|
||||
AdvReachableTime 360000;
|
||||
MinRtrAdvInterval 100;
|
||||
MaxRtrAdvInterval 150;
|
||||
AdvDefaultLifetime 200;
|
||||
prefix AAAA::/64
|
||||
{
|
||||
AdvOnLink on;
|
||||
AdvAutonomous on;
|
||||
AdvPreferredLifetime 4294967295;
|
||||
AdvValidLifetime 4294967295;
|
||||
};
|
||||
};
|
|
@ -1,882 +0,0 @@
|
|||
/**
|
||||
* \file sicslow_ethernet.c
|
||||
* Routines to interface between Ethernet and 6LowPan
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2008 by:
|
||||
* Colin O'Flynn coflynn@newae.com
|
||||
* Eric Gnoske egnoske@gmail.com
|
||||
* Blake Leverett bleverett@gmail.com
|
||||
* Mike Vidales mavida404@gmail.com
|
||||
* Kevin Brown kbrown3@uccs.edu
|
||||
* Nate Bohlmann nate@elfwerks.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:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * 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.
|
||||
* * Neither the name of the copyright holders nor the names of
|
||||
* 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 OWNER 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
\ingroup usbstick
|
||||
\defgroup sicslowinterop 6LowPan Ethernet Interop
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
\par Ethernet to 6LowPan Address Translation
|
||||
|
||||
It should be obvious that since 802.15.4 addresses are 8
|
||||
bytes, and 802.3 addresses are 6 bytes, some form of
|
||||
address translation is needed. These routines provide this
|
||||
|
||||
\par 802.3 Address Formats
|
||||
|
||||
802.3 MAC addresses used here have this form:
|
||||
|
||||
\verbatim
|
||||
+----+----+----+----+----+----+----+----+
|
||||
+ + + + + + TR + GL + MU +
|
||||
+----+----+----+----+----+----+----+----+
|
||||
\endverbatim
|
||||
|
||||
|
||||
It can be seen this is like a normal ethernet MAC address,
|
||||
with GL being the Global/Local bit, and MU being the
|
||||
Multicast/Unicast bit.
|
||||
|
||||
The addition is the 'TR' bit, which if set indicates that
|
||||
the address must be translated when going between 802.15.4
|
||||
and 802.3.
|
||||
|
||||
\par Address Translation
|
||||
|
||||
If the TRANSLATE (TR) bit is CLEAR, this means the 5th and
|
||||
4th LSBytes of the 802.15.4 address are fffe, aka the address
|
||||
has the hexidecial form:
|
||||
|
||||
xxxxxxfffexxxxxx
|
||||
|
||||
\note
|
||||
You should always aim to set the 802.15.4 addresses
|
||||
of the devices on your network to ones that will
|
||||
satisfy this requirement. Some examples are:
|
||||
\note
|
||||
0x02 23 42 ff fe 73 92 28
|
||||
\note
|
||||
0x82 00 82 ff fe cd ee 22
|
||||
|
||||
\note
|
||||
So the most significant octets MUST
|
||||
have bit 0 CLEAR, bit 1 SET, and bit 2 CLEAR. The remaining
|
||||
bits in this octet can be anything.
|
||||
|
||||
If the TRANSLATE bit is SET, this means the address on the
|
||||
802.3 side does not directly convert to an 802.15.4 address.
|
||||
To translate it, the remainder of the octet is used as an
|
||||
index in a look-up table. This look-up table simply stores
|
||||
the 4th, 5th, and 8th octet of the 802.15.4 address, and attaches
|
||||
them to the remaining 5 bytes of the 802.3 address.
|
||||
|
||||
In this way there can be 32 different 802.15.4 'prefixes',
|
||||
requiring only 96 bytes of RAM in a storage table on the
|
||||
802.3 to 802.15.4 bridge.
|
||||
|
||||
Mulitcast addresses on 802.3 are mapped to broadcast addresses on
|
||||
802.15.4 and vis-versa. Since IPv6 does not use 802.3 broadcast,
|
||||
this code will drop all 802.3 broadcast packets. They are most
|
||||
likely something unwanted, such as IPv4 packets that snuck in.
|
||||
|
||||
\par Notes on how addresses are stored
|
||||
|
||||
An 802.15.4 address will be reported for example as:
|
||||
|
||||
0x8877665544332211
|
||||
|
||||
Stored in the array as passed to these functions, it will be:
|
||||
\verbatim
|
||||
array[0] = 0x88;
|
||||
array[1] = 0x77;
|
||||
array[2] = 0x66;
|
||||
etc.
|
||||
\endverbatim
|
||||
|
||||
An 802.3 address will be reported for example as:
|
||||
02:43:53:35:45:45
|
||||
|
||||
Stored in the array as passed to these functions, it will be:
|
||||
\verbatim
|
||||
array[0] = 0x02;
|
||||
array[1] = 0x43;
|
||||
array[2] = 0x53;
|
||||
array[3] = 0x35
|
||||
etc.
|
||||
\endverbatim
|
||||
*/
|
||||
|
||||
#include "uip.h"
|
||||
#include "uip_arp.h" /* For ethernet header structure */
|
||||
#include "net/ipv6/sicslowpan.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
//#define PRINTF printf
|
||||
#define PRINTF(...)
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define ETHBUF(x) ((struct uip_eth_hdr *)x)
|
||||
|
||||
//For little endian, such as our friend mr. AVR
|
||||
#ifndef LSB
|
||||
#define LSB(u16) (((uint8_t *)&(u16))[0]) //!< Least significant byte of \a u16.
|
||||
#define MSB(u16) (((uint8_t *)&(u16))[1]) //!< Most significant byte of \a u16.
|
||||
#endif
|
||||
|
||||
usbstick_mode_t usbstick_mode;
|
||||
|
||||
uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
|
||||
uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
|
||||
/* uint8_t memcmp_reverse(uint8_t * a, uint8_t * b, uint8_t num); */
|
||||
/* void mac_ethhijack_nondata(const struct mac_driver *r); */
|
||||
/* void mac_ethhijack(const struct mac_driver *r); */
|
||||
|
||||
/* extern void (*sicslowmac_snifferhook)(const struct mac_driver *r); */
|
||||
|
||||
|
||||
//! Location of TRANSLATE (TR) bit in Ethernet address
|
||||
#define TRANSLATE_BIT_MASK (1<<2)
|
||||
//! Location of LOCAL (GL) bit in Ethernet address
|
||||
#define LOCAL_BIT_MASK (1<<1)
|
||||
//! Location of MULTICAST (MU) bit in Ethernet address
|
||||
#define MULTICAST_BIT_MASK (1<<0)
|
||||
|
||||
#define PREFIX_BUFFER_SIZE 32
|
||||
|
||||
uint8_t prefixCounter;
|
||||
uint8_t prefixBuffer[PREFIX_BUFFER_SIZE][3];
|
||||
|
||||
/* 6lowpan max size + ethernet header size + 1 */
|
||||
uint8_t raw_buf[127+ UIP_LLH_LEN +1];
|
||||
|
||||
|
||||
/* void tcpip_input( void ) */
|
||||
/* { */
|
||||
/* mac_LowpanToEthernet(); */
|
||||
/* } */
|
||||
|
||||
/**
|
||||
* \brief Perform any setup needed
|
||||
*/
|
||||
/* struct mac_driver * pmac; */
|
||||
void mac_ethernetSetup(void)
|
||||
{
|
||||
usbstick_mode.sicslowpan = 1;
|
||||
usbstick_mode.sendToRf = 1;
|
||||
usbstick_mode.translate = 1;
|
||||
usbstick_mode.raw = 1;
|
||||
|
||||
/* sicslowinput = pinput; */
|
||||
|
||||
|
||||
/* pmac = sicslowmac_get_driver(); */
|
||||
/* pmac->set_receive_function(mac_ethhijack); */
|
||||
/* sicslowmac_snifferhook = mac_ethhijack_nondata; */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Take a packet received over the ethernet link, and send it
|
||||
* out over 802.15.4
|
||||
*/
|
||||
void mac_ethernetToLowpan(uint8_t * ethHeader)
|
||||
{
|
||||
//Dest address
|
||||
uip_lladdr_t destAddr;
|
||||
uip_lladdr_t *destAddrPtr = NULL;
|
||||
|
||||
PRINTF("Packet type: %x\n", ((struct uip_eth_hdr *) ethHeader)->type);
|
||||
|
||||
//RUM doesn't support sending data
|
||||
#if UIP_CONF_USE_RUM
|
||||
return;
|
||||
#endif
|
||||
|
||||
//If not IPv6 we don't do anything
|
||||
if (((struct uip_eth_hdr *) ethHeader)->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) {
|
||||
PRINTF("eth2low: Packet is not IPv6, dropping\n");
|
||||
/* rndis_stat.txbad++; */
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
|
||||
// In sniffer mode we don't ever send anything
|
||||
if (usbstick_mode.sendToRf == 0) {
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
|
||||
/* IPv6 uses 33-33-xx-xx-xx-xx prefix for multicast ND stuff */
|
||||
if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0x33) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0x33) )
|
||||
{
|
||||
PRINTF("eth2low: Ethernet multicast packet received\n");
|
||||
;//Do Nothing
|
||||
} else if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0xFF) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0xFF) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[2] == 0xFF) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[3] == 0xFF) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[4] == 0xFF) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[5] == 0xFF) ) {
|
||||
/* IPv6 does not use broadcast addresses, hence this should not happen */
|
||||
PRINTF("eth2low: Ethernet broadcast address received, should not happen?\n");
|
||||
/* rndis_stat.txbad++; */
|
||||
uip_clear_buf();
|
||||
return;
|
||||
} else {
|
||||
PRINTF("eth2low: Addressed packet received... ");
|
||||
//Check this returns OK
|
||||
if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) {
|
||||
PRINTF(" translation failed\n");
|
||||
/* rndis_stat.txbad++; */
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
PRINTF(" translated OK\n");
|
||||
destAddrPtr = &destAddr;
|
||||
}
|
||||
|
||||
//Remove header from length before passing onward
|
||||
if(uip_len > UIP_LLH_LEN) {
|
||||
uip_len -= UIP_LLH_LEN;
|
||||
|
||||
//Some IP packets have link layer in them, need to change them around!
|
||||
if (usbstick_mode.translate) {
|
||||
/* uint8_t transReturn = */
|
||||
mac_translateIPLinkLayer(ll_802154_type);
|
||||
PRINTF("IPTranslation: returns %d\n", transReturn);
|
||||
}
|
||||
|
||||
if (usbstick_mode.sendToRf){
|
||||
tcpip_output(destAddrPtr);
|
||||
/* rndis_stat.txok++; */
|
||||
}
|
||||
}
|
||||
|
||||
uip_clear_buf();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Take a packet received over the 802.15.4 link, and send it
|
||||
* out over ethernet, performing any translations needed.
|
||||
*/
|
||||
void mac_LowpanToEthernet(void)
|
||||
{
|
||||
/* parsed_frame = sicslowmac_get_frame(); */
|
||||
|
||||
//Setup generic ethernet stuff
|
||||
ETHBUF(uip_buf)->type = uip_htons(UIP_ETHTYPE_IPV6);
|
||||
|
||||
//Check for broadcast message
|
||||
if(packetbuf_holds_broadcast()) {
|
||||
/* if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) && */
|
||||
/* ( parsed_frame->dest_addr->addr16 == 0xffff) ) { */
|
||||
ETHBUF(uip_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(uip_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
} else {
|
||||
//Otherwise we have a real address
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
}
|
||||
|
||||
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
|
||||
//We only do address translation in network mode!
|
||||
if (usbstick_mode.translate) {
|
||||
//Some IP packets have link layer in them, need to change them around!
|
||||
mac_translateIPLinkLayer(ll_8023_type);
|
||||
}
|
||||
|
||||
PRINTF("Low2Eth: Sending packet to ethernet\n");
|
||||
|
||||
uip_len += UIP_LLH_LEN;
|
||||
|
||||
/* rndis_send(uip_buf, uip_len, 1); */
|
||||
/* rndis_stat.rxok++; */
|
||||
/* uip_clear_buf(); */
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Translate IP packet's possible link-layer addresses, passing
|
||||
* the message to the appropriate higher level function for this
|
||||
* packet (aka: ICMP)
|
||||
* \param target The target we want to end up with - either ll_8023_type
|
||||
* for ethernet, or ll_802154_type for 802.15.4
|
||||
* \return Returns how successful the translation was
|
||||
* \retval 0 Addresses, if present, were translated.
|
||||
* \retval <0 Negative return values indicate various errors, as defined
|
||||
* by the higher level function.
|
||||
*/
|
||||
int8_t mac_translateIPLinkLayer(lltype_t target)
|
||||
{
|
||||
|
||||
#if UIP_LLADDR_LEN == 8
|
||||
if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
|
||||
PRINTF("eth2low: ICMP Message detected\n");
|
||||
return mac_translateIcmpLinkLayer(target);
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#include "net/ipv6/uip-icmp6.h"
|
||||
#include "net/ipv6/uip-nd6.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t data[16];
|
||||
} icmp_opts_t;
|
||||
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#define UIP_ICMP_OPTS(x) ((icmp_opts_t *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + x])
|
||||
|
||||
void slide(uint8_t * data, uint8_t length, int16_t slide);
|
||||
|
||||
/**
|
||||
* \brief Translate the link-layer (L2) addresses in an ICMP packet.
|
||||
* This will just be NA/NS/RA/RS packets currently.
|
||||
* \param target The target we want to end up with - either ll_8023_type
|
||||
* for ethernet, or ll_802154_type for 802.15.4
|
||||
* \return Returns how successful the translation was
|
||||
* \retval 0 Addresses, if present, were translated.
|
||||
* \retval -1 ICMP message was unknown type, nothing done.
|
||||
* \retval -2 ICMP Length does not make sense?
|
||||
* \retval -3 Unknown 'target' type
|
||||
*/
|
||||
int8_t mac_translateIcmpLinkLayer(lltype_t target)
|
||||
{
|
||||
uint16_t icmp_opt_offset = 0;
|
||||
int16_t len = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0] << 8);
|
||||
|
||||
uint16_t iplen;
|
||||
|
||||
uint8_t i;
|
||||
|
||||
int16_t sizechange;
|
||||
|
||||
uint8_t llbuf[16];
|
||||
|
||||
//Figure out offset to start of options
|
||||
switch(UIP_ICMP_BUF->type) {
|
||||
case ICMP6_NS:
|
||||
case ICMP6_NA:
|
||||
icmp_opt_offset = 24;
|
||||
break;
|
||||
|
||||
case ICMP6_RS:
|
||||
icmp_opt_offset = 8;
|
||||
break;
|
||||
|
||||
case ICMP6_RA:
|
||||
icmp_opt_offset = 16;
|
||||
break;
|
||||
|
||||
case ICMP6_REDIRECT:
|
||||
icmp_opt_offset = 40;
|
||||
break;
|
||||
|
||||
/** Things without link-layer */
|
||||
case ICMP6_DST_UNREACH:
|
||||
case ICMP6_PACKET_TOO_BIG:
|
||||
case ICMP6_TIME_EXCEEDED:
|
||||
case ICMP6_PARAM_PROB:
|
||||
case ICMP6_ECHO_REQUEST:
|
||||
case ICMP6_ECHO_REPLY:
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Figure out length of options
|
||||
len -= icmp_opt_offset;
|
||||
|
||||
//Sanity check
|
||||
if (len < 8) return -2;
|
||||
|
||||
//While we have options to do...
|
||||
while (len >= 8){
|
||||
|
||||
//If we have one of these, we have something useful!
|
||||
if (((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_SLLAO) ||
|
||||
((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_TLLAO) ) {
|
||||
|
||||
/* Shrinking the buffer may thrash things, so we store the old
|
||||
link-layer address */
|
||||
for(i = 0; i < (UIP_ICMP_OPTS(icmp_opt_offset)->length*8 - 2); i++) {
|
||||
llbuf[i] = UIP_ICMP_OPTS(icmp_opt_offset)->data[i];
|
||||
}
|
||||
|
||||
//Shrink/grow buffer as needed
|
||||
if (target == ll_802154_type) {
|
||||
//Current is 802.3, Hence current link-layer option is 6 extra bytes
|
||||
sizechange = 8;
|
||||
slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 6, len - 6, sizechange);
|
||||
} else if (target == ll_8023_type) {
|
||||
/* Current is 802.15.4, Hence current link-layer option is 14 extra
|
||||
* bytes.
|
||||
* (Actual LL is 8 bytes, but total option length is in multiples of
|
||||
* 8 Bytes, hence 8 + 2 = 10. Closest is 16 bytes, then 16 bytes for
|
||||
* total optional length - 2 bytes for type + length leaves 14 )
|
||||
*/
|
||||
sizechange = -8;
|
||||
slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 14, len - 14, sizechange);
|
||||
} else {
|
||||
return -3; //Uh-oh!
|
||||
}
|
||||
|
||||
//Translate addresses
|
||||
if (target == ll_802154_type) {
|
||||
mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data);
|
||||
} else {
|
||||
mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf);
|
||||
}
|
||||
|
||||
//Adjust the length
|
||||
if (target == ll_802154_type) {
|
||||
UIP_ICMP_OPTS(icmp_opt_offset)->length = 2;
|
||||
} else {
|
||||
UIP_ICMP_OPTS(icmp_opt_offset)->length = 1;
|
||||
}
|
||||
|
||||
//Adjust the IP header length, as well as uIP length
|
||||
iplen = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0]<<8);
|
||||
iplen += sizechange;
|
||||
len += sizechange;
|
||||
|
||||
UIP_IP_BUF->len[1] = (uint8_t)iplen;
|
||||
UIP_IP_BUF->len[0] = (uint8_t)(iplen >> 8);
|
||||
|
||||
uip_len += sizechange;
|
||||
|
||||
//We broke ICMP checksum, be sure to fix that
|
||||
UIP_ICMP_BUF->icmpchksum = 0;
|
||||
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
|
||||
|
||||
//Finally set up next run in while loop
|
||||
len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
|
||||
icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
|
||||
} else {
|
||||
|
||||
//Not an option we care about, ignore it
|
||||
len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
|
||||
|
||||
//This shouldn't happen!
|
||||
if (UIP_ICMP_OPTS(icmp_opt_offset)->length == 0) {
|
||||
PRINTF("Option in ND packet has length zero, error?\n");
|
||||
len = 0;
|
||||
}
|
||||
|
||||
icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
|
||||
|
||||
} //If ICMP_OPT is one we care about
|
||||
|
||||
} //while(len >= 8)
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Create a 802.15.4 long address from a 802.3 address
|
||||
* \param ethernet Pointer to ethernet address
|
||||
* \param lowpan Pointer to 802.15.4 address
|
||||
*/
|
||||
uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
#if UIP_LLADDR_LEN == 8
|
||||
//Special case - if the address is our address, we just copy over what we know to be
|
||||
//our 802.15.4 address
|
||||
|
||||
/* if (memcmp_reverse((uint8_t *)&rndis_ethernet_addr, ethernet, 6) == 0) { */
|
||||
if (memcmp((uint8_t *)&uip_lladdr.addr[2], ethernet, 6) == 0) {
|
||||
memcpy((uint8_t *)lowpan, uip_lladdr.addr, 8);
|
||||
/* byte_reverse((uint8_t *)lowpan, 8); */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Check if translate bit is set, hence we have to look up the prefix
|
||||
if (ethernet[0] & TRANSLATE_BIT_MASK) {
|
||||
|
||||
//Get top bits
|
||||
index = ethernet[0] >> 3;
|
||||
|
||||
//Check this is plausible...
|
||||
if (index >= prefixCounter) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Copy over prefix
|
||||
lowpan->addr[0] = prefixBuffer[index][0];
|
||||
lowpan->addr[3] = prefixBuffer[index][1];
|
||||
lowpan->addr[4] = prefixBuffer[index][2];
|
||||
|
||||
//Bit is clear
|
||||
//so we copy all six
|
||||
} else {
|
||||
lowpan->addr[0] = ethernet[0];
|
||||
lowpan->addr[3] = 0xff;
|
||||
lowpan->addr[4] = 0xfe;
|
||||
}
|
||||
|
||||
//Copy over reamining five bytes
|
||||
lowpan->addr[1] = ethernet[1];
|
||||
lowpan->addr[2] = ethernet[2];
|
||||
lowpan->addr[5] = ethernet[3];
|
||||
lowpan->addr[6] = ethernet[4];
|
||||
lowpan->addr[7] = ethernet[5];
|
||||
|
||||
#else
|
||||
uint8_t i;
|
||||
|
||||
for(i = 0; i < UIP_LLADDR_LEN; i++) {
|
||||
lowpan->addr[i] = ethernet[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Create a 802.3 address from a 802.15.4 long address
|
||||
* \param ethernet Pointer to ethernet address
|
||||
* \param lowpan Pointer to 802.15.4 address
|
||||
*/
|
||||
uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
||||
{
|
||||
uint8_t index = 0;
|
||||
uint8_t i;
|
||||
/* uint8_t j, match; */
|
||||
|
||||
#if UIP_LLADDR_LEN == 8
|
||||
|
||||
//Special case - if the address is our address, we just copy over what we know to be
|
||||
//our 802.3 address
|
||||
/* if (memcmp_reverse(uip_lladdr.addr, (uint8_t *)lowpan, 8) == 0) { */
|
||||
if (memcmp(uip_lladdr.addr, (uint8_t *)lowpan, 8) == 0) {
|
||||
memcpy(ethernet, &uip_lladdr.addr[2], 6);
|
||||
/* byte_reverse(ethernet, 6); */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//Check if we need to do anything:
|
||||
if ((lowpan->addr[3] == 0xff) && (lowpan->addr[4] == 0xfe) &&
|
||||
((lowpan->addr[0] & TRANSLATE_BIT_MASK) == 0) &&
|
||||
((lowpan->addr[0] & MULTICAST_BIT_MASK) == 0) &&
|
||||
(lowpan->addr[0] & LOCAL_BIT_MASK)) {
|
||||
|
||||
/** Nope: just copy over 6 bytes **/
|
||||
ethernet[0] = lowpan->addr[0];
|
||||
ethernet[1] = lowpan->addr[1];
|
||||
ethernet[2] = lowpan->addr[2];
|
||||
ethernet[3] = lowpan->addr[5];
|
||||
ethernet[4] = lowpan->addr[6];
|
||||
ethernet[5] = lowpan->addr[7];
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
/** Yes: need to store prefix **/
|
||||
for (i = 0; i < prefixCounter; i++) {
|
||||
//Check the current prefix - if it fails, check next one
|
||||
|
||||
|
||||
if ((lowpan->addr[0] == prefixBuffer[i][0]) &&
|
||||
(lowpan->addr[3] == prefixBuffer[i][1]) &&
|
||||
(lowpan->addr[4] == prefixBuffer[i][2])) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
index = i;
|
||||
|
||||
//Deal with overflow, iron-fist style
|
||||
if (index >= PREFIX_BUFFER_SIZE) {
|
||||
index = 0;
|
||||
prefixCounter = PREFIX_BUFFER_SIZE;
|
||||
} else {
|
||||
//Are we making a new one?
|
||||
if (index == prefixCounter) {
|
||||
prefixCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
//Copy the prefix over, no matter if we have a new or old one
|
||||
prefixBuffer[index][0] = lowpan->addr[0];
|
||||
prefixBuffer[index][1] = lowpan->addr[3];
|
||||
prefixBuffer[index][2] = lowpan->addr[4];
|
||||
|
||||
//Create ethernet MAC address now
|
||||
ethernet[1] = lowpan->addr[1];
|
||||
ethernet[2] = lowpan->addr[2];
|
||||
ethernet[3] = lowpan->addr[5];
|
||||
ethernet[4] = lowpan->addr[6];
|
||||
ethernet[5] = lowpan->addr[7];
|
||||
|
||||
|
||||
ethernet[0] = TRANSLATE_BIT_MASK | LOCAL_BIT_MASK | (index << 3);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//Create ethernet MAC address now
|
||||
for(i = 0; i < UIP_LLADDR_LEN; i++) {
|
||||
ethernet[i] = lowpan->addr[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Slide the pointed to memory up a certain amount,
|
||||
* growing/shrinking a buffer
|
||||
* \param data Pointer to start of data buffer
|
||||
* \param length Length of the data buffer
|
||||
* \param slide How many bytes to slide the buffer up in memory (if +) or
|
||||
* down in memory (if -)
|
||||
*/
|
||||
void slide(uint8_t * data, uint8_t length, int16_t slide)
|
||||
{
|
||||
//Sanity checks
|
||||
if (!length) return;
|
||||
if (!slide) return;
|
||||
|
||||
uint8_t i = 0;
|
||||
|
||||
while(length) {
|
||||
length--;
|
||||
|
||||
//If we are sliding up, we do from the top of the buffer down
|
||||
if (slide > 0) {
|
||||
*(data + length + slide) = *(data + length);
|
||||
|
||||
//If we are sliding down, we do from the bottom of the buffer up
|
||||
} else {
|
||||
*(data + slide + i) = *(data + i);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/** \brief Process a received 6lowpan packet. Hijack function.
|
||||
* \param r The MAC layer
|
||||
*
|
||||
* The 6lowpan packet is put in packetbuf by the MAC. This routine calls
|
||||
* any other needed layers (either 6lowpan, or just raw ethernet dump)
|
||||
*/
|
||||
#if 0
|
||||
void mac_ethhijack(const struct mac_driver *r)
|
||||
{
|
||||
if (usbstick_mode.raw) {
|
||||
mac_802154raw(r);
|
||||
}
|
||||
|
||||
if (usbstick_mode.sicslowpan) {
|
||||
|
||||
#if UIP_CONF_USE_RUM
|
||||
if (parsed_frame->payload[4]) { /* RUM 6lowpan frame type */
|
||||
#endif
|
||||
sicslowinput(r);
|
||||
#if UIP_CONF_USE_RUM
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
void mac_ethhijack_nondata(const struct mac_driver *r)
|
||||
{
|
||||
if (usbstick_mode.raw)
|
||||
mac_802154raw(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/*--------------------------------------------------------------------*/
|
||||
/** \brief Logs a sent 6lowpan frame
|
||||
*
|
||||
* This routine passes a frame
|
||||
* directly to the ethernet layer without decompressing.
|
||||
*/
|
||||
#if 0
|
||||
void mac_logTXtoEthernet(frame_create_params_t *p,frame_result_t *frame_result)
|
||||
{
|
||||
uint8_t sendlen;
|
||||
|
||||
/* Make sure we are supposed to do this */
|
||||
if (usbstick_mode.raw == 0) return;
|
||||
|
||||
/* Get the raw frame */
|
||||
memcpy(&raw_buf[UIP_LLH_LEN], frame_result->frame, frame_result->length);
|
||||
sendlen = frame_result->length;
|
||||
|
||||
//Setup generic ethernet stuff
|
||||
ETHBUF(raw_buf)->type = uip_htons(UIP_ETHTYPE_802154);
|
||||
|
||||
uint64_t tempaddr;
|
||||
|
||||
|
||||
//Check for broadcast message
|
||||
//if(linkaddr_cmp((const linkaddr_t *)destAddr, &linkaddr_null)) {
|
||||
if( ( p->fcf.destAddrMode == SHORTADDRMODE) &&
|
||||
( p->dest_addr.addr16 == 0xffff) ) {
|
||||
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
} else {
|
||||
|
||||
tempaddr = p->dest_addr.addr64;
|
||||
|
||||
byte_reverse((uint8_t *)&tempaddr, 8);
|
||||
|
||||
//Otherwise we have a real address
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)&tempaddr);
|
||||
|
||||
}
|
||||
|
||||
tempaddr = p->src_addr.addr64;
|
||||
|
||||
byte_reverse((uint8_t *)&tempaddr, 8);
|
||||
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),
|
||||
(uip_lladdr_t *)&tempaddr);
|
||||
|
||||
PRINTF("Low2Eth: Sending 802.15.4 packet to ethernet\n");
|
||||
|
||||
sendlen += UIP_LLH_LEN;
|
||||
|
||||
rndis_send(raw_buf, sendlen, 0);
|
||||
rndis_stat.rxok++;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/** \brief Process a received 6lowpan packet.
|
||||
* \param r The MAC layer
|
||||
*
|
||||
* The 6lowpan packet is put in packetbuf by the MAC. This routine passes
|
||||
* it directly to the ethernet layer without decompressing.
|
||||
*/
|
||||
#if 0
|
||||
void mac_802154raw(const struct mac_driver *r)
|
||||
{
|
||||
uint8_t sendlen;
|
||||
|
||||
parsed_frame = sicslowmac_get_frame();
|
||||
|
||||
/* Get the raw frame */
|
||||
memcpy(&raw_buf[UIP_LLH_LEN], radio_frame_data(), radio_frame_length());
|
||||
sendlen = radio_frame_length();
|
||||
|
||||
//Setup generic ethernet stuff
|
||||
ETHBUF(raw_buf)->type = uip_htons(UIP_ETHTYPE_802154);
|
||||
|
||||
|
||||
//Check for broadcast message
|
||||
//if(linkaddr_cmp((const linkaddr_t *)destAddr, &linkaddr_null)) {
|
||||
if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) &&
|
||||
( parsed_frame->dest_addr->addr16 == 0xffff) ) {
|
||||
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
} else {
|
||||
|
||||
//Otherwise we have a real address
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
|
||||
}
|
||||
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
|
||||
PRINTF("Low2Eth: Sending 802.15.4 packet to ethernet\n");
|
||||
|
||||
sendlen += UIP_LLH_LEN;
|
||||
|
||||
rndis_send(raw_buf, sendlen, 1);
|
||||
rndis_stat.rxok++;
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
* \file sicslow_ethernet.c
|
||||
* Routines to interface between Ethernet and 6LowPan
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2008 by:
|
||||
|
||||
Colin O'Flynn coflynn@newae.com
|
||||
Eric Gnoske egnoske@gmail.com
|
||||
Blake Leverett bleverett@gmail.com
|
||||
Mike Vidales mavida404@gmail.com
|
||||
Kevin Brown kbrown3@uccs.edu
|
||||
Nate Bohlmann nate@elfwerks.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:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* 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.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
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 OWNER 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 SICSLOW_ETHERNET_H
|
||||
#define SICSLOW_ETHERNET_H
|
||||
|
||||
typedef enum {
|
||||
ll_802154_type,
|
||||
ll_8023_type
|
||||
} lltype_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t sicslowpan :1;
|
||||
uint8_t sendToRf :1;
|
||||
uint8_t translate :1;
|
||||
uint8_t raw :1;
|
||||
} usbstick_mode_t;
|
||||
|
||||
|
||||
#define UIP_ETHTYPE_802154 0x809A
|
||||
|
||||
extern usbstick_mode_t usbstick_mode;
|
||||
|
||||
|
||||
int8_t mac_translateIcmpLinkLayer(lltype_t target);
|
||||
int8_t mac_translateIPLinkLayer(lltype_t target);
|
||||
void mac_LowpanToEthernet(void);
|
||||
void mac_ethernetToLowpan(uint8_t * ethHeader);
|
||||
void mac_ethernetSetup(void);
|
||||
/* void mac_802154raw(const struct mac_driver *r); */
|
||||
/* void mac_logTXtoEthernet(frame_create_params_t *p,frame_result_t *frame_result); */
|
||||
|
||||
#endif
|
|
@ -1,152 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2009, 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.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A brief description of what this file is
|
||||
* \author
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "net/ipv6/uip.h"
|
||||
#include "dev/slip.h"
|
||||
#include "dev/leds.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
|
||||
#include "net/packetbuf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
PROCESS(uip6_bridge, "IPv6/6lowpan TAP bridge");
|
||||
PROCESS(tcpip_process, "tcpip dummy");
|
||||
AUTOSTART_PROCESSES(&uip6_bridge);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t (* outputfunc)(const uip_lladdr_t *a);
|
||||
uint8_t
|
||||
tcpip_output(const uip_lladdr_t *a)
|
||||
{
|
||||
if(outputfunc != NULL) {
|
||||
outputfunc(a);
|
||||
leds_toggle(LEDS_GREEN);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void
|
||||
tcpip_ipv6_output(void)
|
||||
{
|
||||
}
|
||||
void
|
||||
tcpip_set_outputfunc(uint8_t (*f)(const uip_lladdr_t *))
|
||||
{
|
||||
outputfunc = f;
|
||||
}
|
||||
PROCESS_THREAD(tcpip_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Packet from SICSLoWPAN */
|
||||
void
|
||||
tcpip_input(void)
|
||||
{
|
||||
if(uip_len > 0) {
|
||||
mac_LowpanToEthernet();
|
||||
if(uip_len > 0) {
|
||||
slip_write(uip_buf, uip_len);
|
||||
leds_toggle(LEDS_RED);
|
||||
uip_clear_buf();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Packet from SLIP */
|
||||
static void
|
||||
slip_tcpip_input(void)
|
||||
{
|
||||
/* TODO Should fix this in slip configuration */
|
||||
memmove(uip_buf, &uip_buf[UIP_LLH_LEN], uip_len);
|
||||
mac_ethernetToLowpan(uip_buf);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
slip_activity(void)
|
||||
{
|
||||
leds_toggle(LEDS_BLUE);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(uip6_bridge, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
printf("Setting up SLIP\n");
|
||||
|
||||
mac_ethernetSetup();
|
||||
|
||||
slip_arch_init();
|
||||
slip_set_input_callback(slip_activity);
|
||||
slip_set_tcpip_input_callback(slip_tcpip_input);
|
||||
process_start(&slip_process, NULL);
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
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;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -451,7 +451,7 @@ arp_out(struct ethip_hdr *iphdr, int len)
|
|||
arphdr->protolen = 4;
|
||||
arphdr->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP);
|
||||
|
||||
/* uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];*/
|
||||
/* uip_appdata = &uip_buf[UIP_IPTCPH_LEN];*/
|
||||
|
||||
return sizeof(struct arp_hdr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue