net: Remove legacy Contiki based uIP stack

This commit removes the legacy Contiki based uIP stack.
The new native IP stack must be used after this commit.

The commit also removes following things:
- legacy cc2520 driver
- legacy ethernet drivers
- legacy IP stack samples

and changes these things:
- disabled tests that only work for legacy IP stack
- select new IP stack by default
- enable random number generator by default as it is needed
  by the new IP stack

Change-Id: I1229f9960a4c6654e9ccc6dac14a7efb9394e45d
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
This commit is contained in:
Jukka Rissanen 2016-11-11 19:49:31 +02:00
commit 6b43821f20
436 changed files with 14 additions and 81965 deletions

View file

@ -3,14 +3,5 @@ ccflags-y += -I$(srctree)/drivers
ccflags-y += -I$(srctree)/drivers/pinmux
asflags-y := ${ccflags-y}
ccflags-$(CONFIG_TI_CC2520_LEGACY) += \
-I${srctree}/net/ip/contiki
ccflags-$(CONFIG_TI_CC2520_LEGACY) += \
-I${srctree}/net/ip/contiki/os/lib
ccflags-$(CONFIG_TI_CC2520_LEGACY) += \
-I${srctree}/net/ip/contiki/os
ccflags-$(CONFIG_TI_CC2520_LEGACY) += \
-I${srctree}/net/ip
obj-$(CONFIG_PINMUX) += pinmux.o
obj-y += board.o

View file

@ -1,14 +1,5 @@
ccflags-y += -I${srctree}/net/ip/contiki
ccflags-y += -I${srctree}/net/ip/contiki/os/lib
ccflags-y += -I${srctree}/net/ip/contiki/os
ccflags-y += -I${srctree}/net/ip
ccflags-y += -I${srctree}
obj-$(CONFIG_ETH_DW) += eth_dw.o
ifdef CONFIG_NET_YAIP
obj-$(CONFIG_ETH_KSDK) += eth_ksdk.o
obj-$(CONFIG_ETH_ENC28J60) += eth_enc28j60.o
else
obj-$(CONFIG_ETH_KSDK) += eth_ksdk_legacy.o
obj-$(CONFIG_ETH_ENC28J60) += eth_enc28j60_legacy.o
endif

View file

@ -1,335 +0,0 @@
/* KSDK Ethernet Driver
*
* Copyright (c) 2016 ARM Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* The driver performs one shot PHY setup. There is no support for
* PHY disconnect, reconnect or configuration change. The PHY setup,
* implemented via KSDK contains polled code that can block the
* initialization thread for a few seconds.
*
* There is no statistics collection for either normal operation or
* error behaviour.
*/
#include <board.h>
#include <device.h>
#include <misc/util.h>
#include <nanokernel.h>
#include <net/ip/net_driver_ethernet.h>
#include "fsl_enet.h"
#include "fsl_phy.h"
#include "fsl_port.h"
#define SYS_LOG_DOMAIN "dev/eth_ksdk"
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_ETHERNET_LEVEL
#include <misc/sys_log.h>
struct eth_context {
enet_handle_t enet_handle;
struct nano_sem tx_buf_sem;
uint8_t mac_addr[6];
};
static int eth_net_tx(struct net_buf *);
static void eth_0_config_func(void);
static enet_rx_bd_struct_t __aligned(ENET_BUFF_ALIGNMENT)
rx_buffer_desc[CONFIG_ETH_KSDK_TX_BUFFERS];
static enet_tx_bd_struct_t __aligned(ENET_BUFF_ALIGNMENT)
tx_buffer_desc[CONFIG_ETH_KSDK_TX_BUFFERS];
/* Use ENET_FRAME_MAX_VALNFRAMELEN for VLAN frame size
* Use ENET_FRAME_MAX_FRAMELEN for ethernet frame size
*/
#define ETH_KSDK_BUFFER_SIZE \
ROUND_UP(ENET_FRAME_MAX_VALNFRAMELEN, ENET_BUFF_ALIGNMENT)
static uint8_t __aligned(ENET_BUFF_ALIGNMENT)
rx_buffer[CONFIG_ETH_KSDK_RX_BUFFERS][ETH_KSDK_BUFFER_SIZE];
static uint8_t __aligned(ENET_BUFF_ALIGNMENT)
tx_buffer[CONFIG_ETH_KSDK_TX_BUFFERS][ETH_KSDK_BUFFER_SIZE];
static int eth_tx(struct device *iface, struct net_buf *buf)
{
struct eth_context *context = iface->driver_data;
status_t status;
nano_sem_take(&context->tx_buf_sem, TICKS_UNLIMITED);
status = ENET_SendFrame(ENET, &context->enet_handle, uip_buf(buf),
uip_len(buf));
if (status) {
SYS_LOG_ERR("ENET_SendFrame error: %d\n", status);
return 0;
}
return 1;
}
static void eth_rx(struct device *iface)
{
struct eth_context *context = iface->driver_data;
struct net_buf *buf;
uint32_t frame_length = 0;
status_t status;
status = ENET_GetRxFrameSize(&context->enet_handle, &frame_length);
if (status) {
enet_data_error_stats_t error_stats;
SYS_LOG_ERR("ENET_GetRxFrameSize return: %d", status);
ENET_GetRxErrBeforeReadFrame(&context->enet_handle,
&error_stats);
/* Flush the current read buffer. This operation can
* only report failure if there is no frame to flush,
* which cannot happen in this context.
*/
status = ENET_ReadFrame(ENET, &context->enet_handle, NULL, 0);
assert(status == kStatus_Success);
return;
}
buf = ip_buf_get_reserve_rx(0);
if (buf == NULL) {
/* We failed to get a receive buffer. We don't add
* any further logging here because the allocator
* issued a diagnostic when it failed to allocate.
*
* Flush the current read buffer. This operation can
* only report failure if there is no frame to flush,
* which cannot happen in this context.
*/
status = ENET_ReadFrame(ENET, &context->enet_handle, NULL, 0);
assert(status == kStatus_Success);
return;
}
if (net_buf_tailroom(buf) < frame_length) {
SYS_LOG_ERR("frame too large\n");
net_buf_unref(buf);
status = ENET_ReadFrame(ENET, &context->enet_handle, NULL, 0);
assert(status == kStatus_Success);
return;
}
status = ENET_ReadFrame(ENET, &context->enet_handle,
net_buf_add(buf, frame_length), frame_length);
if (status) {
SYS_LOG_ERR("ENET_ReadFrame failed: %d\n", status);
net_buf_unref(buf);
return;
}
uip_len(buf) = frame_length;
net_driver_ethernet_recv(buf);
}
void eth_callback(ENET_Type *base, enet_handle_t *handle, enet_event_t event,
void *param)
{
struct device *iface = param;
struct eth_context *context = iface->driver_data;
switch (event) {
case kENET_RxEvent:
eth_rx(iface);
break;
case kENET_TxEvent:
/* Free the TX buffer. */
nano_sem_give(&context->tx_buf_sem);
break;
case kENET_ErrEvent:
/* Error event: BABR/BABT/EBERR/LC/RL/UN/PLR. */
break;
case kENET_WakeUpEvent:
/* Wake up from sleep mode event. */
break;
#ifdef ENET_ENHANCEDBUFFERDESCRIPTOR_MODE
case kENET_TimeStampEvent:
/* Time stamp event. */
break;
case kENET_TimeStampAvailEvent:
/* Time stamp available event. */
break;
#endif
}
}
#if defined(CONFIG_ETH_KSDK_0_RANDOM_MAC)
static void generate_mac(uint8_t *mac_addr)
{
uint32_t entropy;
entropy = sys_rand32_get();
/* Locally administered, unicast */
mac_addr[0] = ((entropy >> 0) & 0xfc) | 0x02;
mac_addr[1] = entropy >> 8;
mac_addr[2] = entropy >> 16;
mac_addr[3] = entropy >> 24;
entropy = sys_rand32_get();
mac_addr[4] = entropy >> 0;
mac_addr[5] = entropy >> 8;
}
#endif
static int eth_0_init(struct device *dev)
{
struct eth_context *context = dev->driver_data;
enet_config_t enet_config;
uint32_t sys_clock;
const uint32_t phy_addr = 0x0;
bool link;
status_t status;
int result;
enet_buffer_config_t buffer_config = {
.rxBdNumber = CONFIG_ETH_KSDK_RX_BUFFERS,
.txBdNumber = CONFIG_ETH_KSDK_TX_BUFFERS,
.rxBuffSizeAlign = ETH_KSDK_BUFFER_SIZE,
.txBuffSizeAlign = ETH_KSDK_BUFFER_SIZE,
.rxBdStartAddrAlign = rx_buffer_desc,
.txBdStartAddrAlign = tx_buffer_desc,
.rxBufferAlign = rx_buffer[0],
.txBufferAlign = tx_buffer[0],
};
nano_sem_init(&context->tx_buf_sem);
for (int i = 0; i < CONFIG_ETH_KSDK_TX_BUFFERS; i++) {
nano_sem_give(&context->tx_buf_sem);
}
sys_clock = CLOCK_GetFreq(kCLOCK_CoreSysClk);
ENET_GetDefaultConfig(&enet_config);
enet_config.interrupt |= kENET_RxFrameInterrupt;
enet_config.interrupt |= kENET_TxFrameInterrupt;
status = PHY_Init(ENET, phy_addr, sys_clock);
if (status) {
SYS_LOG_ERR("PHY_Init() failed: %d", status);
return 1;
}
PHY_GetLinkStatus(ENET, phy_addr, &link);
if (link) {
phy_speed_t phy_speed;
phy_duplex_t phy_duplex;
PHY_GetLinkSpeedDuplex(ENET, phy_addr, &phy_speed, &phy_duplex);
enet_config.miiSpeed = (enet_mii_speed_t) phy_speed;
enet_config.miiDuplex = (enet_mii_duplex_t) phy_duplex;
SYS_LOG_INF("Enabled %dM %s-duplex mode.",
(phy_speed ? 100 : 10),
(phy_duplex ? "full" : "half"));
} else {
SYS_LOG_INF("Link down.");
}
#if defined(CONFIG_ETH_KSDK_0_RANDOM_MAC)
generate_mac(context->mac_addr);
#endif
ENET_Init(ENET,
&context->enet_handle,
&enet_config,
&buffer_config,
context->mac_addr,
sys_clock);
SYS_LOG_DBG("MAC %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
context->mac_addr[0], context->mac_addr[1],
context->mac_addr[2], context->mac_addr[3],
context->mac_addr[4], context->mac_addr[5]);
result = net_set_mac(context->mac_addr, sizeof(context->mac_addr));
if (result) {
return 1;
}
ENET_SetCallback(&context->enet_handle, eth_callback, dev);
net_driver_ethernet_register_tx(eth_net_tx);
eth_0_config_func();
ENET_ActiveRead(ENET);
return 0;
}
static void eth_ksdk_rx_isr(void *p)
{
struct device *dev = p;
struct eth_context *context = dev->driver_data;
ENET_ReceiveIRQHandler(ENET, &context->enet_handle);
}
static void eth_ksdk_tx_isr(void *p)
{
struct device *dev = p;
struct eth_context *context = dev->driver_data;
ENET_TransmitIRQHandler(ENET, &context->enet_handle);
}
static void eth_ksdk_error_isr(void *p)
{
struct device *dev = p;
struct eth_context *context = dev->driver_data;
ENET_ErrorIRQHandler(ENET, &context->enet_handle);
}
static struct eth_context eth_0_context = {
#if !defined(CONFIG_ETH_KSDK_0_RANDOM_MAC)
.mac_addr = {
CONFIG_ETH_KSDK_0_MAC0,
CONFIG_ETH_KSDK_0_MAC1,
CONFIG_ETH_KSDK_0_MAC2,
CONFIG_ETH_KSDK_0_MAC3,
CONFIG_ETH_KSDK_0_MAC4,
CONFIG_ETH_KSDK_0_MAC5
}
#endif
};
DEVICE_INIT(eth_ksdk_0, CONFIG_ETH_KSDK_0_NAME, eth_0_init,
&eth_0_context, NULL,
NANOKERNEL, CONFIG_ETH_INIT_PRIORITY);
static int eth_net_tx(struct net_buf *buf)
{
return eth_tx(DEVICE_GET(eth_ksdk_0), buf);
}
static void eth_0_config_func(void)
{
IRQ_CONNECT(IRQ_ETH_RX, CONFIG_ETH_KSDK_0_IRQ_PRI,
eth_ksdk_rx_isr, DEVICE_GET(eth_ksdk_0), 0);
irq_enable(IRQ_ETH_RX);
IRQ_CONNECT(IRQ_ETH_TX, CONFIG_ETH_KSDK_0_IRQ_PRI,
eth_ksdk_tx_isr, DEVICE_GET(eth_ksdk_0), 0);
irq_enable(IRQ_ETH_TX);
IRQ_CONNECT(IRQ_ETH_ERR_MISC, CONFIG_ETH_KSDK_0_IRQ_PRI,
eth_ksdk_error_isr, DEVICE_GET(eth_ksdk_0), 0);
irq_enable(IRQ_ETH_ERR_MISC);
}

View file

@ -35,11 +35,6 @@
#
menu "IEEE 802.15.4 drivers options"
config TI_CC2520_LEGACY
bool "TI CC2520 Driver support"
depends on NET_UIP
default n
config TI_CC2520
bool "TI CC2520 Driver support"
depends on NET_YAIP
@ -56,7 +51,7 @@ config TI_CC2520_RAW
The CC2520 driver with RAW channel allows to export radio interface
over USB making an USB 802.15.4 dongle.
if TI_CC2520_LEGACY || TI_CC2520 || TI_CC2520_RAW
if TI_CC2520 || TI_CC2520_RAW
config SYS_LOG_TI_CC2520_LEVEL
int
@ -121,36 +116,6 @@ config TI_CC2520_CHANNEL
All the 802.15.4 devices that want to connect to each other need
to have same channel. Default channel is 26.
config TI_CC2520_AUTO_CRC
bool "Let the chip handling CRC on reception"
default y
depends on TI_CC2520_LEGACY
help
When receiving a packet, the hardware can verify the CRC by itself
and will provide a flag letting know the success - or not - on
a flag on the footer.
config TI_CC2520_LINK_DETAILS
bool "Forward RSSI and link information on reception to upper stack"
default n
depends on TI_CC2520_LEGACY
select TI_CC2520_AUTO_CRC
help
If necessary, it will be possible to grab link and RSSI information
from the packet footer and forward them to the above stack.
config TI_CC2520_AUTO_ACK
bool "Let the chip handle TX/RX IEEE 802.15.4 ACK requests"
default n
depends on TI_CC2520_LEGACY
select TI_CC2520_AUTO_CRC
help
The chip is able to reply by itself to ACK requests as well as
waiting for an ACK when a TX packet is requesting an ACK. However,
this feature requires the chip to get hardware filtering on, and
thus the above stack needs to provide the right information for such
filtering feature to work.
config TI_CC2520_INIT_PRIO
int "CC2520 intialization priority"
default 80

View file

@ -1,9 +1,3 @@
subdir-ccflags-$(CONFIG_TI_CC2520_LEGACY) +=-I${srctree}/net/ip/contiki
subdir-ccflags-$(CONFIG_TI_CC2520_LEGACY) +=-I${srctree}/net/ip/contiki/os/lib
subdir-ccflags-$(CONFIG_TI_CC2520_LEGACY) +=-I${srctree}/net/ip/contiki/os
subdir-ccflags-$(CONFIG_TI_CC2520_LEGACY) +=-I${srctree}/net/ip
obj-$(CONFIG_TI_CC2520_LEGACY) += ieee802154_cc2520_legacy.o
obj-$(CONFIG_TI_CC2520) += ieee802154_cc2520.o
obj-$(CONFIG_TI_CC2520_RAW) += ieee802154_cc2520.o
obj-$(CONFIG_UPIPE_15_4) += ieee802154_uart_pipe.o

File diff suppressed because it is too large Load diff

View file

@ -1,402 +0,0 @@
/** @file
* @brief IP buffer API
*
* IP data is passed between application and IP stack via a ip_buf struct.
*/
/*
* Copyright (c) 2015 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Data buffer API - used for all data to/from net */
#ifndef __IP_BUF_H
#define __IP_BUF_H
#include <stdint.h>
#include <stdbool.h>
#include <net/net_core.h>
#include "contiki/ip/uipopt.h"
#include "contiki/ip/uip.h"
#include "contiki/packetbuf.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifdef CONFIG_NETWORKING_WITH_LOGGING
#undef DEBUG_IP_BUFS
#define DEBUG_IP_BUFS
#endif
#ifdef DEBUG_IP_BUFS
#define NET_BUF_CHECK_IF_IN_USE(buf) \
do { \
if (buf->ref) { \
NET_ERR("**ERROR** buf %p in use (%s:%s():%d)\n", \
buf, __FILE__, __func__, __LINE__); \
} \
} while (0)
#define NET_BUF_CHECK_IF_NOT_IN_USE(buf) \
do { \
if (!buf->ref) { \
NET_ERR("**ERROR** buf %p not in use (%s:%s():%d)\n",\
buf, __FILE__, __func__, __LINE__); \
} \
} while (0)
#else
#define NET_BUF_CHECK_IF_IN_USE(buf)
#define NET_BUF_CHECK_IF_NOT_IN_USE(buf)
#endif
struct net_context;
/** @cond ignore */
enum ip_buf_type {
IP_BUF_RX = 0,
IP_BUF_TX = 1,
};
/** @endcond */
/** The default MTU is 1280 (minimum IPv6 packet size) + LL header
* In Contiki terms this is UIP_LINK_MTU + UIP_LLH_LEN = UIP_BUFSIZE
*
* Contiki assumes that this value is UIP_BUFSIZE so do not change it
* without changing the value of UIP_BUFSIZE!
*/
#define IP_BUF_MAX_DATA UIP_BUFSIZE
struct ip_buf {
/** @cond ignore */
enum ip_buf_type type;
uint16_t reserve; /* length of the protocol headers */
/* @endcond */
/** Network connection context */
struct net_context *context;
/** @cond ignore */
/* uIP stack specific data */
uint16_t len; /* Contiki will set this to 0 if packet is discarded */
uint8_t uip_ext_len;
uint8_t uip_ext_bitmap;
uint8_t uip_ext_opt_offset;
uint8_t uip_flags;
uint16_t uip_slen;
uint16_t uip_appdatalen;
uint8_t *uip_next_hdr;
void *uip_appdata; /* application data */
void *uip_sappdata; /* app data to be sent */
void *uip_conn;
void *uip_udp_conn;
linkaddr_t dest;
linkaddr_t src;
#if defined(CONFIG_NETWORKING_WITH_TCP)
int8_t sent_status; /* tells if the TCP packet was sent ok or not */
uint8_t tcp_retry_count;
#endif
/* Neighbor discovery vars. Note that we are using void pointers here
* so that we do not need to include Contiki headers in this file.
*/
void *nd6_opt_prefix_info;
void *nd6_prefix;
void *nd6_nbr;
void *nd6_defrt;
void *nd6_ifaddr;
uint8_t *nd6_opt_llao;
uip_ipaddr_t ipaddr;
uint8_t nd6_opt_offset;
/* 6lowpan specific vars */
uint8_t compressed_hdr_len;
uint8_t uncompressed_hdr_len;
uint8_t first_frag_len;
uint8_t uncompressed;
/* @endcond */
};
/** @cond ignore */
/* Value returned by ip_buf_len() contains length of all the protocol headers,
* like IP and UDP, and the length of the user payload.
*/
#define ip_buf_len(buf) ((buf)->len)
/* Macros to access net_buf when inside Contiki stack */
#define uip_buf(buf) ((buf)->data)
#define uip_len(buf) (((struct ip_buf *)net_buf_user_data((buf)))->len)
#define uip_slen(buf) (((struct ip_buf *)net_buf_user_data((buf)))->uip_slen)
#define uip_ext_len(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_ext_len)
#define uip_ext_bitmap(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_ext_bitmap)
#define uip_ext_opt_offset(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_ext_opt_offset)
#define uip_nd6_opt_offset(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_offset)
#define uip_next_hdr(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_next_hdr)
#define uip_appdata(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_appdata)
#define uip_appdatalen(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_appdatalen)
#define uip_sappdata(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_sappdata)
#define uip_flags(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_flags)
#define uip_conn(buf) \
((struct uip_conn *) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_conn))
#define uip_set_conn(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_conn)
#define uip_udp_conn(buf) \
((struct uip_udp_conn *) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_udp_conn))
#define uip_set_udp_conn(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uip_udp_conn)
#define uip_nd6_opt_prefix_info(buf) \
((uip_nd6_opt_prefix_info *) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_prefix_info))
#define uip_set_nd6_opt_prefix_info(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_prefix_info)
#define uip_prefix(buf) \
((uip_ds6_prefix_t *) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_prefix))
#define uip_set_prefix(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_prefix)
#define uip_nbr(buf) \
((uip_ds6_nbr_t *) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_nbr))
#define uip_set_nbr(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_nbr)
#define uip_defrt(buf) \
((uip_ds6_defrt_t *) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_defrt))
#define uip_set_defrt(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_defrt)
#define uip_addr(buf) \
((uip_ds6_addr_t *) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_ifaddr))
#define uip_set_addr(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_ifaddr)
#define uip_nd6_opt_llao(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_llao)
#define uip_set_nd6_opt_llao(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->nd6_opt_llao)
#define uip_nd6_ipaddr(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->ipaddr)
#define uip_compressed_hdr_len(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->compressed_hdr_len)
#define uip_uncompressed_hdr_len(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uncompressed_hdr_len)
#define uip_first_frag_len(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->first_frag_len)
#define uip_uncompressed(buf) \
(((struct ip_buf *)net_buf_user_data((buf)))->uncompressed)
/* These two return only the application data and length without
* IP and UDP header length.
*/
#define ip_buf_appdata(buf) uip_appdata(buf)
#define ip_buf_appdatalen(buf) uip_appdatalen(buf)
#define ip_buf_reserve(buf) (((struct ip_buf *) \
net_buf_user_data((buf)))->reserve)
#define ip_buf_ll_src(buf) (((struct ip_buf *)net_buf_user_data((buf)))->src)
#define ip_buf_ll_dest(buf) (((struct ip_buf *)net_buf_user_data((buf)))->dest)
#define ip_buf_context(buf) (((struct ip_buf *)net_buf_user_data((buf)))->context)
#define ip_buf_type(ptr) (((struct ip_buf *)net_buf_user_data((ptr)))->type)
#define ip_buf_sent_status(ptr) (((struct ip_buf *)net_buf_user_data((ptr)))->sent_status)
#define ip_buf_tcp_retry_count(ptr) (((struct ip_buf *)net_buf_user_data((ptr)))->tcp_retry_count)
/* @endcond */
/** NET_BUF_IP
*
* @brief This macro returns IP header information struct stored in net_buf.
*
* @details The macro returns pointer to uip_ip_hdr struct which
* contains IP header information.
*
* @param buf Network buffer.
*
* @return Pointer to uip_ip_hdr.
*/
#define NET_BUF_IP(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
/** NET_BUF_UDP
*
* @brief This macro returns UDP header information struct stored in net_buf.
*
* @details The macro returns pointer to uip_udp_hdr struct which
* contains UDP header information.
*
* @param buf Network buffer.
*
* @return Pointer to uip_ip_hdr.
*/
#define NET_BUF_UDP(buf) ((struct uip_udp_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN])
/**
* @brief Get buffer from the available buffers pool.
*
* @details Get network buffer from buffer pool. You must have
* network context before able to use this function.
*
* @param context Network context that will be related to
* this buffer.
*
* @return Network buffer if successful, NULL otherwise.
*/
/* Get buffer from the available buffers pool */
#ifdef DEBUG_IP_BUFS
#define ip_buf_get_rx(context) ip_buf_get_rx_debug(context, __func__, __LINE__)
#define ip_buf_get_tx(context) ip_buf_get_tx_debug(context, __func__, __LINE__)
struct net_buf *ip_buf_get_rx_debug(struct net_context *context,
const char *caller, int line);
struct net_buf *ip_buf_get_tx_debug(struct net_context *context,
const char *caller, int line);
#else
struct net_buf *ip_buf_get_rx(struct net_context *context);
struct net_buf *ip_buf_get_tx(struct net_context *context);
#endif
/**
* @brief Get buffer from pool but also reserve headroom for
* potential headers.
*
* @details Normally this version is not useful for applications
* but is mainly used by network fragmentation code.
*
* @param reserve_head How many bytes to reserve for headroom.
*
* @return Network buffer if successful, NULL otherwise.
*/
/* Same as net_buf_get, but also reserve headroom for potential headers */
#ifdef DEBUG_IP_BUFS
#define ip_buf_get_reserve_rx(res) ip_buf_get_reserve_rx_debug(res, \
__func__, \
__LINE__)
#define ip_buf_get_reserve_tx(res) ip_buf_get_reserve_tx_debug(res, \
__func__, \
__LINE__)
struct net_buf *ip_buf_get_reserve_rx_debug(uint16_t reserve_head,
const char *caller, int line);
struct net_buf *ip_buf_get_reserve_tx_debug(uint16_t reserve_head,
const char *caller, int line);
#else
struct net_buf *ip_buf_get_reserve_rx(uint16_t reserve_head);
struct net_buf *ip_buf_get_reserve_tx(uint16_t reserve_head);
#endif
/**
* @brief Place buffer back into the available buffers pool.
*
* @details Releases the buffer to other use. This needs to be
* called by application after it has finished with
* the buffer.
*
* @param buf Network buffer to release.
*
*/
#ifdef DEBUG_IP_BUFS
#define ip_buf_unref(buf) ip_buf_unref_debug(buf, __func__, __LINE__)
void ip_buf_unref_debug(struct net_buf *buf, const char *caller, int line);
#else
void ip_buf_unref(struct net_buf *buf);
#endif
/**
* @brief Increase the ref count
*
* @details Mark the buffer to be used still.
*
* @param buf Network buffer to ref.
*
* @return Network buffer if successful, NULL otherwise.
*/
#ifdef DEBUG_IP_BUFS
#define ip_buf_ref(buf) ip_buf_ref_debug(buf, __func__, __LINE__)
struct net_buf *ip_buf_ref_debug(struct net_buf *buf, const char *caller, int line);
#else
struct net_buf *ip_buf_ref(struct net_buf *buf);
#endif
/** @cond ignore */
void ip_buf_init(void);
/* @endcond */
/** @cond ignore */
#if defined(CONFIG_INIT_STACKS) && defined(CONFIG_PRINTK)
#include <offsets.h>
#include <misc/printk.h>
static inline void net_analyze_stack(const char *name,
unsigned char *stack,
size_t size)
{
unsigned i, stack_offset, pcnt, unused = 0;
/* The TCS is always placed on a 4-byte aligned boundary - if
* the stack beginning doesn't match that there will be some
* unused bytes in the beginning.
*/
stack_offset = K_THREAD_SIZEOF + ((4 - ((unsigned)stack % 4)) % 4);
/* TODO
* Currently all supported platforms have stack growth down and there is no
* Kconfig option to configure it so this always build "else" branch.
* When support for platform with stack direction up (or configurable direction)
* is added this check should be confirmed that correct Kconfig option is used.
*/
#if defined(CONFIG_STACK_GROWS_UP)
for (i = size - 1; i >= stack_offset; i--) {
if ((unsigned char)stack[i] == 0xaa) {
unused++;
} else {
break;
}
}
#else
for (i = stack_offset; i < size; i++) {
if ((unsigned char)stack[i] == 0xaa) {
unused++;
} else {
break;
}
}
#endif
/* Calculate the real size reserved for the stack */
size -= stack_offset;
pcnt = ((size - unused) * 100) / size;
printk("net (%p): %s stack real size %zu "
"unused %u usage %zu/%zu (%u %%)\n",
sys_thread_self_get(), name, size + stack_offset,
unused, size - unused, size, pcnt);
}
#else
#define net_analyze_stack(...)
#endif
/* @endcond */
#ifdef __cplusplus
}
#endif
#endif /* __IP_BUF_H */

View file

@ -1,166 +0,0 @@
/** @file
* @brief L2 buffer API
*
* L2 (layer 2 or MAC layer) data is passed between application and
* IP stack via a l2_buf struct. Currently L2 buffers are only used
* in IEEE 802.15.4 code.
*/
/*
* Copyright (c) 2015 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Data buffer API - used for all data to/from net */
#ifndef __L2_BUF_H
#define __L2_BUF_H
#include <stdint.h>
#include <net/ip_buf.h>
#include "contiki/ip/uipopt.h"
#include "contiki/ip/uip.h"
#include "contiki/packetbuf.h"
#include "contiki/os/lib/list.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(CONFIG_L2_BUFFERS)
#ifdef CONFIG_NETWORKING_WITH_LOGGING
#undef DEBUG_L2_BUFS
#define DEBUG_L2_BUFS
#endif
/** @cond ignore */
void l2_buf_init(void);
/* @endcond */
/** For the MAC/L2 layer (after the IPv6 packet is fragmented to smaller
* chunks), we can use much smaller buffers (depending on used radio
* technology). For 802.15.4 we use the 128 bytes long buffers.
*/
#ifndef NET_L2_BUF_MAX_SIZE
#define NET_L2_BUF_MAX_SIZE (PACKETBUF_SIZE + PACKETBUF_HDR_SIZE)
#endif
struct l2_buf {
/** @cond ignore */
/* 6LoWPAN pointers */
uint8_t *packetbuf_ptr;
uint8_t packetbuf_hdr_len;
uint8_t packetbuf_payload_len;
uint8_t uncomp_hdr_len;
int last_tx_status;
#if defined(CONFIG_NETWORKING_WITH_15_4)
LIST_STRUCT(neighbor_list);
#endif
struct packetbuf_attr pkt_packetbuf_attrs[PACKETBUF_NUM_ATTRS];
struct packetbuf_addr pkt_packetbuf_addrs[PACKETBUF_NUM_ADDRS];
uint16_t pkt_buflen, pkt_bufptr;
uint8_t pkt_hdrptr;
uint8_t *pkt_packetbufptr;
/* @endcond */
};
/** @cond ignore */
#define uip_packetbuf_ptr(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->packetbuf_ptr)
#define uip_packetbuf_hdr_len(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->packetbuf_hdr_len)
#define uip_packetbuf_payload_len(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->packetbuf_payload_len)
#define uip_uncomp_hdr_len(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->uncomp_hdr_len)
#define uip_last_tx_status(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->last_tx_status)
#if defined(CONFIG_NETWORKING_WITH_15_4)
#define uip_neighbor_list(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->neighbor_list)
#endif
#define uip_pkt_buflen(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_buflen)
#define uip_pkt_bufptr(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_bufptr)
#define uip_pkt_hdrptr(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_hdrptr)
#define uip_pkt_packetbufptr(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_packetbufptr)
#define uip_pkt_packetbuf_attrs(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_packetbuf_attrs)
#define uip_pkt_packetbuf_addrs(buf) \
(((struct l2_buf *)net_buf_user_data((buf)))->pkt_packetbuf_addrs)
/* Note that we do not reserve extra space for the header when the packetbuf
* is converted to use net_buf, so the packet starts directly from the
* data pointer. This is done in order to simplify the 802.15.4 packet
* handling. So the L2 buffer should only be allocated by calling
* reserve function like this: l2_buf_get_reserve(0);
*/
#define uip_pkt_packetbuf(ptr) ((ptr)->data)
/* @endcond */
/**
* @brief Get buffer from the available buffers pool
* and also reserve headroom for potential headers.
*
* @details Normally this version is not useful for applications
* but is mainly used by network fragmentation code.
*
* @param reserve How many bytes to reserve for headroom.
*
* @return Network buffer if successful, NULL otherwise.
*/
#ifdef DEBUG_L2_BUFS
#define l2_buf_get_reserve(res) l2_buf_get_reserve_debug(res, \
__func__, __LINE__)
struct net_buf *l2_buf_get_reserve_debug(uint16_t reserve_head,
const char *caller, int line);
#else
struct net_buf *l2_buf_get_reserve(uint16_t reserve_head);
#endif
/**
* @brief Place buffer back into the available buffers pool.
*
* @details Releases the buffer to other use. This needs to be
* called by application after it has finished with
* the buffer.
*
* @param buf Network buffer to release.
*
*/
#ifdef DEBUG_L2_BUFS
#define l2_buf_unref(buf) l2_buf_unref_debug(buf, __func__, __LINE__)
void l2_buf_unref_debug(struct net_buf *buf, const char *caller, int line);
#else
void l2_buf_unref(struct net_buf *buf);
#endif
#else /* defined(CONFIG_L2_BUFFERS) */
#define l2_buf_init(...)
#endif /* defined(CONFIG_L2_BUFFERS) */
#ifdef __cplusplus
}
#endif
#endif /* __L2_BUF_H */

View file

@ -16,7 +16,4 @@
#if defined(CONFIG_NET_YAIP)
#include <net/yaip/net_context.h>
#else
/* For legacy stack the context API stuff is in net_socket.h */
#include <net/uip/net_socket.h>
#endif

View file

@ -16,6 +16,4 @@
#if defined(CONFIG_NET_YAIP)
#include <net/yaip/net_core.h>
#else
#include <net/uip/net_core.h>
#endif

View file

@ -14,8 +14,4 @@
* limitations under the License.
*/
#if defined(CONFIG_NET_YAIP)
#include <net/yaip/net_ip.h>
#else
#include <net/uip/net_ip.h>
#endif

View file

@ -1,21 +0,0 @@
/*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined(CONFIG_NET_YAIP)
#include <net/yaip/net_socket.h>
#else
#include <net/uip/net_socket.h>
#endif

View file

@ -1,164 +0,0 @@
/** @file
* @brief Network core definitions
*
* Definitions for networking support.
*/
/*
* Copyright (c) 2015 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __NET_CORE_H
#define __NET_CORE_H
#ifdef __cplusplus
extern "C" {
#endif
/* Network subsystem logging helpers */
#ifdef CONFIG_NETWORKING_WITH_LOGGING
#define NET_DBG(fmt, ...) printk("net: %s (%p): " fmt, __func__, \
sys_thread_self_get(), ##__VA_ARGS__)
#define NET_ERR(fmt, ...) printk("net: %s: " fmt, __func__, ##__VA_ARGS__)
#define NET_INFO(fmt, ...) printk("net: " fmt, ##__VA_ARGS__)
#define NET_PRINT(fmt, ...) printk(fmt, ##__VA_ARGS__)
#else
#define NET_DBG(...)
#define NET_ERR(...)
#define NET_INFO(...)
#define NET_PRINT(...)
#endif /* CONFIG_NETWORKING_WITH_LOGGING */
enum net_tcp_type {
NET_TCP_TYPE_UNKNOWN = 0,
NET_TCP_TYPE_SERVER,
NET_TCP_TYPE_CLIENT,
};
struct net_buf;
struct net_context;
#include <misc/printk.h>
#include <string.h>
#include <net/net_socket.h>
/**
* @brief Initialize network stack. This is will be automatically called
* by the OS.
*
* @details No harm will happen if application calls this multiple times.
*
* @return 0 if ok, < 0 in case of error.
*/
int net_init(void);
struct net_driver {
/** How much headroom is needed for net transport headers */
size_t head_reserve;
/** Open the net transport */
int (*open)(void);
/** Send data to net. The send() function should return:
* 0 : If packet could not be sent. In this case buf should
* not be released.
* 1 : If the packet was sent successfully. In this case the buf
* should be released by either the send() or some other
* lower layer function.
* <0: If there is an error, the buf should not be released by
* send() function.
*/
int (*send)(struct net_buf *buf);
};
/**
* @brief Register a new network driver to the network stack.
*
* @details Only one network device can be registered at a time.
*
* @param drv Network driver.
*
* @return 0 if ok, < 0 in case of error.
*/
int net_register_driver(struct net_driver *drv);
/**
* @brief Unregister a previously registered network driver.
*
* @param drv Network driver.
*
* @details Networking will be disabled if there is no driver
* available.
*
*/
void net_unregister_driver(struct net_driver *drv);
/**
* @brief Set the MAC/EUI-64 address of the device.
*
* @details Network device driver should call this function to
* tell the used MAC or EUI-64 address to the IP stack.
*
* @param mac MAC or EUI-64 address
* @param len If len == 6, then the first parameter is interpreted
* to be the MAC address and the function sets the U/L bits etc.
* If the len == 8, then the value is used as is to generate the
* link local IPv6 address.
*
* @return 0 if ok, < 0 in case of error.
*/
int net_set_mac(uint8_t *mac, uint8_t len);
/**
* @brief Send a reply packet to the message originator.
*
* @details Application can call this function if it has received
* a network packet from peer. The application needs to write
* reply data into net_buf. The app can use ip_buf_appdata(buf) and
* ip_buf_appdatalen(buf) to set the application data and length.
* This function will yield in thread and fiber contexts.
*
* @param context Network context
* @param buf Network buffer containing the network data.
*
* @return 0 if ok, < 0 in case of error.
*/
int net_reply(struct net_context *context, struct net_buf *buf);
/* Called by driver when an IP packet has been received */
int net_recv(struct net_buf *buf);
void net_context_init(void);
/**
* @brief Get current status of the TCP connection.
*
* @details Application can call this to get the current status
* of TCP connection. The returned value maps to errno values.
* Value 0 means ok. For UDP context 0 is always returned.
*
* @param context Network context
*
* @return 0 if ok, < 0 connection status
*/
int net_context_get_connection_status(struct net_context *context);
#ifdef __cplusplus
}
#endif
#endif /* __NET_CORE_H */

View file

@ -1,119 +0,0 @@
/** @file
* @brief IPv6 and IPv4 definitions
*
* Generic IPv6 and IPv4 address definitions.
*/
/*
* Copyright (c) 2015 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __NET_IP_H
#define __NET_IP_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Protocol families */
#define PF_UNSPEC 0 /* Unspecified. */
#define PF_INET 2 /* IP protocol family. */
#define PF_INET6 10 /* IP version 6. */
/** Address families. */
#define AF_UNSPEC PF_UNSPEC
#define AF_INET PF_INET
#define AF_INET6 PF_INET6
/** Protocol numbers from IANA */
enum ip_protocol {
IPPROTO_TCP = 6,
IPPROTO_UDP = 17,
IPPROTO_ICMPV6 = 58,
};
/** IPv6 address structure */
struct in6_addr {
union {
uint8_t u6_addr8[16];
uint16_t u6_addr16[8]; /* In big endian */
uint32_t u6_addr32[4]; /* In big endian */
} in6_u;
#define s6_addr in6_u.u6_addr8
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
};
/** IPv4 address */
struct in_addr {
union {
uint8_t u4_addr8[4];
uint16_t u4_addr16[2]; /* In big endian */
uint32_t u4_addr32[1]; /* In big endian */
} in4_u;
#define s4_addr in4_u.u4_addr8
#define s4_addr16 in4_u.u4_addr16
#define s4_addr32 in4_u.u4_addr32
#define s_addr s4_addr32
};
typedef unsigned short int sa_family_t;
struct net_addr {
sa_family_t family;
union {
struct in6_addr in6_addr;
struct in_addr in_addr;
};
};
#define IN6ADDR_ANY_INIT { { { 0, 0, 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0 } } }
#define IN6ADDR_LOOPBACK_INIT { { { 0, 0, 0, 0, 0, 0, 0, \
0, 0, 0, 0, 0, 0, 0, 0, 1 } } }
#define INET6_ADDRSTRLEN 46
#define INADDR_ANY 0
/** IPv6/IPv4 network connection tuple */
struct net_tuple {
/** IPv6/IPv4 remote address */
struct net_addr *remote_addr;
/** IPv6/IPv4 local address */
struct net_addr *local_addr;
/** UDP/TCP remote port */
uint16_t remote_port;
/** UDP/TCP local port */
uint16_t local_port;
/** IP protocol */
enum ip_protocol ip_proto;
};
#if defined(CONFIG_NETWORKING_WITH_TCP)
enum tcp_event_type {
TCP_READ_EVENT = 1,
TCP_WRITE_EVENT,
};
#endif
#ifdef __cplusplus
}
#endif
#endif /* __NET_IP_H */

View file

@ -1,137 +0,0 @@
/** @file
* @brief Simple socket API
*
* Simple socket API for applications to connection establishment and
* disconnection.
*/
/*
* Copyright (c) 2015 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __NET_SOCKET_H
#define __NET_SOCKET_H
#include <stdint.h>
#include <net/net_ip.h>
#include <net/buf.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Get network context.
*
* @details Network context is used to define the connection
* 5-tuple (protocol, remote address, remote port, source
* address and source port).
*
* @param ip_proto Protocol to use. Currently only UDP is supported.
* @param remote_addr Remote IPv6/IPv4 address.
* @param remote_port Remote UDP/TCP port.
* @param local_addr Local IPv6/IPv4 address. If the local address is
* set to be anyaddr (all zeros), the IP stack will use the link
* local address defined for the system.
* @param local_port Local UDP/TCP port. If the local port is 0,
* then a random port will be allocated.
*
* @return Network context if successful, NULL otherwise.
*/
struct net_context *net_context_get(enum ip_protocol ip_proto,
const struct net_addr *remote_addr,
uint16_t remote_port,
struct net_addr *local_addr,
uint16_t local_port);
/**
* @brief Get network tuple.
*
* @details This function returns the used connection tuple.
*
* @param context Network context.
*
* @return Network tuple if successful, NULL otherwise.
*/
struct net_tuple *net_context_get_tuple(struct net_context *context);
/**
* @brief Release network context.
*
* @details Free the resources allocated for the context.
* All network listeners tied to this context are removed.
*
* @param context Network context.
*
*/
void net_context_put(struct net_context *context);
/**
* @brief Send data to network.
*
* @details Send user specified data to network. This
* requires that net_buf is tied to context. This means
* that the net_buf was allocated using net_buf_get().
* This function will yield in thread and fiber contexts.
*
* @param buf Network buffer.
*
* @return 0 if ok (do not unref the buf),
* <0 if error (unref the buf).
*/
int net_send(struct net_buf *buf);
/**
* @brief Receive data from network.
*
* @details Application uses this to get data from network
* connection. Caller can specify a timeout, if there is no
* data to return after a timeout, a NULL will be returned.
* Caller is responsible to release the returned net_buf.
*
* @param context Network context.
* @param timeout Timeout to wait. The value is in ticks.
* If TICKS_UNLIMITED (-1), wait forever.
* If TICKS_NONE (0), do not wait.
* If > 0, wait amount of ticks.
* The timeout is only available if kernel is compiled
* with CONFIG_NANO_TIMEOUTS. If CONFIG_NANO_TIMEOUT is not
* defined, then value > 0 means not to wait.
*
* @return Network buffer if successful, NULL otherwise.
*/
struct net_buf *net_receive(struct net_context *context,
int32_t timeout);
/**
* @brief Get the UDP connection pointer from net_context.
*
* @details This is only needed in special occacions when
* there is an existing UDP connection that application
* wants to attach to. Normally the connection information
* is not needed by application.
*
* @return UDP connection if it exists, NULL otherwise.
*/
struct simple_udp_connection *
net_context_get_udp_connection(struct net_context *context);
void *net_context_get_internal_connection(struct net_context *context);
#ifdef __cplusplus
}
#endif
#endif /* __NET_SOCKET_H */

View file

@ -50,31 +50,17 @@ config NETWORKING
select NANO_TIMEOUTS
select NANO_TIMERS
select NET_BUF
select NET_YAIP
select TEST_RANDOM_GENERATOR
default n
help
This option enabled generic link layer and IP networking support.
if NETWORKING
choice
prompt "IP stack"
default NET_UIP
help
Select what IP stack to use. The legacy stack is
Contiki based uIP stack.
config NET_UIP
bool "uIP"
help
Choose this if unsure.
config NET_YAIP
bool "New IP stack [EXPERIMENTAL]"
help
New IP stack.
endchoice
source "net/ip/Kconfig"
bool
default y
source "net/yaip/Kconfig"

View file

@ -5,6 +5,4 @@ obj-y += yaip/nbuf.o
else
obj-y += yaip/
endif
else
obj-$(CONFIG_NETWORKING) += ip/
endif

View file

@ -1,582 +0,0 @@
# networking.kconf - Generic networking configuration options
#
# Copyright (c) 2015 Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#
# UIP options
#
menu "uIP stack"
depends on NET_UIP
config IP_BUF_RX_SIZE
int "Number of IP net buffers to use when receiving data"
default 1
help
Each network buffer will contain one received IPv6 or IPv4 packet.
Each buffer will occupy 1280 bytes of memory.
config IP_BUF_TX_SIZE
int "Number of IP net buffers to use when sending data"
default 2
help
Each network buffer will contain one sent IPv6 or IPv4 packet.
Each buffer will occupy 1280 bytes of memory.
config IP_RX_STACK_SIZE
int "RX fiber stack size"
default 1024
help
Set the RX fiber stack size in bytes. The RX fiber is waiting
network packets from lower level bearers. It will then run the
packet through IP stack which validates the packet and passes
it eventually to application.
config IP_TX_STACK_SIZE
int "TX fiber stack size"
default 1024
help
Set the TX fiber stack size in bytes. The TX fiber is waiting
data from application. It will then validate the data and push
it to network driver to be sent out.
config IP_TIMER_STACK_SIZE
int "Timer fiber stack size"
default 1536
help
Set the timer fiber stack size in bytes. The timer fiber is
responsible for handling re-transmissions and periodic network
packet sending like IPv6 router solicitations.
config NET_MAX_CONTEXTS
int "How many network context to use"
default 2
help
The network context is similar concept as network socket.
It defines a network endpoint and number of context depends
on application usage.
config UDP_MAX_CONNECTIONS
int "How many UDP connections can be used"
default 2
help
Amount of concurrent UDP connections.
choice
prompt "Internet Protocol version"
depends on NETWORKING
help
The IP stack can either support IPv6 or IPv4 but
not both at the same time. The IPv6 support should
be selected by default as there is limited set of
network bearers provided that support IPv4.
default NETWORKING_WITH_IPV6
config NETWORKING_WITH_IPV6
bool "IPv6"
help
Choose this if unsure.
config NETWORKING_WITH_IPV4
bool "IPv4"
help
Legacy IP.
endchoice
config NETWORKING_STATISTICS
bool
prompt "Enable IP statistics gathering"
depends on NETWORKING
default n
help
This is only for debugging the network. Do not activate
this in live system! The option uses memory and slows
down IP packet processing.
config NETWORKING_IPV6_NO_ND
bool
prompt "Disable IPv6 neighbor discovery"
depends on NETWORKING
depends on NETWORKING_WITH_IPV6
default n
help
Normally ND should be enabled but in order to simplify
the network setup it can be turned off if using
slip and tun device.
config NETWORKING_MAX_NEIGHBORS
int "Max number of neighbors"
depends on NETWORKING
depends on NETWORKING_WITH_IPV6
default 4
help
Specifies the maximum number of neighbors that each node will
be able to handle.
config NETWORKING_WITH_TCP
bool
prompt "Enable TCP protocol"
depends on NETWORKING
default n
help
Enable Transmission and Control Protocol (TCP) support.
config TCP_MAX_CONNECTIONS
int "Maximum number of connections"
depends on NETWORKING_WITH_TCP
default 2
help
Tweak the TCP maximum segment size. Normally one should
not change this but let the IP stack to calculate a best
size for it.
config TCP_DISABLE_ACTIVE_OPEN
bool
prompt "Disallow host to initiate connection attempt"
depends on NETWORKING_WITH_TCP
default n
help
By default application is allowed to initiate a TCP
connection attempt. If the application is only acting
as a server, then some memory can be saved by disabling
the client role.
config TCP_MSS
int
prompt "TCP maximum segment size"
depends on NETWORKING_WITH_TCP
default 0
help
Tweak the TCP maximum segment size. Normally one should
not change this but let the IP stack to calculate a best
size for it.
config TCP_RECEIVE_WINDOW
int
prompt "TCP receive window size"
depends on NETWORKING_WITH_TCP
default 0
help
Tweak the TCP receive window size. Normally one should
not change this but let the IP stack to calculate a best
size for it.
config NETWORKING_WITH_RPL
bool
prompt "Enable RPL (ripple) IPv6 mesh routing protocol"
depends on NETWORKING && NETWORKING_WITH_IPV6
default n
help
Enable RPL (RFC 6550) IPv6 Routing Protocol for
Low-Power and Lossy Networks.
config RPL_STATS
bool
prompt "Enable RPL statistics"
depends on NETWORKING_WITH_RPL
select NETWORKING_STATISTICS
default n
help
Enable RPL statistics support.
config RPL_PROBING
bool
prompt "Enable RPL probing"
depends on NETWORKING_WITH_RPL
default n
help
Enable RPL probing support. When enabled, probes will be sent
periodically to keep parent link estimates up to date.
choice
prompt "Objective function"
depends on NETWORKING_WITH_RPL
help
The objective function to use. All RPL nodes in a DODAG
must use the same OF.
The default is MRHOF, see RFC 6719 for details.
Other alternative is OF0, see RFC 6552 for details.
default RPL_WITH_MRHOF
config RPL_WITH_MRHOF
bool "Minimum Rank with Hysteresis, RFC 6719"
help
Choose this (MRHOF) if unsure.
config RPL_WITH_OF0
bool "OF Zero, RFC 6552"
help
Objective function zero (OF0).
endchoice
config NETWORKING_WITH_TRICKLE
bool "Enable Trickle algorithm"
depends on NETWORKING
default n
help
Enable Trickle algorithm (RFC 6206) support. This only
includes Trickle library but IP stack does not call its
functions.
config NETWORKING_WITH_LOOPBACK
bool
prompt "Enable loopback driver"
depends on NETWORKING
default n
help
Enable a simple loopback driver that installs
IPv6 loopback addresses into routing table and
neighbor cache. All packets transmitted are
looped back to the receiving fifo/fiber.
config NETWORK_LOOPBACK_TEST_COUNT
int "How many packets the loopback test passes"
depends on NETWORKING_WITH_LOOPBACK
default 0
help
If set to 0, then the loopback test runs forever.
choice
prompt "Wired networking support"
depends on NETWORKING
default NETWORKING_NO_WIRED
config NETWORKING_NO_WIRED
bool "No wired network driver"
help
Do not enable any wired network driver. It is still
possible to select other types of network drivers if
this option is selected.
config NETWORKING_UART
bool "Network UART/slip driver"
select UART_PIPE
help
Enable UART driver for passing IPv6 packets using slip.
config ETHERNET
bool "Ethernet drivers"
help
Include Ethernet drivers in system config. This
option enables Ethernet support in the core network
subsystem, but it is necessary to also select a
specific Ethernet device driver.
endchoice
config NETWORKING_DEBUG_UART
bool
prompt "Network UART driver debug"
depends on NETWORKING_UART && NETWORKING_WITH_LOGGING
default n
help
This option enables debug support for network UART
driver.
config ETHERNET_DEBUG
bool
prompt "Network Ethernet driver debug"
depends on NETWORKING_WITH_LOGGING && ETHERNET
default n
help
This option enables debug support for Ethernet drivers.
config L2_BUFFERS
bool
default n
config NETWORKING_WITH_15_4
bool
prompt "Enable 802.15.4 driver"
depends on NETWORKING && NETWORKING_WITH_IPV6
select L2_BUFFERS
default n
help
Enable 802.15.4 driver that receives the IPv6 packet,
does header compression on it and writes it to the
802.15.4 stack Tx FIFO. The 802.15.4 Tx fiber will pick up
the header compressed IPv6 6lowpan packet and fragment
it into suitable chunks ready to be sent to the 802.15.4
hw driver
config NETWORKING_WITH_15_4_ALWAYS_ACK
bool
prompt "Always request 802.15.4 packet acknowledgment"
depends on NETWORKING_WITH_15_4
default n
help
This is meant to be used for testing only. Requesting an
acknowledgment on all data packet will draw power resource.
Use case for this option it for testing only.
# Using nullmac 802.15.4 driver only.
config NETWORKING_WITH_15_4_MAC_NULL
bool
default n
choice
prompt "802.15.4 RDC Driver"
depends on NETWORKING && NETWORKING_WITH_15_4
help
The 802.15.4 RDC (Radio Duty Cycle) layer can use either
sicslowmac or simplerdc.
config NETWORKING_WITH_15_4_RDC_SIMPLE
bool
prompt "simplerdc driver"
help
Enable simplerdc driver.
config NETWORKING_WITH_15_4_RDC_SICSLOWMAC
bool
prompt "sicslowmac driver"
help
Enable sicslowmac driver.
endchoice
config 15_4_RX_STACK_SIZE
int "Stack size of 802.15.4 RX fiber"
depends on NETWORKING_WITH_15_4
default 1024
help
Set the 802.15.4 RX fiber stack size in bytes. The RX fiber
is waiting network packets from 802.15.4 device driver.
It will then run the packet through 6LoWPAN stack which
uncompresses and de-fragments the packet and passes those to
upper layers.
config 15_4_TX_STACK_SIZE
int "Stack size of 802.15.4 TX fiber"
depends on NETWORKING_WITH_15_4
default 4096
help
Set the 802.15.4 TX fiber stack size in bytes. The TX fiber
is waiting network packets from IP stack. It then feeds those
to 6LoWPAN stack which compresses and fragments packets before
passing the fragments to 802.15.4 device driver. Note that
this stack needs to be bigger that TX stack because stack is
used to store the fragmented 802.15.4 packets.
config 15_4_BEACON_SUPPORT
bool
prompt "Enable 802.15.4 beacon support"
depends on NETWORKING_WITH_15_4
default n
help
Enable 802.15.4 beacon support
config 15_4_BEACON_STATS
bool
prompt "Enable 802.15.4 beacon statistics"
depends on NETWORKING_WITH_15_4
depends on 15_4_BEACON_SUPPORT
select NETWORKING_STATISTICS
default n
help
Enable 802.15.4 beacon statistics support.
config NETWORKING_WITH_15_4_PAN_ID
hex
prompt "IEEE 802.15.4 PAN id/address"
depends on NETWORKING_WITH_15_4
default 0xabcd
help
All the 802.15.4 devices that want to connect to each
other need to have same PAN id (address).
Default PAN id is 0xABCD
choice
prompt "802.15.4 Radio Driver"
depends on NETWORKING && NETWORKING_WITH_15_4
default n
help
The 802.15.4 layer can either support loopback within
or loopback with uart but not both at the same time.
config NETWORKING_WITH_15_4_TI_CC2520
bool
prompt "TI CC2520"
select TEST_RANDOM_GENERATOR
select TI_CC2520_LEGACY
help
Enable Texas Instruments CC2520 802.15.4 radio driver.
config NETWORKING_WITH_15_4_LOOPBACK
bool
prompt "Loopback"
help
Enable 802.15.4 loopback radio driver that receives
the 802.15.4 frame and put it back 802.15.4 Rx Fifo.
config NETWORKING_WITH_15_4_LOOPBACK_UART
bool
prompt "Loopback with UART"
select UART_PIPE
help
Enable 802.15.4 loopback radio driver that sends
802.15.4 frames out of qemu through uart and receive
frames through uart. This way one can test 802.15.4 frames
between two qemus
endchoice
config NETWORKING_WITH_BT
bool
prompt "Enable Bluetooth driver"
depends on NETWORKING && NETWORKING_WITH_IPV6
select L2_BUFFERS
select NETWORKING_IPV6_NO_ND
select NETWORKING_WITH_6LOWPAN
select 6LOWPAN_COMPRESSION_IPHC
select BLUETOOTH
select BLUETOOTH_PERIPHERAL
select BLUETOOTH_L2CAP_DYNAMIC_CHANNEL
select BLUETOOTH_SMP
default n
help
Enable Bluetooth driver that send and receives IPv6 packets,
does header compression on it and writes it to the
Bluetooth stack via L2CAP channel.
config NETWORKING_WITH_6LOWPAN
bool
prompt "Enable 6LoWPAN (IPv6 compression) in the uIP stack"
depends on NETWORKING
depends on NETWORKING_WITH_15_4 || NETWORKING_WITH_BT
default n
help
Enable 6LoWPAN in uIP stack. Currently this requires 802.15.4
stack to be enabled.
choice
prompt "6LoWPAN compression method"
depends on NETWORKING_WITH_6LOWPAN
help
Select the compression method that is used in 6LoWPAN.
default 6LOWPAN_COMPRESSION_IPV6
config 6LOWPAN_COMPRESSION_IPV6
bool "No compression"
help
Choose this if unsure.
config 6LOWPAN_COMPRESSION_IPHC
bool "IP header compression"
help
IP header compression
endchoice
config TINYDTLS
bool
prompt "Enable tinyDTLS support."
depends on NETWORKING
default n
help
Enable tinyDTLS support so that applications can use it.
This is needed at least in CoAP.
config TINYDTLS_DEBUG
bool
prompt "Enable tinyDTLS debugging support."
depends on TINYDTLS
default n
help
Enable tinyDTLS debugging support.
config ER_COAP
bool
prompt "Enable Erbium CoAP engine support."
depends on NETWORKING
default n
help
Enable Erbium CoAP engine support so that applications can use it.
config ER_COAP_WITH_DTLS
bool
prompt "Use DTLS in CoAP"
depends on ER_COAP
select TINYDTLS
default n
help
Make CoAP engine use DTLS. Note that if you activate DTLS, you
are not able to send or receive non-DTLS CoAP messages, and
vice versa.
config ER_COAP_LINK_FORMAT_FILTERING
bool "Enable link format filtering"
select MINIMAL_LIBC_EXTENDED
default n
help
Make CoAP engine support link format filters.
config COAP_STATS
bool
prompt "Enable CoAP statistics"
depends on ER_COAP
select NETWORKING_STATISTICS
default n
help
Enable CoAP statistics support.
config ER_COAP_CLIENT
bool
prompt "Enable CoAP client support"
depends on ER_COAP
default n
help
Compile in client CoAP support.
config DHCP
bool
prompt "Enable DHCP support."
depends on NETWORKING && NETWORKING_WITH_IPV4
default n
help
Enable DHCP support so that applications can use it.
choice
prompt "DHCP message type"
depends on DHCP
help
Select the DHCP message type broadcast or unicast.
default DHCP_BROADCAST
config DHCP_BROADCAST
bool "Broadcast message"
help
Choose this if unsure.
config DHCP_UNICAST
bool "Unicast message"
help
DHCP message type
endchoice
config NET_SANITY_TEST
bool
prompt "Enable networking sanity test"
depends on NETWORKING
default n
help
Enable networking sanity tests. Network sanity test
verification and test report submission will fall under
this config.
config NET_15_4_LOOPBACK_NUM
int
prompt "Number of times loopback test runs"
depends on (NETWORKING_WITH_15_4_LOOPBACK || NETWORKING_WITH_15_4_LOOPBACK_UART) && NET_SANITY_TEST
default 0
help
Number of times loopback test runs, 0 means infinite.
config NET_TESTING
bool
prompt "Enable network Qemu-to-Qemu testing setup"
depends on NETWORKING
default n
help
Setup the network stack such a way that it is suitable for
testing with Qemu-to-Qemu and slip. Note that this setting should
not be used for Qemu-to-Host communication.
source "net/ip/Kconfig.debug"
endmenu

View file

@ -1,274 +0,0 @@
# Kconfig.debug - IP stack debugging configuration options
#
# Copyright (c) 2016 Intel Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
menuconfig NETWORKING_WITH_LOGGING
bool "Enable network stack logging"
depends on NET_UIP
select STDOUT_CONSOLE
default n
help
Enable logging in various parts of the network stack.
choice
prompt "General debug level"
default NETWORK_IP_STACK_DEBUG_PRINT
depends on NETWORKING_WITH_LOGGING
help
Set the level of debugging you want. This will be generalized,
whatever the part you will be debugging.
config NETWORK_IP_STACK_DEBUG_PRINT
bool "Print only debug messages"
config NETWORK_IP_STACK_DEBUG_ANNOTATE
bool "Print only annotations"
config NETWORK_IP_STACK_DEBUG_FULL
bool "Print both messages and annotations"
endchoice
if NETWORKING_WITH_LOGGING
config NETWORK_IP_STACK_DEBUG_CONTEXT
bool "Debug network context allocation"
default n
help
Enables printing of network context allocations and frees.
config NETWORK_IP_STACK_DEBUG_NET_BUF
bool "Debug network buffer allocation"
default n
help
Enables printing of network buffer allocations and frees.
config NETWORK_IP_STACK_DEBUG_RECV_SEND
bool "Debug network generic receive and send functions"
default n
help
Enables generic debug printing when receiving and sending data.
config NETWORK_IP_STACK_DEBUG_TCP_PSOCK
bool "Debug network TCP protosockets"
depends on NETWORKING_WITH_TCP
default n
help
Enables debugging the protosockets used in TCP engine.
config NETWORK_IP_STACK_DEBUG_IPV6
bool "Debug core IPv6"
depends on NETWORKING_WITH_IPV6 || NET_IPV6
default n
help
Enables core IPv6 code part to output debug messages
config NETWORK_IP_STACK_DEBUG_SIMPLE_UDP
bool "Debug simple udp"
default n
help
Enables network simple udp debug messages
config NETWORK_IP_STACK_DEBUG_UDP_PACKET
bool "Debug udp packet"
default n
help
Enables network uip udp packet debug messages
config NETWORK_IP_STACK_DEBUG_IPV6_DS
bool "Debug IPv6 Data Structures"
depends on NETWORKING_WITH_IPV6
default n
help
Enables IPv6 Data Structures code part to output debug messages
config NETWORK_IP_STACK_DEBUG_IPV6_ICMPV6
bool "Debug ICMPv6"
depends on NETWORKING_WITH_IPV6
default n
help
Enables ICMPv6 code part to output debug messages
config NETWORK_IP_STACK_DEBUG_IPV6_ND
bool "Debug IPv6 Neighbour Discovery"
depends on NETWORKING_WITH_IPV6 || NET_IPV6
default n
help
Enables IPv6 Neighbour Discovery code part to output debug messages
config NETWORK_IP_STACK_DEBUG_IPV6_NBR_CACHE
bool "Debug IPv6 neighbour cache"
depends on NETWORKING_WITH_IPV6 || NET_IPV6
default n
help
Enables Neighbour Cache code part to output debug messages
config NETWORK_IP_STACK_DEBUG_IPV6_ROUTE
bool "Debug IPv6 route"
depends on NETWORKING_WITH_IPV6 || NET_IPV6
default n
help
Enables IPv6 route code part to output debug messages
config NETWORK_IP_STACK_DEBUG_15_4_NET_DRIVER
bool "Debug 802.15.4 network driver"
depends on NETWORKING_WITH_15_4
default n
help
Enables 802.15.4 network driver output debug messages
config NETWORK_IP_STACK_DEBUG_15_4_MAC
bool "Debug 802.15.4 MAC layer"
depends on NETWORKING_WITH_15_4
default n
help
Enables 802.15.4 MAC layer to output debug messages
config NETWORK_IP_STACK_DEBUG_15_4_FRAMING
bool "Debug 802.15.4 packet framing"
depends on NETWORKING_WITH_15_4
default n
help
Enables 802.15.4 packet framing to output debug messages
config NETWORK_IP_STACK_DEBUG_15_4_6LOWPAN_FRAG
bool "Debug 802.15.4 6LoWPAN fragmentation"
depends on NETWORKING_WITH_15_4
default n
help
Enables 802.15.4 6LoWPAN fragmentation to output debug messages
config NETWORK_IP_STACK_DEBUG_6LOWPAN_COMPRESSION
bool "Debug generic 6LoWPAN compression"
depends on NETWORKING_WITH_IPV6
default n
help
Enables generic (802.15.4 or Bluetooth) 6LoWPAN compression
to output debug messages
config NETWORK_IP_STACK_DEBUG_PACKET_QUEUE
bool "Debug uip packet queue"
depends on NETWORKING_WITH_IPV6
default n
help
Enables uip packet queue output debug messages
config NETWORK_IP_STACK_DEBUG_RPL
bool "Debug RPL messages"
depends on NETWORKING_WITH_RPL
default n
help
Enables RPL debug messages
config NETWORK_IP_STACK_DEBUG_RPL_ICMPV6
bool "Debug RPL ICMPv6 messages"
depends on NETWORKING_WITH_RPL
default n
help
Enables RPL ICMPv6 debug messages
config NETWORK_IP_STACK_DEBUG_RPL_OF
bool "Debug RPL objective function messages"
depends on NETWORKING_WITH_RPL
default n
help
Enables RPL Objective Function related debug messages
config NETWORK_IP_STACK_DEBUG_RPL_TIMERS
bool "Debug RPL timer functionality"
depends on NETWORKING_WITH_RPL
default n
help
Enables RPL timers related debug messages
config NETWORK_IP_STACK_DEBUG_IPV4
bool "Debug core IPv4"
depends on NETWORKING_WITH_IPV4 || NET_IPV4
default n
help
Enables core IPv4 code part to output debug messages
config NETWORK_IP_STACK_DEBUG_IPV4_ARP
bool "Debug IPv4 ARP"
depends on NETWORKING_WITH_IPV4 || NET_IPV4
default n
help
Enables core ARP code part to output debug messages
config NETWORK_IP_STACK_DEBUG_COAP_CONTEXT
bool "Debug CoAP context"
depends on ER_COAP
default n
help
Enables CoAP context output debug messages
config NETWORK_IP_STACK_DEBUG_COAP_ENGINE
bool "Debug CoAP engine"
depends on ER_COAP
default n
help
Enables CoAP engine output debug messages
config NETWORK_IP_STACK_DEBUG_COAP_TRANSACTION
bool "Debug CoAP transaction"
depends on ER_COAP
default n
help
Enables CoAP transaction output debug messages
config NETWORK_IP_STACK_DEBUG_COAP_INTERNAL
bool "Debug CoAP internals"
depends on ER_COAP
default n
help
Enables CoAP internals output debug messages
config NETWORK_IP_STACK_DEBUG_COAP_OBSERVE
bool "Debug CoAP observe"
depends on ER_COAP
default n
help
Enables CoAP observe output debug messages
config NETWORK_IP_STACK_DEBUG_COAP_WELL_KNOWN
bool "Debug CoAP well known core"
depends on ER_COAP
default n
help
Enables CoAP resource well known core ouput debug messages
config NETWORK_IP_STACK_DEBUG_REST_ENGINE
bool "Debug REST engine"
depends on ER_COAP
default n
help
Enables REST engine output debug messages
config NETWORK_IP_STACK_DEBUG_DHCP
bool "Debug DHCP"
depends on DHCP
default n
help
Enables DHCP output debug messages
config NETWORK_IP_STACK_DEBUG_TRICKLE
bool "Debug Trickle algorithm"
default n
help
Enables Trickle library output debug messages
endif

View file

@ -1,184 +0,0 @@
ccflags-y += -I${srctree}/net/ip/contiki
ccflags-y += -I${srctree}/net/ip/contiki/os/lib
ccflags-y += -I${srctree}/net/ip/contiki/os
ccflags-y += -I${srctree}/net/ip
ccflags-y += -I${srctree}/include/drivers
# Zephyr specific files
obj-y = net_core.o \
ip_buf.o \
net_context.o
obj-$(CONFIG_L2_BUFFERS) += l2_buf.o
# Contiki IP stack files
obj-y += contiki/netstack.o \
contiki/nbr-table.o \
contiki/linkaddr.o \
contiki/ip/uip-debug.o \
contiki/ip/uip-packetqueue.o \
contiki/ip/uip-udp-packet.o \
contiki/ip/udp-socket.o \
contiki/ip/simple-udp.o \
contiki/ip/uiplib.o \
contiki/ip/uip-nameserver.o \
contiki/ip/tcpip.o \
contiki/os/sys/process.o \
contiki/os/sys/stimer.o \
contiki/os/sys/etimer.o \
contiki/os/sys/timer.o \
contiki/os/sys/arg.o \
contiki/os/sys/ctimer.o \
contiki/os/sys/rtimer.o \
contiki/os/sys/clock.o \
contiki/os/dev/nullradio.o \
contiki/os/lib/mmem.o \
contiki/os/lib/memb.o \
contiki/os/lib/list.o \
contiki/os/lib/random.o \
contiki/os/lib/aes-128.o \
contiki/llsec/nullsec.o
obj-$(CONFIG_NETWORKING_WITH_IPV6) += \
contiki/ipv6/uip6.o \
contiki/ipv6/uip-icmp6.o \
contiki/ipv6/uip-ds6.o \
contiki/ipv6/uip-nd6.o \
contiki/ipv6/uip-ds6-route.o \
contiki/ipv6/uip-ds6-nbr.o
obj-$(CONFIG_NETWORKING_WITH_IPV4) += \
contiki/ipv4/uip_arp.o \
contiki/ipv4/uip.o \
contiki/ipv4/uip-neighbor.o
obj-$(CONFIG_NETWORKING_WITH_TCP) += contiki/ip/psock.o
# RPL (RFC 6550) support
ifeq ($(CONFIG_NETWORKING_WITH_RPL),y)
ccflags-y += -DUIP_CONF_IPV6_RPL=1
obj-y += contiki/rpl/rpl-dag.o \
contiki/rpl/rpl-timers.o \
contiki/rpl/rpl.o \
contiki/rpl/rpl-ext-header.o \
contiki/rpl/rpl-icmp6.o \
contiki/ipv6/multicast/uip-mcast6-route.o \
contiki/ipv6/multicast/smrf.o \
contiki/ipv6/multicast/uip-mcast6-stats.o
obj-$(CONFIG_RPL_WITH_OF0) += contiki/rpl/rpl-of0.o
obj-$(CONFIG_RPL_WITH_MRHOF) += contiki/rpl/rpl-mrhof.o
else
ccflags-y += -DUIP_CONF_IPV6_RPL=0
endif
# 6LoWPAN support
ifeq ($(CONFIG_NETWORKING_WITH_6LOWPAN),y)
ccflags-y += -DSICSLOWPAN_CONF_ENABLE
obj-y += contiki/sicslowpan/sicslowpan_compression.o
obj-$(CONFIG_NETWORKING_WITH_15_4) += contiki/sicslowpan/sicslowpan_fragmentation.o
else
obj-$(CONFIG_NETWORKING_WITH_15_4) += contiki/mac/framer-nullmac.o \
contiki/mac/simplerdc.o \
contiki/sicslowpan/null_compression.o \
contiki/sicslowpan/null_fragmentation.o
endif
# RDC driver
ifeq ($(CONFIG_NETWORKING_WITH_15_4_RDC_SICSLOWMAC),y)
obj-$(CONFIG_NETWORKING_WITH_15_4) += contiki/mac/sicslowmac/sicslowmac.o
else
ifeq ($(CONFIG_NETWORKING_WITH_15_4_RDC_SIMPLE),y)
obj-$(CONFIG_NETWORKING_WITH_15_4) += contiki/mac/simplerdc.o
endif
endif
ccflags-$(CONFIG_NETWORKING_WITH_LOGGING) += -DUIP_CONF_LOGGING=1
obj-$(CONFIG_NETWORKING_WITH_LOGGING) += contiki/uip-log.o
obj-$(CONFIG_NETWORKING_WITH_LOOPBACK) += net_driver_loopback.o
obj-$(CONFIG_NETWORKING_WITH_15_4_LOOPBACK) += dummy_15_4_radio.o
obj-$(CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART) += dummy_15_4_radio.o
obj-$(CONFIG_NETWORKING_WITH_15_4) += net_driver_15_4.o \
contiki/packetbuf.o \
contiki/queuebuf.o \
contiki/mac/mac.o \
contiki/mac/framer.o \
contiki/mac/frame802154.o \
contiki/mac/framer-802154.o \
contiki/mac/mac-sequence.o
obj-$(CONFIG_NETWORKING_WITH_15_4_MAC_NULL) += contiki/mac/nullmac.o
obj-$(CONFIG_NETWORKING_WITH_15_4_MAC_CSMA) += contiki/mac/csma.o
obj-$(CONFIG_15_4_BEACON_SUPPORT) += contiki/mac/handler-802154.o
obj-$(CONFIG_NETWORKING_WITH_BT) += net_driver_bt.o \
contiki/packetbuf.o \
contiki/queuebuf.o \
contiki/mac/mac.o \
contiki/mac/framer.o \
contiki/mac/framer-nullmac.o \
contiki/sicslowpan/null_fragmentation.o
# At the moment we only need nullsec driver for 802.15.4
#obj-$(CONFIG_NETWORKING_WITH_15_4) += contiki/llsec/ccm-star.o \
# contiki/llsec/ccm-star.o \
# contiki/llsec/anti-replay.o
ifeq ($(CONFIG_NETWORKING_WITH_15_4),y)
obj-y += contiki/mac/nullmac.o \
contiki/mac/framer-nullmac.o \
contiki/mac/simplerdc.o
endif
obj-$(CONFIG_NETWORKING_UART) += contiki/os/dev/slip.o \
contiki/os/dev/slip-arch.o \
net_driver_slip.o
obj-$(CONFIG_ETHERNET) += net_driver_ethernet.o
ccflags-$(CONFIG_TINYDTLS) += -DCONTIKI_TARGET_ZEPHYR=1
ccflags-$(CONFIG_TINYDTLS) += -DWITH_SHA256=1
ccflags-$(CONFIG_TINYDTLS) += -DDTLS_TICKS_PER_SECOND=sys_clock_ticks_per_sec
ccflags-$(CONFIG_TINYDTLS) += -I${srctree}/net/ip/contiki/os/sys
ccflags-$(CONFIG_TINYDTLS) += -I${srctree}/net/ip/tinydtls
obj-$(CONFIG_TINYDTLS) += tinydtls/dtls.o \
tinydtls/crypto.o \
tinydtls/hmac.o \
tinydtls/aes/rijndael.o \
tinydtls/sha2/sha2.o \
tinydtls/ccm.o \
tinydtls/netq.o \
tinydtls/dtls_time.o \
tinydtls/peer.o \
tinydtls/session.o \
tinydtls/ecc/ecc.o
ifeq ($(CONFIG_TINYDTLS_DEBUG),)
ccflags-y += -DNDEBUG
endif
obj-$(CONFIG_TINYDTLS_DEBUG) += tinydtls/debug.o
ccflags-$(CONFIG_ER_COAP) += -I${srctree}/net/ip/rest-engine
ccflags-$(CONFIG_ER_COAP) += -I${srctree}/net/ip/er-coap
obj-$(CONFIG_ER_COAP) += er-coap/er-coap.o \
er-coap/er-coap-engine.o \
er-coap/er-coap-transactions.o \
er-coap/er-coap-observe.o \
er-coap/er-coap-separate.o \
er-coap/er-coap-res-well-known-core.o \
er-coap/er-coap-block1.o \
er-coap/er-coap-context.o \
rest-engine/rest-engine.o
obj-$(CONFIG_ER_COAP_CLIENT) += er-coap/er-coap-observe-client.o
obj-$(CONFIG_DHCP) += contiki/ip/dhcpc.o
obj-$(CONFIG_NETWORKING_WITH_TRICKLE) += \
contiki/trickle/trickle-timer.o

View file

@ -1,8 +0,0 @@
#ifndef CC2520154RADIO_H
#define CC2520154RADIO_H
#include "dev/radio.h"
extern const struct radio_driver cc2520_15_4_radio_driver;
#endif /* CC2520154RADIO_H */

View file

@ -1,254 +0,0 @@
/* contiki-conf.h - These settings override the default configuration */
/*
* Copyright (c) 2016 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdint.h>
#include <sys_clock.h>
#ifndef __CONTIKI_CONF_H__
#define __CONTIKI_CONF_H__
#define PACK_ALIAS_STRUCT __attribute__((__packed__,__may_alias__))
#define CCIF
#define CLIF
typedef uint32_t clock_time_t;
typedef unsigned int uip_stats_t;
#define CLOCK_CONF_SECOND sys_clock_ticks_per_sec
/* It is either IPv6 or IPv4 but not both at the same time. */
#ifdef CONFIG_NETWORKING_WITH_IPV6
#define NETSTACK_CONF_WITH_IPV6 1
#define UIP_CONF_ICMP6 1
#elif CONFIG_NETWORKING_WITH_IPV4
#define NETSTACK_CONF_WITH_IPV6 0
#else
#error "Either IPv6 or IPv4 needs to be supported."
#endif
/* The actual MTU size is defined in uipopt.h */
#define UIP_CONF_BUFFER_SIZE UIP_LINK_MTU
#ifdef CONFIG_NETWORKING_WITH_TCP
#define UIP_CONF_TCP 1
#ifdef CONFIG_TCP_DISABLE_ACTIVE_OPEN
#define UIP_CONF_ACTIVE_OPEN 0
#else /* CONFIG_TCP_DISABLE_ACTIVE_OPEN */
#define UIP_CONF_ACTIVE_OPEN 1
#endif /* CONFIG_TCP_DISABLE_ACTIVE_OPEN */
#if CONFIG_TCP_MSS > 0
#define UIP_CONF_TCP_MSS CONFIG_TCP_MSS
#endif /* CONFIG_TCP_MSS */
#if CONFIG_TCP_RECEIVE_WINDOW > 0
#define UIP_CONF_RECEIVE_WINDOW CONFIG_TCP_RECEIVE_WINDOW
#endif /* CONFIG_TCP_RECEIVE_WINDOW */
#else
#define UIP_CONF_TCP 0
#endif
/* We do not want to be a router */
#define UIP_CONF_ROUTER 0
/* No Rime */
#define NETSTACK_CONF_WITH_RIME 0
/* How many IPv6 addresses will be allocated for the user (default is 2).
* Increased this setting so that user can specify multicast addresses.
*/
#define UIP_CONF_DS6_ADDR_NBU 4
/* The queuebuf count defines how many fragments we are able to
* receive. Value 13 means that we can receive full IPv6 data
* (1280 bytes), we need also some extra buffers for temp use.
*/
#define QUEUEBUF_CONF_NUM (13 + 5)
/* Do not just drop packets because of some other packet is sent.
* So queue the packet and send it later.
*/
#define UIP_CONF_IPV6_QUEUE_PKT 1
#ifdef SICSLOWPAN_CONF_ENABLE
/* Min and Max compressible UDP ports */
#define SICSLOWPAN_UDP_PORT_MIN 0xF0B0
#define SICSLOWPAN_UDP_PORT_MAX 0xF0BF /* F0B0 + 15 */
#define NETSTACK_CONF_COMPRESS sicslowpan_compression
#ifdef CONFIG_NETWORKING_WITH_BT
#define NETSTACK_CONF_FRAGMENT null_fragmentation
#else
#define NETSTACK_CONF_FRAGMENT sicslowpan_fragmentation
#endif
#else
#define NETSTACK_CONF_COMPRESS null_compression
#define NETSTACK_CONF_FRAGMENT null_fragmentation
#endif /* SICSLOWPAN_CONF_ENABLE */
#ifdef CONFIG_NETWORKING_WITH_15_4
#ifdef CONFIG_NETWORKING_WITH_15_4_PAN_ID
#define IEEE802154_CONF_PANID CONFIG_NETWORKING_WITH_15_4_PAN_ID
#endif /* CONFIG_NETWORKING_WITH_15_4_PAN_ID */
#define NETSTACK_CONF_FRAMER framer_802154
#ifdef CONFIG_NETWORKING_WITH_6LOWPAN
#if defined(CONFIG_NETWORKING_WITH_15_4_RDC_SICSLOWMAC)
#define NETSTACK_CONF_RDC sicslowmac_driver
#elif defined(CONFIG_NETWORKING_WITH_15_4_RDC_SIMPLE)
#define NETSTACK_CONF_RDC simplerdc_driver
/* Simple RDC config*/
#ifdef CONFIG_TI_CC2520_AUTO_ACK
#define SIMPLERDC_802154_AUTOACK 1
#else
#define SIMPLERDC_802154_SEND_ACK 1
#endif
#ifdef CONFIG_NETWORKING_WITH_15_4_ALWAYS_ACK
#define SIMPLERDC_802154_ACK_REQ 1
#endif
#define SIMPLERDC_MAX_RETRANSMISSIONS 3
#endif /* RDC driver */
#endif /* CONFIG_NETWORKING_WITH_6LOWPAN */
#ifdef CONFIG_NETWORKING_WITH_15_4_MAC_NULL
#define NETSTACK_CONF_MAC nullmac_driver
#endif
#ifdef CONFIG_NETWORKING_WITH_15_4_MAC_CSMA
#define NETSTACK_CONF_MAC csma_driver
#endif
#define LINKADDR_CONF_SIZE 8
#define UIP_CONF_LL_802154 1
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1
#ifdef CONFIG_6LOWPAN_COMPRESSION_IPHC
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_IPHC
#else /* 6lowpan compression method */
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_IPV6
#endif /* 6lowpan compression method */
#ifdef CONFIG_15_4_BEACON_SUPPORT
#define FRAMER_802154_HANDLER handler_802154_frame_received
#endif /* CONFIG_15_4_BEACON_SUPPORT */
#ifdef CONFIG_15_4_BEACON_STATS
#define HANDLER_802154_CONF_STATS 1
#endif /* CONFIG_15_4_BEACON_STATS */
#else /* CONFIG_NETWORKING_WITH_15_4 */
#define NETSTACK_CONF_FRAMER framer_nullmac
#define NETSTACK_CONF_RDC simplerdc_driver
#define NETSTACK_CONF_MAC nullmac_driver
#define LINKADDR_CONF_SIZE 6
#ifdef CONFIG_NETWORKING_WITH_BT
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_IPHC
#endif /* CONFIG_NETWORKING_WITH_BT */
#endif /* CONFIG_NETWORKING_WITH_15_4 */
#define NETSTACK_CONF_LLSEC nullsec_driver
#ifdef CONFIG_NETWORKING_WITH_15_4_TI_CC2520
#define NETSTACK_CONF_RADIO cc2520_15_4_radio_driver
#endif
#ifdef CONFIG_NETWORKING_WITH_RPL
#define UIP_MCAST6_CONF_ENGINE UIP_MCAST6_ENGINE_SMRF
#define UIP_CONF_IPV6_MULTICAST 1
#ifdef CONFIG_RPL_WITH_MRHOF
#define RPL_CONF_OF rpl_mrhof
#else
#define RPL_CONF_OF rpl_of0
#endif /* CONFIG_RPL_WITH_MRHOF */
#ifdef CONFIG_RPL_PROBING
#define RPL_CONF_WITH_PROBING 1
#else
#define RPL_CONF_WITH_PROBING 0
#endif /* CONFIG_RPL_PROBING */
#ifdef CONFIG_RPL_STATS
#define RPL_CONF_STATS 1
#else
#define RPL_CONF_STATS 0
#endif /* CONFIG_RPL_STATS */
#else /* CONFIG_NETWORKING_WITH_RPL */
#define RPL_CONF_STATS 0
#endif
#if defined(CONFIG_NETWORKING_STATISTICS) && defined(CONFIG_L2_BUFFERS)
#define NET_MAC_CONF_STATS 1
#else
#define NET_MAC_CONF_STATS 0
#endif
#if defined(CONFIG_COAP_STATS)
#define NET_COAP_CONF_STATS 1
#define NET_COAP_STAT(code) (net_coap_stats.code)
#else
#define NET_COAP_CONF_STATS 0
#define NET_COAP_STAT(code)
#endif
#ifdef CONFIG_NETWORKING_IPV6_NO_ND
/* Disabling ND will simplify the IPv6 address assignment.
* This should only be done in testing phase.
*/
#define UIP_CONF_ND6_SEND_NA 0
#else
#define UIP_CONF_ND6_SEND_NA 1
#endif
#ifndef NETSTACK_CONF_RADIO
/* #error "No radio configured, cannot continue!" */
#endif
#ifdef CONFIG_ER_COAP
#ifndef REST
#define REST REGISTERED_ENGINE_ERBIUM
#endif
#endif
#ifdef CONFIG_ER_COAP_WITH_DTLS
#define ER_COAP_WITH_DTLS 1
#else
#define ER_COAP_WITH_DTLS 0
#endif
#ifdef CONFIG_ER_COAP_CLIENT
#define COAP_OBSERVE_CLIENT 1
#else
#undef COAP_OBSERVE_CLIENT
#endif
#ifdef CONFIG_NETWORKING_STATISTICS
#define UIP_CONF_STATISTICS 1
#endif
#ifdef CONFIG_ETHERNET
#define UIP_CONF_LLH_LEN 14
#endif
#if defined(CONFIG_UDP_MAX_CONNECTIONS)
#define UIP_CONF_UDP_CONNS CONFIG_UDP_MAX_CONNECTIONS
#endif
#if defined(CONFIG_TCP_MAX_CONNECTIONS)
#define UIP_CONF_MAX_CONNECTIONS CONFIG_TCP_MAX_CONNECTIONS
#endif
#if defined(CONFIG_NETWORKING_MAX_NEIGHBORS)
#define NBR_TABLE_CONF_MAX_NEIGHBORS CONFIG_NETWORKING_MAX_NEIGHBORS
#endif
#endif /* __CONTIKI_CONF_H__ */

View file

@ -1,266 +0,0 @@
/*
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef CONTIKI_DEFAULT_CONF_H
#define CONTIKI_DEFAULT_CONF_H
/*---------------------------------------------------------------------------*/
/* Netstack configuration
*
* The netstack configuration is typically overridden by the platform
* configuration, as defined in contiki-conf.h
*/
/* NETSTACK_CONF_RADIO specifies the radio driver. The radio driver
typically depends on the radio used on the target hardware. */
#ifndef NETSTACK_CONF_RADIO
#if defined (CONFIG_NETWORKING_WITH_15_4_LOOPBACK)
#define NETSTACK_CONF_RADIO dummy154radio_driver
#elif defined (CONFIG_NETWORKING_WITH_15_4_LOOPBACK_UART)
#define NETSTACK_CONF_RADIO dummy154radio_driver
#else
#define NETSTACK_CONF_RADIO nullradio_driver
#endif /* CONFIG_NETWORKING_WITH_15_4_LOOPBACK */
/* #define NETSTACK_CONF_RADIO cc2420_driver */
#endif /* NETSTACK_CONF_RADIO */
/* NETSTACK_CONF_FRAMER specifies the over-the-air frame format used
by Contiki radio packets. For IEEE 802.15.4 radios, use the
framer_802154 driver. */
#ifndef NETSTACK_CONF_FRAMER
#define NETSTACK_CONF_FRAMER framer_nullmac
/* #define NETSTACK_CONF_FRAMER framer_802154 */
#endif /* NETSTACK_CONF_FRAMER */
/* NETSTACK_CONF_RDC specifies the Radio Duty Cycling (RDC) layer. The
simplerdc_driver never turns the radio off and is compatible with all
radios, but consumes a lot of power. The contikimac_driver is
highly power-efficent and allows sleepy routers, but is not
compatible with all radios. */
#ifndef NETSTACK_CONF_RDC
#define NETSTACK_CONF_RDC simplerdc_driver
/* #define NETSTACK_CONF_RDC contikimac_driver */
#endif /* NETSTACK_CONF_RDC */
/* NETSTACK_CONF_MAC specifies the Medium Access Control (MAC)
layer. The nullmac_driver does not provide any MAC
functionality. The csma_driver is the default CSMA MAC layer, but
is not compatible with all radios. */
#ifndef NETSTACK_CONF_MAC
#define NETSTACK_CONF_MAC nullmac_driver
/* #define NETSTACK_CONF_MAC csma_driver */
#endif /* NETSTACK_CONF_MAC */
/* NETSTACK_CONF_LLSEC specifies the link layer security driver. */
#ifndef NETSTACK_CONF_LLSEC
#define NETSTACK_CONF_LLSEC nullsec_driver
#endif /* NETSTACK_CONF_LLSEC */
#ifndef NETSTACK_CONF_FRAGMENT
#define NETSTACK_CONF_FRAGMENT null_fragmentation
#endif /* NETSTACK_CONF_FRAGMENT */
#ifndef NETSTACK_CONF_COMPRESS
#define NETSTACK_CONF_COMPRESS null_compression
#endif /* NETSTACK_CONF_COMPRESS */
/* To avoid unnecessary complexity, we assume the common case of
a constant LoWPAN-wide IEEE 802.15.4 security level, which
can be specified by defining LLSEC802154_CONF_SECURITY_LEVEL. */
#ifndef LLSEC802154_CONF_SECURITY_LEVEL
#define LLSEC802154_CONF_SECURITY_LEVEL 0
#endif /* LLSEC802154_CONF_SECURITY_LEVEL */
/* NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE specifies the channel check
rate of the RDC layer. This defines how often the RDC will wake up
and check for radio channel activity. A higher check rate results
in higher communication performance at the cost of a higher power
consumption. */
#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8
#endif /* NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE */
/*---------------------------------------------------------------------------*/
/* Packet buffer size options.
*
* The packet buffer size options can be tweaked on a per-project
* basis to reduce memory consumption.
*/
/* QUEUEBUF_CONF_NUM specifies the number of queue buffers. Queue
buffers are used throughout the Contiki netstack but the
configuration option can be tweaked to save memory. Performance can
suffer with a too low number of queue buffers though. */
#ifndef QUEUEBUF_CONF_NUM
#define QUEUEBUF_CONF_NUM 8
#endif /* QUEUEBUF_CONF_NUM */
/*---------------------------------------------------------------------------*/
/* uIPv6 configuration options.
*
* Many of the uIPv6 configuration options can be overriden by a
* project-specific configuration to save memory.
*/
/* NETSTACK_CONF_WITH_IPV6 specifies whether or not IPv6 should be used. If IPv6
is not used, IPv4 is used instead. */
#ifndef NETSTACK_CONF_WITH_IPV6
#define NETSTACK_CONF_WITH_IPV6 0
#endif /* NETSTACK_CONF_WITH_IPV6 */
/* UIP_CONF_BUFFER_SIZE specifies how much memory should be reserved
for the uIP packet buffer. This sets an upper bound on the largest
IP packet that can be received by the system. */
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_CONF_BUFFER_SIZE 128
#endif /* UIP_CONF_BUFFER_SIZE */
/* UIP_CONF_ROUTER specifies if the IPv6 node should be a router or
not. By default, all Contiki nodes are routers. */
#ifndef UIP_CONF_ROUTER
#define UIP_CONF_ROUTER 1
#endif /* UIP_CONF_ROUTER */
/* UIP_CONF_IPV6_RPL specifies if RPL is to be used for IPv6
routing. */
#ifndef UIP_CONF_IPV6_RPL
#define UIP_CONF_IPV6_RPL 1
#endif /* UIP_CONF_IPV6_RPL */
/* UIP_CONF_MAX_ROUTES specifies the maximum number of routes that each
node will be able to handle. */
#ifndef UIP_CONF_MAX_ROUTES
#define UIP_CONF_MAX_ROUTES 20
#endif /* UIP_CONF_MAX_ROUTES */
/* UIP_CONF_UDP specifies if UDP support should be included or
not. Disabling UDP saves memory but breaks a lot of stuff. */
#ifndef UIP_CONF_UDP
#define UIP_CONF_UDP 1
#endif /* UIP_CONF_UDP */
/* UIP_CONF_MAX_CONNECTIONS specifies the maximum number of
simultaneous TCP connections. */
#ifndef UIP_CONF_MAX_CONNECTIONS
#define UIP_CONF_MAX_CONNECTIONS 8
#endif /* UIP_CONF_MAX_CONNECTIONS */
/* UIP_CONF_TCP specifies if TCP support should be included or
not. Disabling TCP saves memory. */
#ifndef UIP_CONF_TCP
#define UIP_CONF_TCP 1
#endif /* UIP_CONF_TCP */
/* UIP_CONF_MAX_CONNECTIONS specifies the maximum number of
simultaneous TCP connections. */
#ifndef UIP_CONF_MAX_CONNECTIONS
#define UIP_CONF_MAX_CONNECTIONS 8
#endif /* UIP_CONF_MAX_CONNECTIONS */
/* UIP_CONF_TCP_SPLIT enables a performance optimization hack, where
each maximum-sized TCP segment is split into two, to avoid the
performance degradation that is caused by delayed ACKs. */
#ifndef UIP_CONF_TCP_SPLIT
#define UIP_CONF_TCP_SPLIT 0
#endif /* UIP_CONF_TCP_SPLIT */
/* NBR_TABLE_CONF_MAX_NEIGHBORS specifies the maximum number of neighbors
that each node will be able to handle. */
#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS
#define NBR_TABLE_CONF_MAX_NEIGHBORS 8
#endif /* NBR_TABLE_CONF_MAX_NEIGHBORS */
/* UIP_CONF_ND6_SEND_NA enables standard IPv6 Neighbor Discovery Protocol.
This is unneeded when RPL is used. Disable to save ROM and a little RAM. */
#ifndef UIP_CONF_ND6_SEND_NA
#define UIP_CONF_ND6_SEND_NA 1
#endif /* UIP_CONF_ND6_SEND_NA */
/*---------------------------------------------------------------------------*/
/* 6lowpan configuration options.
*
* These options change the behavior of the 6lowpan header compression
* code (sicslowpan). They typically depend on the type of radio used
* on the target platform, and are therefore platform-specific.
*/
/* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS specifies how many times the
MAC layer should resend packets if no link-layer ACK was
received. This only makes sense with the csma_driver
NETSTACK_CONF_MAC. */
#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS
#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 4
#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */
/* SICSLOWPAN_CONF_FRAG specifies if 6lowpan fragmentation should be
used or not. Fragmentation is on by default. */
#ifndef SICSLOWPAN_CONF_FRAG
#define SICSLOWPAN_CONF_FRAG 1
#endif /* SICSLOWPAN_CONF_FRAG */
/* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD is the maximum available size for
frame headers, link layer security-related overhead, as well as
6LoWPAN payload. By default, SICSLOWPAN_CONF_MAC_MAX_PAYLOAD is
127 bytes (MTU of 802.15.4) - 2 bytes (Footer of 802.15.4). */
#ifndef SICSLOWPAN_CONF_MAC_MAX_PAYLOAD
#define SICSLOWPAN_CONF_MAC_MAX_PAYLOAD (127 - 2)
#endif /* SICSLOWPAN_CONF_MAC_MAX_PAYLOAD */
/* SICSLOWPAN_CONF_COMPRESSION_THRESHOLD sets a lower threshold for
when packets should not be compressed. This is used by ContikiMAC,
which requires packets to be larger than a given minimum size. */
#ifndef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD
#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 0
/* #define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 */
#endif /* SICSLOWPAN_CONF_COMPRESSION_THRESHOLD */
/* SICSLOWPAN_CONF_COMPRESSION specifies what 6lowpan compression
mechanism to be used. 6lowpan hc06 is the default in Contiki. */
#ifndef SICSLOWPAN_CONF_COMPRESSION
#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06
#endif /* SICSLOWPAN_CONF_COMPRESSION */
/*---------------------------------------------------------------------------*/
/* ContikiMAC configuration options.
*
* These are typically configured on a per-platform basis.
*/
/* CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION specifies if ContikiMAC
should optimize for the phase of neighbors. The phase optimization
may reduce power consumption but is not compatible with all timer
settings and is therefore off by default. */
#ifndef CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION
#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0
#endif /* CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION */
#endif /* CONTIKI_DEFAULT_CONF_H */

View file

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

View file

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

View file

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

View file

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

View file

@ -1,495 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#include <stdio.h>
#include <string.h>
#include <net/ip_buf.h>
#include "contiki.h"
#include "contiki-net.h"
#include "contiki/ip/dhcpc.h"
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_DHCP
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
#define STATE_INITIAL 0
#define STATE_SENDING 1
#define STATE_OFFER_RECEIVED 2
#define STATE_CONFIG_RECEIVED 3
static struct dhcpc_state s;
dhcpc_configured configure_cb = NULL;
dhcpc_unconfigured unconfigure_cb = NULL;
struct dhcp_msg {
uint8_t op, htype, hlen, hops;
uint8_t xid[4];
uint16_t secs, flags;
uint8_t ciaddr[4];
uint8_t yiaddr[4];
uint8_t siaddr[4];
uint8_t giaddr[4];
uint8_t chaddr[16];
#ifndef UIP_CONF_DHCP_LIGHT
uint8_t sname[64];
uint8_t file[128];
#endif
uint8_t options[312];
} __packed;
#ifdef CONFIG_DHCP_BROADCAST
#define BOOTP_BROADCAST 0x8000
#elif CONFIG_DHCP_UNICAST
#define BOOTP_UNICAST 0x0000
#endif
#define DHCP_REQUEST 1
#define DHCP_REPLY 2
#define DHCP_HTYPE_ETHERNET 1
#define DHCP_HLEN_ETHERNET 6
#define DHCP_MSG_LEN 236
#define DHCPC_SERVER_PORT 67
#define DHCPC_CLIENT_PORT 68
#define DHCPDISCOVER 1
#define DHCPOFFER 2
#define DHCPREQUEST 3
#define DHCPDECLINE 4
#define DHCPACK 5
#define DHCPNAK 6
#define DHCPRELEASE 7
#define DHCP_OPTION_SUBNET_MASK 1
#define DHCP_OPTION_ROUTER 3
#define DHCP_OPTION_DNS_SERVER 6
#define DHCP_OPTION_REQ_IPADDR 50
#define DHCP_OPTION_LEASE_TIME 51
#define DHCP_OPTION_MSG_TYPE 53
#define DHCP_OPTION_SERVER_ID 54
#define DHCP_OPTION_REQ_LIST 55
#define DHCP_OPTION_END 255
static uint32_t xid;
static const uint8_t magic_cookie[4] = {99, 130, 83, 99};
/*---------------------------------------------------------------------------*/
static void
configure_dhcpc(struct dhcpc_state *s)
{
uip_sethostaddr(&s->ipaddr);
uip_setnetmask(&s->netmask);
uip_setdraddr(&s->default_router);
uip_nameserver_update(&s->dnsaddr, UIP_NAMESERVER_INFINITE_LIFETIME);
if(configure_cb)
configure_cb();
}
/*---------------------------------------------------------------------------*/
static void
unconfigure_dhcpc(struct dhcpc_state *s)
{
if(unconfigure_cb)
unconfigure_cb();
}
/*---------------------------------------------------------------------------*/
static uint8_t *
add_msg_type(uint8_t *optptr, uint8_t type)
{
*optptr++ = DHCP_OPTION_MSG_TYPE;
*optptr++ = 1;
*optptr++ = type;
return optptr;
}
/*---------------------------------------------------------------------------*/
static uint8_t *
add_server_id(uint8_t *optptr)
{
*optptr++ = DHCP_OPTION_SERVER_ID;
*optptr++ = 4;
memcpy(optptr, s.serverid, 4);
return optptr + 4;
}
/*---------------------------------------------------------------------------*/
static uint8_t *
add_req_ipaddr(uint8_t *optptr)
{
*optptr++ = DHCP_OPTION_REQ_IPADDR;
*optptr++ = 4;
memcpy(optptr, s.ipaddr.u16, 4);
return optptr + 4;
}
/*---------------------------------------------------------------------------*/
static uint8_t *
add_req_options(uint8_t *optptr)
{
*optptr++ = DHCP_OPTION_REQ_LIST;
*optptr++ = 3;
*optptr++ = DHCP_OPTION_SUBNET_MASK;
*optptr++ = DHCP_OPTION_ROUTER;
*optptr++ = DHCP_OPTION_DNS_SERVER;
return optptr;
}
/*---------------------------------------------------------------------------*/
static uint8_t *
add_end(uint8_t *optptr)
{
*optptr++ = DHCP_OPTION_END;
return optptr;
}
/*---------------------------------------------------------------------------*/
static void
create_msg(struct dhcp_msg *m)
{
m->op = DHCP_REQUEST;
m->htype = DHCP_HTYPE_ETHERNET;
m->hlen = s.mac_len;
m->hops = 0;
memcpy(m->xid, &xid, sizeof(m->xid));
m->secs = 0;
#ifdef CONFIG_DHCP_BROADCAST
m->flags = UIP_HTONS(BOOTP_BROADCAST); /* Broadcast bit. */
#elif CONFIG_DHCP_UNICAST
m->flags = UIP_HTONS(BOOTP_UNICAST); /* Unicast bit. */
#endif
/* uip_ipaddr_copy(m->ciaddr, uip_hostaddr);*/
memcpy(m->ciaddr, uip_hostaddr.u16, sizeof(m->ciaddr));
memset(m->yiaddr, 0, sizeof(m->yiaddr));
memset(m->siaddr, 0, sizeof(m->siaddr));
memset(m->giaddr, 0, sizeof(m->giaddr));
memcpy(m->chaddr, s.mac_addr, s.mac_len);
memset(&m->chaddr[s.mac_len], 0, sizeof(m->chaddr) - s.mac_len);
#ifndef UIP_CONF_DHCP_LIGHT
memset(m->sname, 0, sizeof(m->sname));
memset(m->file, 0, sizeof(m->file));
#endif
memcpy(m->options, magic_cookie, sizeof(magic_cookie));
}
/*---------------------------------------------------------------------------*/
static void
send_discover(void)
{
uint8_t *end;
struct dhcp_msg *m;
struct net_buf *buf;
int len;
buf = ip_buf_get_reserve_tx(UIP_LLH_LEN + UIP_IPUDPH_LEN);
if(!buf) {
PRINTF("dhcp: failed to get buffer\n");
return;
}
uip_set_udp_conn(buf) = s.conn;
m = (struct dhcp_msg *)uip_appdata(buf);
create_msg(m);
end = add_msg_type(&m->options[4], DHCPDISCOVER);
end = add_req_options(end);
end = add_end(end);
len = (int)(end - (uint8_t *)uip_appdata(buf));
uip_appdatalen(buf) = len;
uip_send_udp(buf, uip_appdata(buf), len);
}
/*---------------------------------------------------------------------------*/
static void
send_request(void)
{
uint8_t *end;
struct dhcp_msg *m;
struct net_buf *buf;
int len;
buf = ip_buf_get_reserve_tx(UIP_LLH_LEN + UIP_IPUDPH_LEN);
if(!buf) {
PRINTF("dhcp: failed to get buffer\n");
return;
}
uip_set_udp_conn(buf) = s.conn;
m = (struct dhcp_msg *)uip_appdata(buf);
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);
len = (int)(end - (uint8_t *)uip_appdata(buf));
uip_appdatalen(buf) = len;
uip_send_udp(buf, uip_appdata(buf), len);
}
/*---------------------------------------------------------------------------*/
static uint8_t
parse_options(uint8_t *optptr, int len)
{
uint8_t *end = optptr + len;
uint8_t type = 0;
while(optptr < end) {
switch(*optptr) {
case DHCP_OPTION_SUBNET_MASK:
memcpy(s.netmask.u16, optptr + 2, 4);
break;
case DHCP_OPTION_ROUTER:
memcpy(s.default_router.u16, optptr + 2, 4);
break;
case DHCP_OPTION_DNS_SERVER:
memcpy(s.dnsaddr.u16, optptr + 2, 4);
break;
case DHCP_OPTION_MSG_TYPE:
type = *(optptr + 2);
break;
case DHCP_OPTION_SERVER_ID:
memcpy(s.serverid, optptr + 2, 4);
break;
case DHCP_OPTION_LEASE_TIME:
memcpy(s.lease_time, optptr + 2, 4);
break;
case DHCP_OPTION_END:
return type;
}
optptr += optptr[1] + 2;
}
return type;
}
/*---------------------------------------------------------------------------*/
static uint8_t
parse_msg(struct net_buf *buf)
{
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata(buf);
uint8_t ret = 0;
if(m->op == DHCP_REPLY &&
memcmp(m->xid, &xid, sizeof(xid)) == 0 &&
memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
memcpy(s.ipaddr.u16, m->yiaddr, 4);
ret = parse_options(&m->options[4], uip_datalen(buf));
}
ip_buf_unref(buf);
return ret;
}
/*---------------------------------------------------------------------------*/
/*
* Is this a "fresh" reply for me? If it is, return the type.
*/
static int
msg_for_me(struct net_buf *buf)
{
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata(buf);
uint8_t *optptr = &m->options[4];
uint8_t *end = (uint8_t*)uip_appdata(buf) + uip_datalen(buf);
if(m->op == DHCP_REPLY &&
memcmp(m->xid, &xid, sizeof(xid)) == 0 &&
memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
while(optptr < end) {
if(*optptr == DHCP_OPTION_MSG_TYPE) {
return *(optptr + 2);
} else if (*optptr == DHCP_OPTION_END) {
return -1;
}
optptr += optptr[1] + 2;
}
}
return -1;
}
/*---------------------------------------------------------------------------*/
PROCESS(dhcp_process, "DHCP process");
PROCESS_THREAD(dhcp_process, ev, data, buf, user_data)
{
clock_time_t ticks;
PROCESS_BEGIN();
init:
xid++;
s.state = STATE_SENDING;
s.ticks = CLOCK_SECOND * 8;
while (1) {
send_discover();
etimer_set(&s.etimer, s.ticks, &dhcp_process);
do {
PROCESS_YIELD();
if(ev == tcpip_event && uip_newdata(buf) && msg_for_me(buf) == DHCPOFFER) {
parse_msg(buf);
s.state = STATE_OFFER_RECEIVED;
goto selecting;
}
} while (!etimer_expired(&s.etimer));
if(s.ticks < CLOCK_SECOND * 60) {
s.ticks *= 2;
}
}
selecting:
s.ticks = CLOCK_SECOND;
do {
send_request();
etimer_set(&s.etimer, s.ticks, &dhcp_process);
do {
PROCESS_YIELD();
if(ev == tcpip_event && uip_newdata(buf) && msg_for_me(buf) == DHCPACK) {
parse_msg(buf);
s.state = STATE_CONFIG_RECEIVED;
goto bound;
}
} while (!etimer_expired(&s.etimer));
if(s.ticks <= CLOCK_SECOND * 10) {
s.ticks += CLOCK_SECOND;
} else {
goto init;
}
} while(s.state != STATE_CONFIG_RECEIVED);
bound:
PRINTF("Got IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.ipaddr));
PRINTF("Got netmask %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.netmask));
PRINTF("Got DNS server %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.dnsaddr));
PRINTF("Got default router %d.%d.%d.%d\n",
uip_ipaddr_to_quad(&s.default_router));
PRINTF("Lease expires in %ld seconds\n",
uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]));
configure_dhcpc(&s);
#define MAX_TICKS (~((clock_time_t)0) / 2)
#define MAX_TICKS32 (~((uint32_t)0))
#define IMIN(a, b) ((a) < (b) ? (a) : (b))
if((uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]))*CLOCK_SECOND/2
<= MAX_TICKS32) {
s.ticks = (uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1])
)*CLOCK_SECOND/2;
} else {
s.ticks = MAX_TICKS32;
}
while(s.ticks > 0) {
ticks = IMIN(s.ticks, MAX_TICKS);
s.ticks -= ticks;
etimer_set(&s.etimer, ticks, &dhcp_process);
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_TIMER);
}
if((uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1]))*CLOCK_SECOND/2
<= MAX_TICKS32) {
s.ticks = (uip_ntohs(s.lease_time[0])*65536ul + uip_ntohs(s.lease_time[1])
)*CLOCK_SECOND/2;
} else {
s.ticks = MAX_TICKS32;
}
/* renewing: */
do {
send_request();
ticks = IMIN(s.ticks / 2, MAX_TICKS);
s.ticks -= ticks;
etimer_set(&s.etimer, ticks, &dhcp_process);
do {
PROCESS_YIELD();
if(ev == tcpip_event && uip_newdata(buf) && msg_for_me(buf) == DHCPACK) {
parse_msg(buf);
goto bound;
}
} while(!etimer_expired(&s.etimer));
} while(s.ticks >= CLOCK_SECOND*3);
/* rebinding: */
/* lease_expired: */
unconfigure_dhcpc(&s);
goto init;
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
void
dhcpc_init(const void *mac_addr, int mac_len)
{
uip_ipaddr_t addr;
uip_ipaddr_t ipaddr;
s.mac_addr = mac_addr;
s.mac_len = mac_len;
s.state = STATE_INITIAL;
uip_ipaddr(&ipaddr, 0,0,0,0);
uip_sethostaddr(&ipaddr);
uip_ipaddr(&addr, 255,255,255,255);
s.conn = udp_new(&addr, UIP_HTONS(DHCPC_SERVER_PORT), NULL);
if(s.conn != NULL) {
udp_bind(s.conn, UIP_HTONS(DHCPC_CLIENT_PORT));
}
process_start(&dhcp_process, NULL, NULL);
}
/*---------------------------------------------------------------------------*/
void
dhcpc_appcall(process_event_t ev, struct net_buf *buf)
{
if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) {
process_post_synch(&dhcp_process, ev, NULL, buf);
}
}
/*---------------------------------------------------------------------------*/
int msg_for_dhcpc(struct net_buf *buf)
{
int msg;
msg = msg_for_me(buf);
if(msg == DHCPOFFER || msg == DHCPACK)
return 1;
return 0;
}
/*---------------------------------------------------------------------------*/
void dhcpc_set_callbacks(dhcpc_configured conf, dhcpc_unconfigured unconf)
{
configure_cb = conf;
unconfigure_cb = unconf;
}
/*---------------------------------------------------------------------------*/

View file

@ -1,61 +0,0 @@
/*
* Copyright (c) 2005, Swedish Institute of Computer Science
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#ifndef DHCPC_H_
#define DHCPC_H_
typedef void (*dhcpc_configured)(void);
typedef void (*dhcpc_unconfigured)(void);
struct dhcpc_state {
struct pt pt;
char state;
struct uip_udp_conn *conn;
struct etimer etimer;
uint32_t ticks;
const void *mac_addr;
int mac_len;
uint8_t serverid[4];
uint16_t lease_time[2];
uip_ipaddr_t ipaddr;
uip_ipaddr_t netmask;
uip_ipaddr_t dnsaddr;
uip_ipaddr_t default_router;
};
void dhcpc_init(const void *mac_addr, int mac_len);
void dhcpc_appcall(process_event_t ev, struct net_buf *buf);
int msg_for_dhcpc(struct net_buf *buf);
void dhcpc_set_callbacks(dhcpc_configured conf, dhcpc_unconfigured unconf);
#endif /* DHCPC_H_ */

View file

@ -1,342 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include <string.h>
#include <net/ip_buf.h>
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_TCP_PSOCK
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
#include "contiki/ip/psock.h"
#define STATE_NONE 0
#define STATE_ACKED 1
#define STATE_READ 2
#define STATE_BLOCKED_NEWDATA 3
#define STATE_BLOCKED_CLOSE 4
#define STATE_BLOCKED_SEND 5
#define STATE_DATA_SENT 6
/*
* Return value of the buffering functions that indicates that a
* buffer was not filled by incoming data.
*
*/
#define BUF_NOT_FULL 0
#define BUF_NOT_FOUND 0
/*
* Return value of the buffering functions that indicates that a
* buffer was completely filled by incoming data.
*
*/
#define BUF_FULL 1
/*
* Return value of the buffering functions that indicates that an
* end-marker byte was found.
*
*/
#define BUF_FOUND 2
/*---------------------------------------------------------------------------*/
static void
buf_setup(struct psock_buf *buf,
uint8_t *bufptr, uint16_t bufsize)
{
buf->ptr = bufptr;
buf->left = bufsize;
}
/*---------------------------------------------------------------------------*/
static uint8_t
buf_bufdata(struct psock_buf *buf, uint16_t len,
uint8_t **dataptr, uint16_t *datalen)
{
if(*datalen < buf->left) {
PRINTF("%d: *datalen(%d) < left(%d), copy buf->ptr(%p) <- *dataptr(%p)\n",
__LINE__, *datalen, buf->left, buf->ptr, *dataptr);
memcpy(buf->ptr, *dataptr, *datalen);
buf->ptr += *datalen;
buf->left -= *datalen;
*dataptr += *datalen;
*datalen = 0;
return BUF_NOT_FULL;
} else if(*datalen == buf->left) {
PRINTF("%d: *datalen(%d) == left(%d), copy buf->ptr(%p) <- *dataptr(%p)\n",
__LINE__, *datalen, buf->left, buf->ptr, *dataptr);
memcpy(buf->ptr, *dataptr, *datalen);
buf->ptr += *datalen;
buf->left = 0;
*dataptr += *datalen;
*datalen = 0;
return BUF_FULL;
} else {
PRINTF("%d: *datalen(%d) > left(%d), copy buf->ptr(%p) <- buf->left(%p)\n",
__LINE__, *datalen, buf->left, buf->ptr, buf->left);
memcpy(buf->ptr, *dataptr, buf->left);
buf->ptr += buf->left;
*datalen -= buf->left;
*dataptr += buf->left;
buf->left = 0;
return BUF_FULL;
}
}
/*---------------------------------------------------------------------------*/
static uint8_t
buf_bufto(CC_REGISTER_ARG struct psock_buf *buf, uint8_t endmarker,
CC_REGISTER_ARG uint8_t **dataptr, CC_REGISTER_ARG uint16_t *datalen)
{
uint8_t c;
while(buf->left > 0 && *datalen > 0) {
c = *buf->ptr = **dataptr;
++*dataptr;
++buf->ptr;
--*datalen;
--buf->left;
if(c == endmarker) {
return BUF_FOUND;
}
}
if(*datalen == 0) {
return BUF_NOT_FOUND;
}
return BUF_FULL;
}
/*---------------------------------------------------------------------------*/
static char
data_is_sent_and_acked(CC_REGISTER_ARG struct psock *s)
{
/* If data has previously been sent, and the data has been acked, we
increase the send pointer and call send_data() to send more
data. */
PRINTF("%s: psock %p buf %p data[%p..%p] sendptr %p sendlen %d mss %d\n",
__func__, s, s->net_buf, ip_buf_appdata(s->net_buf),
ip_buf_appdata(s->net_buf) + ip_buf_appdatalen(s->net_buf),
s->sendptr, s->sendlen,
uip_mss(s->net_buf));
if(s->state != STATE_DATA_SENT || uip_rexmit(s->net_buf)) {
if(s->sendlen > uip_mss(s->net_buf)) {
uip_send(s->net_buf, s->sendptr, uip_mss(s->net_buf));
} else {
uip_send(s->net_buf, s->sendptr, s->sendlen);
}
s->state = STATE_DATA_SENT;
return 0;
} else if(s->state == STATE_DATA_SENT && uip_acked(s->net_buf)) {
if(s->sendlen > uip_mss(s->net_buf)) {
s->sendlen -= uip_mss(s->net_buf);
s->sendptr += uip_mss(s->net_buf);
} else {
s->sendptr += s->sendlen;
s->sendlen = 0;
}
s->state = STATE_ACKED;
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_send(CC_REGISTER_ARG struct psock *s, struct net_buf *net_buf))
{
PT_BEGIN(&s->psockpt);
PRINTF("%s: psock %p buf %p len %d\n", __func__, s, net_buf,
ip_buf_appdatalen(net_buf));
/* If there is no data to send, we exit immediately. */
if(ip_buf_appdatalen(net_buf) == 0) {
PT_EXIT(&s->psockpt);
}
/* Save the length of and a pointer to the data that is to be
sent. */
s->sendptr = ip_buf_appdata(net_buf);
s->sendlen = ip_buf_appdatalen(net_buf);
s->net_buf = net_buf;
s->state = STATE_NONE;
/* We loop here until all data is sent. The s->sendlen variable is
updated by the data_sent() function. */
while(s->sendlen > 0) {
/*
* The protothread will wait here until all data has been
* acknowledged and sent (data_is_acked_and_send() returns 1).
*/
PT_WAIT_UNTIL(&s->psockpt, data_is_sent_and_acked(s));
}
s->state = STATE_NONE;
PT_END(&s->psockpt);
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_generator_send(CC_REGISTER_ARG struct psock *s,
unsigned short (*generate)(void *), void *arg))
{
PT_BEGIN(&s->psockpt);
/* Ensure that there is a generator function to call. */
if(generate == NULL) {
PT_EXIT(&s->psockpt);
}
s->state = STATE_NONE;
do {
/* Call the generator function to generate the data in the
uip_appdata buffer. */
s->sendlen = generate(arg);
s->sendptr = uip_appdata(s->net_buf);
if(s->sendlen > uip_mss(s->net_buf)) {
uip_send(s->net_buf, s->sendptr, uip_mss(s->net_buf));
} else {
uip_send(s->net_buf, s->sendptr, s->sendlen);
}
s->state = STATE_DATA_SENT;
/* Wait until all data is sent and acknowledged. */
// if (!s->sendlen) break; //useful debugging aid
PT_YIELD_UNTIL(&s->psockpt, uip_acked(s->net_buf) || \
uip_rexmit(s->net_buf));
} while(!uip_acked(s->net_buf));
s->state = STATE_NONE;
PT_END(&s->psockpt);
}
/*---------------------------------------------------------------------------*/
uint16_t
psock_datalen(struct psock *psock)
{
return psock->bufsize - psock->buf.left;
}
/*---------------------------------------------------------------------------*/
char
psock_newdata(struct psock *s)
{
if(s->readlen > 0) {
/* There is data in the uip_appdata buffer that has not yet been
read with the PSOCK_READ functions. */
return 1;
} else if(s->state == STATE_READ) {
/* All data in uip_appdata buffer already consumed. */
s->state = STATE_BLOCKED_NEWDATA;
return 0;
} else if(uip_newdata(s->net_buf)) {
/* There is new data that has not been consumed. */
return 1;
} else {
/* There is no new data. */
return 0;
}
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_readto(CC_REGISTER_ARG struct psock *psock, unsigned char c))
{
PT_BEGIN(&psock->psockpt);
buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
/* XXX: Should add buf_checkmarker() before do{} loop, if
incoming data has been handled while waiting for a write. */
do {
if(psock->readlen == 0) {
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
psock->state = STATE_READ;
psock->readptr = (uint8_t *)uip_appdata(psock->net_buf);
psock->readlen = uip_datalen(psock->net_buf);
}
} while(buf_bufto(&psock->buf, c,
&psock->readptr,
&psock->readlen) == BUF_NOT_FOUND);
if(psock_datalen(psock) == 0) {
psock->state = STATE_NONE;
PT_RESTART(&psock->psockpt);
}
PT_END(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/
PT_THREAD(psock_readbuf_len(CC_REGISTER_ARG struct psock *psock, uint16_t len))
{
PT_BEGIN(&psock->psockpt);
buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
/* XXX: Should add buf_checkmarker() before do{} loop, if
incoming data has been handled while waiting for a write. */
/* read len bytes or to end of data */
do {
if(psock->readlen == 0) {
PT_WAIT_UNTIL(&psock->psockpt, psock_newdata(psock));
psock->state = STATE_READ;
psock->readptr = (uint8_t *)uip_appdata(psock->net_buf);
psock->readlen = uip_datalen(psock->net_buf);
}
} while(buf_bufdata(&psock->buf, psock->bufsize,
&psock->readptr, &psock->readlen) == BUF_NOT_FULL &&
psock_datalen(psock) < len);
if(psock_datalen(psock) == 0) {
psock->state = STATE_NONE;
PT_RESTART(&psock->psockpt);
}
PT_END(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/
void
psock_init(CC_REGISTER_ARG struct psock *psock, struct net_buf *net_buf)
{
psock->state = STATE_NONE;
psock->readlen = 0;
psock->bufptr = ip_buf_appdata(net_buf);
psock->bufsize = ip_buf_appdatalen(net_buf);
psock->net_buf = net_buf;
buf_setup(&psock->buf, psock->bufptr, psock->bufsize);
PT_INIT(&psock->pt);
PT_INIT(&psock->psockpt);
}
/*---------------------------------------------------------------------------*/

View file

@ -1,400 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup psock Protosockets library
* @{
*
* The protosocket library provides an interface to the uIP stack that is
* similar to the traditional BSD socket interface. Unlike programs
* written for the ordinary uIP event-driven interface, programs
* written with the protosocket library are executed in a sequential
* fashion and does not have to be implemented as explicit state
* machines.
*
* Protosockets only work with TCP connections.
*
* The protosocket library uses \ref pt protothreads to provide
* sequential control flow. This makes the protosockets lightweight in
* terms of memory, but also means that protosockets inherits the
* functional limitations of protothreads. Each protosocket lives only
* within a single function block. Automatic variables (stack
* variables) are not necessarily retained across a protosocket
* library function call.
*
* \note Because the protosocket library uses protothreads, local variables
* will not always be saved across a call to a protosocket library
* function. It is therefore advised that local variables are used
* with extreme care.
*
* The protosocket library provides functions for sending data without
* having to deal with retransmissions and acknowledgements, as well
* as functions for reading data without having to deal with data
* being split across more than one TCP segment.
*
* Because each protosocket runs as a protothread, the protosocket has to be
* started with a call to PSOCK_BEGIN() at the start of the function
* in which the protosocket is used. Similarly, the protosocket protothread can
* be terminated by a call to PSOCK_EXIT().
*
*/
/**
* \file
* Protosocket library header file
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef PSOCK_H_
#define PSOCK_H_
#include "contiki.h"
#include "contiki-lib.h"
#include "contiki-net.h"
/*
* The structure that holds the state of a buffer.
*
* This structure holds the state of a uIP buffer. The structure has
* no user-visible elements, but is used through the functions
* provided by the library.
*
*/
struct psock_buf {
uint8_t *ptr;
unsigned short left;
};
/**
* The representation of a protosocket.
*
* The protosocket structrure is an opaque structure with no user-visible
* elements.
*/
struct psock {
struct pt pt, psockpt; /* Protothreads - one that's using the psock
functions, and one that runs inside the
psock functions. */
const uint8_t *sendptr; /* Pointer to the next data to be sent. */
uint8_t *readptr; /* Pointer to the next data to be read. */
uint8_t *bufptr; /* Pointer to the buffer used for buffering
incoming data. */
uint16_t sendlen; /* The number of bytes left to be sent. */
uint16_t readlen; /* The number of bytes left to be read. */
struct psock_buf buf; /* The structure holding the state of the
input buffer. */
unsigned int bufsize; /* The size of the input buffer. */
unsigned char state; /* The state of the protosocket. */
struct net_buf *net_buf; /* contains conn state etc. */
};
void psock_init(struct psock *psock, struct net_buf *net_buf);
/**
* Initialize a protosocket.
*
* This macro initializes a protosocket and must be called before the
* protosocket is used. The initialization also specifies the input buffer
* for the protosocket.
*
* \param psock (struct psock *) A pointer to the protosocket to be
* initialized
*
* \param buffer (struct net_buf *) A Pointer to network buffer to send.
*
* \hideinitializer
*/
#define PSOCK_INIT(psock, net_buf) \
psock_init(psock, net_buf)
/**
* Start the protosocket protothread in a function.
*
* This macro starts the protothread associated with the protosocket and
* must come before other protosocket calls in the function it is used.
*
* \param psock (struct psock *) A pointer to the protosocket to be
* started.
*
* \hideinitializer
*/
#define PSOCK_BEGIN(psock) PT_BEGIN(&((psock)->pt))
PT_THREAD(psock_send(struct psock *psock, struct net_buf *buf));
/**
* Send data.
*
* This macro sends data over a protosocket. The protosocket protothread blocks
* until all data has been sent and is known to have been received by
* the remote end of the TCP connection.
*
* \param psock (struct psock *) A pointer to the protosocket over which
* data is to be sent.
*
* \param buf (struct net_buf *) A pointer to the buffer that is to be sent.
*
* \hideinitializer
*/
#define PSOCK_SEND(psock, buf) \
PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, buf))
/**
* \brief Send a null-terminated string.
* \param psock Pointer to the protosocket.
* \param str The string to be sent.
*
* This function sends a null-terminated string over the
* protosocket.
*
* \hideinitializer
*/
#define PSOCK_SEND_STR(psock, str) \
PT_WAIT_THREAD(&((psock)->pt), psock_send(psock, (uint8_t *)str, strlen(str)))
PT_THREAD(psock_generator_send(struct psock *psock,
unsigned short (*f)(void *), void *arg));
/**
* \brief Generate data with a function and send it
* \param psock Pointer to the protosocket.
* \param generator Pointer to the generator function
* \param arg Argument to the generator function
*
* This function generates data and sends it over the
* protosocket. This can be used to dynamically generate
* data for a transmission, instead of generating the data
* in a buffer beforehand. This function reduces the need for
* buffer memory. The generator function is implemented by
* the application, and a pointer to the function is given
* as an argument with the call to PSOCK_GENERATOR_SEND().
*
* The generator function should place the generated data
* directly in the uip_appdata buffer, and return the
* length of the generated data. The generator function is
* called by the protosocket layer when the data first is
* sent, and once for every retransmission that is needed.
*
* \hideinitializer
*/
#define PSOCK_GENERATOR_SEND(psock, generator, arg) \
PT_WAIT_THREAD(&((psock)->pt), \
psock_generator_send(psock, generator, arg))
/**
* Close a protosocket.
*
* This macro closes a protosocket and can only be called from within the
* protothread in which the protosocket lives.
*
* \param psock (struct psock *) A pointer to the protosocket that is to
* be closed.
*
* \hideinitializer
*/
#define PSOCK_CLOSE(psock) uip_close()
PT_THREAD(psock_readbuf_len(struct psock *psock, uint16_t len));
/**
* Read data until the buffer is full.
*
* This macro will block waiting for data and read the data into the
* input buffer specified with the call to PSOCK_INIT(). Data is read
* until the buffer is full..
*
* \param psock (struct psock *) A pointer to the protosocket from which
* data should be read.
*
* \hideinitializer
*/
#define PSOCK_READBUF(psock) \
PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, 1))
/**
* Read data until at least len bytes have been read.
*
* This macro will block waiting for data and read the data into the
* input buffer specified with the call to PSOCK_INIT(). Data is read
* until the buffer is full or len bytes have been read.
*
* \param psock (struct psock *) A pointer to the protosocket from which
* data should be read.
* \param len (uint16_t) The minimum number of bytes to read.
*
* \hideinitializer
*/
#define PSOCK_READBUF_LEN(psock, len) \
PT_WAIT_THREAD(&((psock)->pt), psock_readbuf_len(psock, len))
PT_THREAD(psock_readto(struct psock *psock, unsigned char c));
/**
* Read data up to a specified character.
*
* This macro will block waiting for data and read the data into the
* input buffer specified with the call to PSOCK_INIT(). Data is only
* read until the specified character appears in the data stream.
*
* \param psock (struct psock *) A pointer to the protosocket from which
* data should be read.
*
* \param c (char) The character at which to stop reading.
*
* \hideinitializer
*/
#define PSOCK_READTO(psock, c) \
PT_WAIT_THREAD(&((psock)->pt), psock_readto(psock, c))
/**
* The length of the data that was previously read.
*
* This macro returns the length of the data that was previously read
* using PSOCK_READTO() or PSOCK_READ().
*
* \param psock (struct psock *) A pointer to the protosocket holding the data.
*
* \hideinitializer
*/
#define PSOCK_DATALEN(psock) psock_datalen(psock)
uint16_t psock_datalen(struct psock *psock);
/**
* Exit the protosocket's protothread.
*
* This macro terminates the protothread of the protosocket and should
* almost always be used in conjunction with PSOCK_CLOSE().
*
* \sa PSOCK_CLOSE_EXIT()
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_EXIT(psock) PT_EXIT(&((psock)->pt))
/**
* Close a protosocket and exit the protosocket's protothread.
*
* This macro closes a protosocket and exits the protosocket's protothread.
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_CLOSE_EXIT(psock) \
do { \
PSOCK_CLOSE(psock); \
PSOCK_EXIT(psock); \
} while(0)
/**
* Declare the end of a protosocket's protothread.
*
* This macro is used for declaring that the protosocket's protothread
* ends. It must always be used together with a matching PSOCK_BEGIN()
* macro.
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_END(psock) PT_END(&((psock)->pt))
char psock_newdata(struct psock *s);
/**
* Check if new data has arrived on a protosocket.
*
* This macro is used in conjunction with the PSOCK_WAIT_UNTIL()
* macro to check if data has arrived on a protosocket.
*
* \param psock (struct psock *) A pointer to the protosocket.
*
* \hideinitializer
*/
#define PSOCK_NEWDATA(psock) psock_newdata(psock)
/**
* Wait until a condition is true.
*
* This macro blocks the protothread until the specified condition is
* true. The macro PSOCK_NEWDATA() can be used to check if new data
* arrives when the protosocket is waiting.
*
* Typically, this macro is used as follows:
*
\code
PT_THREAD(thread(struct psock *s, struct timer *t))
{
PSOCK_BEGIN(s);
PSOCK_WAIT_UNTIL(s, PSOCK_NEWDATA(s) || timer_expired(t));
if(PSOCK_NEWDATA(s)) {
PSOCK_READTO(s, '\n');
} else {
handle_timed_out(s);
}
PSOCK_END(s);
}
\endcode
*
* \param psock (struct psock *) A pointer to the protosocket.
* \param condition The condition to wait for.
*
* \hideinitializer
*/
#define PSOCK_WAIT_UNTIL(psock, condition) \
PT_WAIT_UNTIL(&((psock)->pt), (condition));
#define PSOCK_WAIT_THREAD(psock, condition) \
PT_WAIT_THREAD(&((psock)->pt), (condition))
#endif /* PSOCK_H_ */
/** @} */
/** @} */

View file

@ -1,221 +0,0 @@
/*
* Copyright (c) 2011, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Code for the simple-udp module.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
/**
* \addtogroup simple-udp
* @{
*/
#include <net/ip_buf.h>
#include "contiki-net.h"
#include "contiki/ip/simple-udp.h"
#include <string.h>
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_SIMPLE_UDP
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
#if UIP_LOGGING
#include <stdio.h>
void uip_log(char *msg);
#define UIP_LOG(m) uip_log(m)
#else
#define UIP_LOG(m)
#endif
PROCESS(simple_udp_process, "Simple UDP process");
static uint8_t started = 0;
#if 0
/* Moved to net_buf */
static uint8_t databuffer[UIP_BUFSIZE];
#endif
#define UIP_IP_BUF(buf) ((struct uip_udpip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
/*---------------------------------------------------------------------------*/
static void
init_simple_udp(void)
{
if(started == 0) {
process_start(&simple_udp_process, NULL, NULL);
started = 1;
}
}
/*---------------------------------------------------------------------------*/
int
simple_udp_send(struct net_buf *buf, struct simple_udp_connection *c,
const void *data, uint16_t datalen)
{
if(c->udp_conn != NULL) {
return uip_udp_packet_sendto(buf, c->udp_conn, data, datalen,
&c->remote_addr, UIP_HTONS(c->remote_port));
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
simple_udp_sendto(struct net_buf *buf, struct simple_udp_connection *c,
const void *data, uint16_t datalen,
const uip_ipaddr_t *to)
{
if(c->udp_conn != NULL) {
return uip_udp_packet_sendto(buf, c->udp_conn, data, datalen,
to, UIP_HTONS(c->remote_port));
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
simple_udp_sendto_port(struct net_buf *buf, struct simple_udp_connection *c,
const void *data, uint16_t datalen,
const uip_ipaddr_t *to,
uint16_t port)
{
if(c->udp_conn != NULL) {
return uip_udp_packet_sendto(buf, c->udp_conn, data, datalen,
to, UIP_HTONS(port));
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
simple_udp_register(struct simple_udp_connection *c,
uint16_t local_port,
uip_ipaddr_t *remote_addr,
uint16_t remote_port,
simple_udp_callback receive_callback,
void *user_data)
{
init_simple_udp();
c->local_port = local_port;
c->remote_port = remote_port;
if(remote_addr != NULL) {
uip_ipaddr_copy(&c->remote_addr, remote_addr);
}
c->receive_callback = receive_callback;
c->user_data = user_data;
PROCESS_CONTEXT_BEGIN(&simple_udp_process);
c->udp_conn = udp_new(remote_addr, UIP_HTONS(remote_port), c);
if(c->udp_conn != NULL) {
udp_bind(c->udp_conn, UIP_HTONS(local_port));
}
PROCESS_CONTEXT_END();
if(c->udp_conn == NULL) {
return 0;
}
return 1;
}
/*---------------------------------------------------------------------------*/
int
simple_udp_unregister(struct simple_udp_connection *c)
{
if (c) {
c->local_port = 0;
if (c->udp_conn) {
udp_unbind(c->udp_conn);
}
return 0;
}
return 1;
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(simple_udp_process, ev, data, buf, user_data)
{
struct simple_udp_connection *c;
PROCESS_BEGIN();
while(1) {
PROCESS_WAIT_EVENT();
if(ev == tcpip_event) {
/* An appstate pointer is passed to use from the IP stack
through the 'data' pointer. We registered this appstate when
we did the udp_new() call in simple_udp_register() as the
struct simple_udp_connection pointer. So we extract this
pointer and use it when calling the reception callback. */
c = (struct simple_udp_connection *)data;
/* Defensive coding: although the appstate *should* be non-null
here, we make sure to avoid the program crashing on us. */
if(c != NULL) {
/* If we were called because of incoming data, we should call
the reception callback. */
if(uip_newdata(buf)) {
#if 0
/* Copy the data from the uIP data buffer into our own
buffer to avoid the uIP buffer being messed with by the
callee. */
memcpy(databuffer, uip_appdata, uip_datalen());
#endif
/* Call the client process. We use the PROCESS_CONTEXT
mechanism to temporarily switch process context to the
client process. */
if(c->receive_callback != NULL) {
PROCESS_CONTEXT_BEGIN(c->client_process);
PRINTF("simple_udp_process(%p): calling cb %p "
"appdata %p datalen %d\n", buf,
c->receive_callback, uip_appdata(buf),
uip_datalen(buf));
c->receive_callback(c,
&(UIP_IP_BUF(buf)->srcipaddr),
UIP_HTONS(UIP_IP_BUF(buf)->srcport),
&(UIP_IP_BUF(buf)->destipaddr),
UIP_HTONS(UIP_IP_BUF(buf)->destport),
uip_appdata(buf), uip_datalen(buf),
c->user_data, buf);
PROCESS_CONTEXT_END();
}
}
}
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,182 +0,0 @@
/*
* Copyright (c) 2011, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Header file for the simple-udp module.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup simple-udp A simple UDP API
*
* The default Contiki UDP API is difficult to use. The simple-udp
* module provides a significantly simpler API.
*
* @{
*/
#ifndef SIMPLE_UDP_H
#define SIMPLE_UDP_H
#include "contiki/ip/uip.h"
struct simple_udp_connection;
/** Simple UDP Callback function type. */
typedef void (* simple_udp_callback)(struct simple_udp_connection *c,
const uip_ipaddr_t *source_addr,
uint16_t source_port,
const uip_ipaddr_t *dest_addr,
uint16_t dest_port,
const uint8_t *data, uint16_t datalen,
void *user_data,
struct net_buf *buf);
/** Simple UDP connection */
struct simple_udp_connection {
struct simple_udp_connection *next;
uip_ipaddr_t remote_addr;
uint16_t remote_port, local_port;
simple_udp_callback receive_callback;
struct uip_udp_conn *udp_conn;
struct process *client_process;
void *user_data;
};
/**
* \brief Register a UDP connection
* \param c A pointer to a struct simple_udp_connection
* \param local_port The local UDP port in host byte order
* \param remote_addr The remote IP address
* \param remote_port The remote UDP port in host byte order
* \param receive_callback A pointer to a function of to be called for incoming packets
* \retval 0 If no UDP connection could be allocated
* \retval 1 If the connection was successfully allocated
*
* This function registers a UDP connection and attaches a
* callback function to it. The callback function will be
* called for incoming packets. The local UDP port can be
* set to 0 to indicate that an ephemeral UDP port should
* be allocated. The remote IP address can be NULL, to
* indicate that packets from any IP address should be
* accepted.
*
*/
int simple_udp_register(struct simple_udp_connection *c,
uint16_t local_port,
uip_ipaddr_t *remote_addr,
uint16_t remote_port,
simple_udp_callback receive_callback,
void *user_data);
/**
* \brief Unregister a UDP connection
* \param c A pointer to a struct simple_udp_connection
* \retval 0 If UDP connection parameter is invalid
* \retval 1 If the connection was successfully unregistered
*
* This function unregisters a UDP connection.
*/
int simple_udp_unregister(struct simple_udp_connection *c);
/**
* \brief Send a UDP packet
* \param buf Buffer to send
* \param c A pointer to a struct simple_udp_connection
* \param data A pointer to the data to be sent
* \param datalen The length of the data
*
* This function sends a UDP packet. The packet will be
* sent to the IP address and with the UDP ports that were
* specified when the connection was registered with
* simple_udp_register().
*
* \sa simple_udp_sendto()
*/
int simple_udp_send(struct net_buf *buf, struct simple_udp_connection *c,
const void *data, uint16_t datalen);
/**
* \brief Send a UDP packet to a specified IP address
* \param buf Buffer to send
* \param c A pointer to a struct simple_udp_connection
* \param data A pointer to the data to be sent
* \param datalen The length of the data
* \param to The IP address of the receiver
*
* This function sends a UDP packet to a specified IP
* address. The packet will be sent with the UDP ports
* that were specified when the connection was registered
* with simple_udp_register().
*
* \sa simple_udp_send()
*/
int simple_udp_sendto(struct net_buf *buf, struct simple_udp_connection *c,
const void *data, uint16_t datalen,
const uip_ipaddr_t *to);
/**
* \brief Send a UDP packet to a specified IP address and UDP port
* \param buf Buffer to send
* \param c A pointer to a struct simple_udp_connection
* \param data A pointer to the data to be sent
* \param datalen The length of the data
* \param to The IP address of the receiver
* \param to_port The UDP port of the receiver, in host byte order
*
* This function sends a UDP packet to a specified IP
* address and UDP port. The packet will be sent with the
* UDP ports that were specified when the connection was
* registered with simple_udp_register().
*
* \sa simple_udp_sendto()
*/
int simple_udp_sendto_port(struct net_buf *buf, struct simple_udp_connection *c,
const void *data, uint16_t datalen,
const uip_ipaddr_t *to, uint16_t to_port);
void simple_udp_init(void);
PROCESS_NAME(simple_udp_process);
#endif /* SIMPLE_UDP_H */
/** @} */
/** @} */

View file

@ -1,956 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*/
/**
* \file
* Code for tunnelling uIP packets over the Rime mesh routing module
*
* \author Adam Dunkels <adam@sics.se>\author
* \author Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code)
* \author Julien Abeille <jabeille@cisco.com> (IPv6 related code)
*/
#include <net/ip_buf.h>
#include "contiki-net.h"
#include "contiki/ip/uip-split.h"
#include "contiki/ip/uip-packetqueue.h"
#if NETSTACK_CONF_WITH_IPV6
#include "contiki/ipv6/uip-nd6.h"
#include "contiki/ipv6/uip-ds6.h"
#endif
#include <string.h>
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_RECV_SEND
#define TCPIP_CONF_ANNOTATE_TRANSMISSIONS 1
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
#ifdef CONFIG_DHCP
#include "contiki/ip/dhcpc.h"
#endif
#if UIP_LOGGING
#include <stdio.h>
void uip_log(char *msg);
#define UIP_LOG(m) uip_log(m)
#else
#define UIP_LOG(m)
#endif
#define UIP_ICMP_BUF(buf) ((struct uip_icmp_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN + uip_ext_len(buf)])
#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
#define UIP_TCP_BUF(buf) ((struct uip_tcpip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
#ifdef UIP_FALLBACK_INTERFACE
extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE;
#endif
#if UIP_CONF_IPV6_RPL
#include "rpl/rpl.h"
#endif
process_event_t tcpip_event;
#if UIP_CONF_ICMP6
process_event_t tcpip_icmp6_event;
#endif /* UIP_CONF_ICMP6 */
/* Periodic check of active connections. */
static struct etimer periodic;
#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_REASSEMBLY
/* Timer for reassembly. */
extern struct etimer uip_reass_timer;
#endif
#if UIP_TCP
/**
* \internal Structure for holding a TCP port and a process ID.
*/
struct listenport {
uint16_t port;
struct process *p;
};
static struct internal_state {
struct listenport listenports[UIP_LISTENPORTS];
struct process *p;
} s;
#endif
enum {
TCP_POLL,
UDP_POLL,
PACKET_INPUT
};
/* Called on IP packet output. */
static uint8_t (* outputfunc)(struct net_buf *buf, const uip_lladdr_t *a);
uint8_t
tcpip_output(struct net_buf *buf, const uip_lladdr_t *a)
{
if(outputfunc != NULL) {
return outputfunc(buf, a);
}
UIP_LOG("tcpip_output: Use tcpip_set_outputfunc() to set an output function");
return 0;
}
void
tcpip_set_outputfunc(uint8_t (*f)(struct net_buf *buf, const uip_lladdr_t *))
{
outputfunc = f;
}
#if UIP_CONF_IP_FORWARD
unsigned char tcpip_is_forwarding; /* Forwarding right now? */
#endif /* UIP_CONF_IP_FORWARD */
struct net_buf;
PROCESS(tcpip_process, "TCP/IP stack");
/*---------------------------------------------------------------------------*/
#if UIP_TCP || UIP_CONF_IP_FORWARD
static void
start_periodic_tcp_timer(void)
{
if(etimer_expired(&periodic)) {
etimer_restart(&periodic);
}
}
#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */
/*---------------------------------------------------------------------------*/
static void
check_for_tcp_syn(struct net_buf *buf)
{
#if UIP_TCP || UIP_CONF_IP_FORWARD
/* This is a hack that is needed to start the periodic TCP timer if
an incoming packet contains a SYN: since uIP does not inform the
application if a SYN arrives, we have no other way of starting
this timer. This function is called for every incoming IP packet
to check for such SYNs. */
#define TCP_SYN 0x02
if(UIP_IP_BUF(buf)->proto == UIP_PROTO_TCP &&
(UIP_TCP_BUF(buf)->flags & TCP_SYN) == TCP_SYN) {
start_periodic_tcp_timer();
}
#endif /* UIP_TCP || UIP_CONF_IP_FORWARD */
}
/*---------------------------------------------------------------------------*/
static uint8_t
packet_input(struct net_buf *buf)
{
uint8_t ret = 0;
#if UIP_CONF_IP_FORWARD
if(uip_len > 0) {
tcpip_is_forwarding = 1;
if(uip_fw_forward() == UIP_FW_LOCAL) {
tcpip_is_forwarding = 0;
check_for_tcp_syn();
uip_input();
if(uip_len > 0) {
#if UIP_CONF_TCP_SPLIT
uip_split_output();
#else /* UIP_CONF_TCP_SPLIT */
#if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output();
#else
PRINTF("tcpip packet_input forward output len %d\n", uip_len);
tcpip_output();
#endif
#endif /* UIP_CONF_TCP_SPLIT */
}
}
tcpip_is_forwarding = 0;
}
#else /* UIP_CONF_IP_FORWARD */
if(uip_len(buf) > 0) {
check_for_tcp_syn(buf);
ret = uip_input(buf);
if(ret && uip_len(buf) > 0) {
#if UIP_CONF_TCP_SPLIT
uip_split_output(buf);
#else /* UIP_CONF_TCP_SPLIT */
#if NETSTACK_CONF_WITH_IPV6
PRINTF("tcpip packet_input output len %d\n", uip_len(buf));
ret = tcpip_ipv6_output(buf);
#else
PRINTF("tcpip packet_input output len %d\n", uip_len(buf));
ret = tcpip_output(buf, NULL);
#endif
#endif /* UIP_CONF_TCP_SPLIT */
}
}
#endif /* UIP_CONF_IP_FORWARD */
return ret;
}
/*---------------------------------------------------------------------------*/
#if UIP_TCP
#if UIP_ACTIVE_OPEN
struct uip_conn *
tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate,
struct process *process)
{
struct uip_conn *c;
c = uip_connect(ripaddr, port);
if(c == NULL) {
return NULL;
}
c->appstate.p = process;
c->appstate.state = appstate;
tcpip_poll_tcp(c);
return c;
}
#endif /* UIP_ACTIVE_OPEN */
/*---------------------------------------------------------------------------*/
void
tcp_unlisten(uint16_t port, struct process *handler)
{
static unsigned char i;
struct listenport *l;
l = s.listenports;
for(i = 0; i < UIP_LISTENPORTS; ++i) {
if(l->port == port &&
l->p == handler) {
l->port = 0;
uip_unlisten(port);
break;
}
++l;
}
}
/*---------------------------------------------------------------------------*/
void
tcp_listen(uint16_t port, struct process *handler)
{
static unsigned char i;
struct listenport *l;
l = s.listenports;
for(i = 0; i < UIP_LISTENPORTS; ++i) {
if(l->port == 0) {
l->port = port;
l->p = handler;
uip_listen(port);
break;
}
++l;
}
}
/*---------------------------------------------------------------------------*/
void
tcp_attach(struct uip_conn *conn,
void *appstate)
{
uip_tcp_appstate_t *s;
s = &conn->appstate;
s->p = PROCESS_CURRENT();
s->state = appstate;
}
#endif /* UIP_TCP */
/*---------------------------------------------------------------------------*/
#if UIP_UDP
void
udp_attach(struct uip_udp_conn *conn,
void *appstate)
{
uip_udp_appstate_t *s;
s = &conn->appstate;
s->p = PROCESS_CURRENT();
s->state = appstate;
}
/*---------------------------------------------------------------------------*/
struct uip_udp_conn *
udp_new(const uip_ipaddr_t *ripaddr, uint16_t port, void *appstate)
{
struct uip_udp_conn *c;
uip_udp_appstate_t *s;
c = uip_udp_new(ripaddr, port);
if(c == NULL) {
return NULL;
}
s = &c->appstate;
s->p = PROCESS_CURRENT();
s->state = appstate;
return c;
}
/*---------------------------------------------------------------------------*/
struct uip_udp_conn *
udp_broadcast_new(uint16_t port, void *appstate)
{
uip_ipaddr_t addr;
struct uip_udp_conn *conn;
#if NETSTACK_CONF_WITH_IPV6
uip_create_linklocal_allnodes_mcast(&addr);
#else
uip_ipaddr(&addr, 255,255,255,255);
#endif /* NETSTACK_CONF_WITH_IPV6 */
conn = udp_new(&addr, port, appstate);
if(conn != NULL) {
udp_bind(conn, port);
}
return conn;
}
#endif /* UIP_UDP */
/*---------------------------------------------------------------------------*/
#if UIP_CONF_ICMP6
uint8_t
icmp6_new(void *appstate) {
if(uip_icmp6_conns.appstate.p == PROCESS_NONE) {
uip_icmp6_conns.appstate.p = PROCESS_CURRENT();
uip_icmp6_conns.appstate.state = appstate;
return 0;
}
return 1;
}
void
tcpip_icmp6_call(uint8_t type)
{
if(uip_icmp6_conns.appstate.p != PROCESS_NONE) {
/* XXX: This is a hack that needs to be updated. Passing a pointer (&type)
like this only works with process_post_synch. */
process_post_synch(uip_icmp6_conns.appstate.p, tcpip_icmp6_event, &type,
NULL);
}
return;
}
#endif /* UIP_CONF_ICMP6 */
/*---------------------------------------------------------------------------*/
static void
eventhandler(process_event_t ev, process_data_t data, struct net_buf *buf)
{
#if UIP_TCP
static unsigned char i;
register struct listenport *l;
#endif /*UIP_TCP*/
struct process *p;
switch(ev) {
case PROCESS_EVENT_EXITED:
/* This is the event we get if a process has exited. We go through
the TCP/IP tables to see if this process had any open
connections or listening TCP ports. If so, we'll close those
connections. */
p = (struct process *)data;
#if UIP_TCP
l = s.listenports;
for(i = 0; i < UIP_LISTENPORTS; ++i) {
if(l->p == p) {
uip_unlisten(l->port);
l->port = 0;
l->p = PROCESS_NONE;
}
++l;
}
{
struct uip_conn *cptr;
for(cptr = &uip_conns[0]; cptr < &uip_conns[UIP_CONNS]; ++cptr) {
if(cptr->appstate.p == p) {
cptr->appstate.p = PROCESS_NONE;
cptr->tcpstateflags = UIP_CLOSED;
}
}
}
#endif /* UIP_TCP */
#if UIP_UDP
{
struct uip_udp_conn *cptr;
for(cptr = &uip_udp_conns[0];
cptr < &uip_udp_conns[UIP_UDP_CONNS]; ++cptr) {
if(cptr->appstate.p == p) {
cptr->lport = 0;
}
}
}
#endif /* UIP_UDP */
break;
case PROCESS_EVENT_TIMER:
/* We get this event if one of our timers have expired. */
{
if(!buf)
break;
/* Check the clock to see if we should call the periodic uIP
processing. */
if(data == &periodic &&
!etimer_is_triggered(&periodic)) {
etimer_set_triggered(&periodic);
#if UIP_TCP
for(i = 0; i < UIP_CONNS; ++i) {
if(uip_conn_active(i)) {
/* Only restart the timer if there are active
connections. */
etimer_restart(&periodic);
uip_periodic(buf, i);
#if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output(buf);
#else
if(uip_len(buf) > 0) {
PRINTF("tcpip_output from periodic len %d\n", uip_len(buf));
tcpip_output(buf, NULL);
PRINTF("tcpip_output after periodic len %d\n", uip_len(buf));
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
}
#endif /* UIP_TCP */
#if UIP_CONF_IP_FORWARD
uip_fw_periodic();
#endif /* UIP_CONF_IP_FORWARD */
}
#if NETSTACK_CONF_WITH_IPV6
#if UIP_CONF_IPV6_REASSEMBLY
/*
* check the timer for reassembly
*/
if(data == &uip_reass_timer &&
!etimer_is_triggered(&uip_reass_timer)) {
etimer_set_triggered(&uip_reass_timer);
uip_reass_over();
tcpip_ipv6_output(buf);
}
#endif /* UIP_CONF_IPV6_REASSEMBLY */
/*
* check the different timers for neighbor discovery and
* stateless autoconfiguration
*/
/*if(data == &uip_ds6_timer_periodic &&
etimer_expired(&uip_ds6_timer_periodic)) {
uip_ds6_periodic();
tcpip_ipv6_output();
}*/
#if !UIP_CONF_ROUTER
if(data == &uip_ds6_timer_rs &&
!etimer_is_triggered(&uip_ds6_timer_rs)) {
etimer_set_triggered(&uip_ds6_timer_rs);
uip_ds6_send_rs(buf);
tcpip_ipv6_output(buf);
}
#endif /* !UIP_CONF_ROUTER */
if(data == &uip_ds6_timer_periodic &&
!etimer_is_triggered(&uip_ds6_timer_periodic)) {
etimer_set_triggered(&uip_ds6_timer_periodic);
uip_ds6_periodic(buf);
tcpip_ipv6_output(buf);
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
break;
#if UIP_TCP
case TCP_POLL:
if(data != NULL) {
uint8_t ret = 0;
uip_poll_conn(buf, data);
#if NETSTACK_CONF_WITH_IPV6
if (!uip_len(buf) && buf->len) {
/* Make sure we are sending something if needed. */
uip_len(buf) = buf->len;
}
ret = tcpip_ipv6_output(buf);
#else /* NETSTACK_CONF_WITH_IPV6 */
if(uip_len(buf) > 0) {
PRINTF("tcpip_output from tcp poll len %d\n", uip_len(buf));
ret = tcpip_output(buf, NULL);
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
/* Start the periodic polling, if it isn't already active. */
start_periodic_tcp_timer();
if (!ret) {
/* Packet was not sent properly */
ip_buf_unref(buf);
}
}
break;
#endif /* UIP_TCP */
#if UIP_UDP
case UDP_POLL:
if(data != NULL) {
uip_udp_periodic_conn(buf, data);
#if NETSTACK_CONF_WITH_IPV6
tcpip_ipv6_output(buf);
#else
if(uip_len(buf) > 0) {
tcpip_output(buf, NULL);
}
#endif /* UIP_UDP */
}
break;
#endif /* UIP_UDP */
case PACKET_INPUT:
if (!packet_input(buf)) {
PRINTF("Packet %p was not sent and must be discarded by caller\n", buf);
} else {
PRINTF("Packet %p was sent ok\n", buf);
}
break;
};
}
/*---------------------------------------------------------------------------*/
uint8_t
tcpip_input(struct net_buf *buf)
{
process_post_synch(&tcpip_process, PACKET_INPUT, NULL, buf);
if (uip_len(buf) == 0) {
/* This indicates that there was a parsing/other error
* in packet.
*/
return 0;
}
uip_len(buf) = 0;
#if NETSTACK_CONF_WITH_IPV6
uip_ext_len(buf) = 0;
#endif /*NETSTACK_CONF_WITH_IPV6*/
return 1;
}
/*---------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV6
uint8_t
tcpip_ipv6_output(struct net_buf *buf)
{
uip_ds6_nbr_t *nbr = NULL;
uip_ipaddr_t *nexthop;
uint8_t ret = 0; /* return value 0 == failed, 1 == ok */
if(!buf || uip_len(buf) == 0) {
return 0;
}
PRINTF("%s(): buf %p len %d\n", __FUNCTION__, buf, uip_len(buf));
if(uip_len(buf) > UIP_LINK_MTU) {
UIP_LOG("tcpip_ipv6_output: Packet too big");
uip_len(buf) = 0;
uip_ext_len(buf) = 0;
return 0;
}
if(uip_is_addr_unspecified(&UIP_IP_BUF(buf)->destipaddr)){
UIP_LOG("tcpip_ipv6_output: Destination address unspecified");
uip_len(buf) = 0;
uip_ext_len(buf) = 0;
return 0;
}
if(!uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)) {
/* Next hop determination */
nbr = NULL;
/* We first check if the destination address is on our immediate
link. If so, we simply use the destination address as our
nexthop address. */
if(uip_ds6_is_addr_onlink(&UIP_IP_BUF(buf)->destipaddr)){
nexthop = &UIP_IP_BUF(buf)->destipaddr;
} else {
uip_ds6_route_t *route;
/* Check if we have a route to the destination address. */
route = uip_ds6_route_lookup(&UIP_IP_BUF(buf)->destipaddr);
/* No route was found - we send to the default route instead. */
if(route == NULL) {
PRINTF("tcpip_ipv6_output: no route found, using default route\n");
nexthop = uip_ds6_defrt_choose();
if(nexthop == NULL) {
#ifdef UIP_FALLBACK_INTERFACE
PRINTF("FALLBACK: removing ext hdrs & setting proto %d %d\n",
uip_ext_len(buf), *((uint8_t *)UIP_IP_BUF(buf) + 40));
if(uip_ext_len(buf) > 0) {
extern void remove_ext_hdr(void);
uint8_t proto = *((uint8_t *)UIP_IP_BUF(buf) + 40);
remove_ext_hdr();
/* This should be copied from the ext header... */
UIP_IP_BUF(buf)->proto = proto;
}
UIP_FALLBACK_INTERFACE.output();
#else
PRINTF("tcpip_ipv6_output: Destination off-link but no route\n");
#endif /* !UIP_FALLBACK_INTERFACE */
uip_len(buf) = 0;
uip_ext_len(buf) = 0;
return 0;
}
} else {
/* A route was found, so we look up the nexthop neighbor for
the route. */
nexthop = uip_ds6_route_nexthop(route);
/* If the nexthop is dead, for example because the neighbor
never responded to link-layer acks, we drop its route. */
if(nexthop == NULL) {
#if UIP_CONF_IPV6_RPL
/* If we are running RPL, and if we are the root of the
network, we'll trigger a global repair berfore we remove
the route. */
rpl_dag_t *dag;
rpl_instance_t *instance;
dag = (rpl_dag_t *)route->state.dag;
if(dag != NULL) {
instance = dag->instance;
rpl_repair_root(instance->instance_id);
}
#endif /* UIP_CONF_IPV6_RPL */
uip_ds6_route_rm(route);
/* We don't have a nexthop to send the packet to, so we drop
it. */
return 0;
}
}
#if TCPIP_CONF_ANNOTATE_TRANSMISSIONS
if(nexthop != NULL) {
static uint8_t annotate_last;
static uint8_t annotate_has_last = 0;
if(annotate_has_last) {
printf("#L %u 0; red\n", annotate_last);
}
printf("#L %u 1; red\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
annotate_last = nexthop->u8[sizeof(uip_ipaddr_t) - 1];
annotate_has_last = 1;
}
#endif /* TCPIP_CONF_ANNOTATE_TRANSMISSIONS */
}
/* End of next hop determination */
#if UIP_CONF_IPV6_RPL
if(rpl_update_header_final(buf, nexthop)) {
uip_len(buf) = 0;
uip_ext_len(buf) = 0;
return 0;
}
#endif /* UIP_CONF_IPV6_RPL */
nbr = uip_ds6_nbr_lookup(nexthop);
if(nbr == NULL) {
#if UIP_ND6_SEND_NA
if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) {
PRINTF("IP packet buf %p len %d discarded because cannot "
"add neighbor\n", buf, uip_len(buf));
uip_len(buf) = 0;
uip_ext_len(buf) = 0;
return 0;
} else {
#if UIP_CONF_IPV6_QUEUE_PKT
/* Copy outgoing pkt in the queuing buffer for later transmit. */
if(uip_packetqueue_alloc(buf, &nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF(buf), uip_len(buf));
uip_packetqueue_set_buflen(&nbr->packethandle, uip_len(buf));
}
#else
PRINTF("IP packet buf %p len %d discarded because NS is "
"being sent\n", buf, uip_len(buf));
#endif
/* RFC4861, 7.2.2:
* "If the source address of the packet prompting the solicitation is the
* same as one of the addresses assigned to the outgoing interface, that
* address SHOULD be placed in the IP Source Address of the outgoing
* solicitation. Otherwise, any one of the addresses assigned to the
* interface should be used."*/
if(uip_ds6_is_my_addr(&UIP_IP_BUF(buf)->srcipaddr)){
uip_nd6_ns_output(NULL, &UIP_IP_BUF(buf)->srcipaddr, NULL, &nbr->ipaddr);
} else {
uip_nd6_ns_output(NULL, NULL, NULL, &nbr->ipaddr);
}
stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
nbr->nscount = 1;
}
uip_len(buf) = 0;
uip_ext_len(buf) = 0;
return 0; /* packet was discarded */
#else /* UIP_ND6_SEND_NA */
int uiplen = uip_len(buf);
int extlen = uip_ext_len(buf);
/* Neighbor discovery is not there. Just try to send the packet. */
ret = tcpip_output(buf, NULL);
if (ret) {
/* We must set the length back as these were overwritten
* by other part of the stack. If we do not do this then
* there will be a double memory free in the caller.
* FIXME properly later!
*/
uip_len(buf) = uiplen;
uip_ext_len(buf) = extlen;
} else {
uip_len(buf) = 0;
uip_ext_len(buf) = 0;
}
return ret;
#endif /* UIP_ND6_SEND_NA */
} else {
#if UIP_ND6_SEND_NA
if(nbr->state == NBR_INCOMPLETE) {
PRINTF("tcpip_ipv6_output: nbr cache entry incomplete\n");
#if UIP_CONF_IPV6_QUEUE_PKT
/* Copy outgoing pkt in the queuing buffer for later transmit and set
the destination nbr to nbr. */
if(uip_packetqueue_alloc(buf, &nbr->packethandle, UIP_DS6_NBR_PACKET_LIFETIME) != NULL) {
memcpy(uip_packetqueue_buf(&nbr->packethandle), UIP_IP_BUF(buf), uip_len(buf));
uip_packetqueue_set_buflen(&nbr->packethandle, uip_len(buf));
} else {
PRINTF("IP packet buf %p len %d discarded because no space "
"in the queue\n", buf, uip_len(buf));
}
#else
PRINTF("IP packet buf %p len %d discarded because neighbor info is "
"not yet received\n", buf, uip_len(buf));
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
uip_len(buf) = 0;
uip_ext_len(buf) = 0;
return 0;
}
/* Send in parallel if we are running NUD (nbc state is either STALE,
DELAY, or PROBE). See RFC 4861, section 7.3.3 on node behavior. */
if(nbr->state == NBR_STALE) {
nbr->state = NBR_DELAY;
stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
nbr->nscount = 0;
PRINTF("tcpip_ipv6_output: nbr cache entry stale moving to delay\n");
}
#endif /* UIP_ND6_SEND_NA */
ret = tcpip_output(buf, uip_ds6_nbr_get_ll(nbr));
#if UIP_CONF_IPV6_QUEUE_PKT
/*
* Send the queued packets from here, may not be 100% perfect though.
* This happens in a few cases, for example when instead of receiving a
* NA after sendiong a NS, you receive a NS with SLLAO: the entry moves
* to STALE, and you must both send a NA and the queued packet.
*/
if(uip_packetqueue_buflen(&nbr->packethandle) != 0) {
bool allocated_here = false;
if (ret != 0) {
/* The IP buf was freed because the send succeed so we need to
* allocate a new one here.
*/
buf = ip_buf_get_reserve_tx(0);
if (!buf) {
PRINTF("%s(): Cannot send queued packet, no net buffers\n", __FUNCTION__);
uip_packetqueue_free(&nbr->packethandle);
goto no_buf;
}
allocated_here = true;
}
uip_len(buf) = buf->len = uip_packetqueue_buflen(&nbr->packethandle);
memcpy(UIP_IP_BUF(buf), uip_packetqueue_buf(&nbr->packethandle),
uip_len(buf));
uip_packetqueue_free(&nbr->packethandle);
ret = tcpip_output(buf, uip_ds6_nbr_get_ll(nbr));
if (allocated_here && !ret) {
/* There was a sending error and the buffer was not released.
* We cannot return the buffer to upper layers so just release
* it here.
*/
ip_buf_unref(buf);
ret = 1; /* This will tell caller that buf is released. */
}
}
no_buf:
#endif /*UIP_CONF_IPV6_QUEUE_PKT*/
if (ret == 0) {
uip_len(buf) = 0;
uip_ext_len(buf) = 0;
}
return ret;
}
return 0; /* discard packet */
}
/* Multicast IP destination address. */
ret = tcpip_output(buf, NULL);
uip_len(buf) = 0;
uip_ext_len(buf) = 0;
return ret;
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
/*---------------------------------------------------------------------------*/
#if UIP_UDP
void
tcpip_poll_udp(struct uip_udp_conn *conn)
{
process_post(&tcpip_process, UDP_POLL, conn);
}
#endif /* UIP_UDP */
/*---------------------------------------------------------------------------*/
#if UIP_TCP
void
tcpip_poll_tcp(struct uip_conn *conn)
{
/* We are sending here the initial SYN */
struct net_buf *buf = ip_buf_get_tx(conn->appstate.state);
uip_set_conn(buf) = conn;
conn->buf = ip_buf_ref(buf);
process_post_synch(&tcpip_process, TCP_POLL, conn, buf);
}
#if UIP_ACTIVE_OPEN
void tcpip_resend_syn(struct uip_conn *conn, struct net_buf *buf)
{
/* The network driver will unref the buf so in order not to loose the
* buffer, we need to ref it here.
*/
ip_buf_ref(buf);
/* We are re-sending here the SYN */
process_post_synch(&tcpip_process, TCP_POLL, conn, buf);
}
#endif /* UIP_ACTIVE_OPEN */
#endif /* UIP_TCP */
/*---------------------------------------------------------------------------*/
void
tcpip_uipcall(struct net_buf *buf)
{
struct tcpip_uipstate *ts;
#if UIP_UDP
if(uip_conn(buf) != NULL) {
ts = &uip_conn(buf)->appstate;
} else {
ts = &uip_udp_conn(buf)->appstate;
}
#else /* UIP_UDP */
ts = &uip_conn(buf)->appstate;
#endif /* UIP_UDP */
#if UIP_TCP
{
static unsigned char i;
struct listenport *l;
/* If this is a connection request for a listening port, we must
mark the connection with the right process ID. */
if(uip_connected(buf)) {
l = &s.listenports[0];
for(i = 0; i < UIP_LISTENPORTS; ++i) {
if(l->port == uip_conn(buf)->lport &&
l->p != PROCESS_NONE) {
ts->p = l->p;
ts->state = NULL;
break;
}
++l;
}
/* Start the periodic polling, if it isn't already active. */
start_periodic_tcp_timer();
}
}
#endif /* UIP_TCP */
#ifdef CONFIG_DHCP
if(msg_for_dhcpc(buf)) {
PRINTF("msg for dhcpc\n");
dhcpc_appcall(tcpip_event, buf);
return;
}
#endif
if(ts->p != NULL) {
process_post_synch(ts->p, tcpip_event, ts->state, buf);
}
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(tcpip_process, ev, data, buf, user_data)
{
PROCESS_BEGIN();
#if UIP_TCP
{
static unsigned char i;
for(i = 0; i < UIP_LISTENPORTS; ++i) {
s.listenports[i].port = 0;
}
s.p = PROCESS_CURRENT();
}
#endif
tcpip_event = process_alloc_event();
#if UIP_CONF_ICMP6
tcpip_icmp6_event = process_alloc_event();
#endif /* UIP_CONF_ICMP6 */
etimer_set(&periodic, CLOCK_SECOND / 2, &tcpip_process);
uip_init();
#ifdef UIP_FALLBACK_INTERFACE
UIP_FALLBACK_INTERFACE.init();
#endif
/* initialize RPL if configured for using RPL */
#if NETSTACK_CONF_WITH_IPV6 && UIP_CONF_IPV6_RPL
rpl_init();
#endif /* UIP_CONF_IPV6_RPL */
while(1) {
PROCESS_YIELD();
eventhandler(ev, data, buf);
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -1,391 +0,0 @@
/*
* Copyright (c) 2004, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
/**
* \file
* Header for the Contiki/uIP interface.
* \author Adam Dunkels <adam@sics.se>
* \author Mathilde Durvy <mdurvy@cisco.com> (IPv6 related code)
* \author Julien Abeille <jabeille@cisco.com> (IPv6 related code)
*/
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup tcpip The Contiki/uIP interface
* @{
*
* TCP/IP support in Contiki is implemented using the uIP TCP/IP
* stack. For sending and receiving data, Contiki uses the functions
* provided by the uIP module, but Contiki adds a set of functions for
* connection management. The connection management functions make
* sure that the uIP TCP/IP connections are connected to the correct
* process.
*
* Contiki also includes an optional protosocket library that provides
* an API similar to the BSD socket API.
*
* \sa \ref uip "The uIP TCP/IP stack"
* \sa \ref psock "Protosockets library"
*
*/
#ifndef TCPIP_H_
#define TCPIP_H_
#include "contiki.h"
#include "contiki/ip/uipaddr.h"
struct uip_conn;
struct tcpip_uipstate {
struct process *p;
void *state;
};
#define UIP_APPCALL(buf) tcpip_uipcall(buf)
#define UIP_UDP_APPCALL(buf) tcpip_uipcall(buf)
#define UIP_ICMP6_APPCALL tcpip_icmp6_call
/*#define UIP_APPSTATE_SIZE sizeof(struct tcpip_uipstate)*/
typedef struct tcpip_uipstate uip_udp_appstate_t;
typedef struct tcpip_uipstate uip_tcp_appstate_t;
typedef struct tcpip_uipstate uip_icmp6_appstate_t;
#include "contiki/ip/uip.h"
void tcpip_uipcall(struct net_buf *buf);
/**
* \name TCP functions
* @{
*/
/**
* Attach a TCP connection to the current process
*
* This function attaches the current process to a TCP
* connection. Each TCP connection must be attached to a process in
* order for the process to be able to receive and send
* data. Additionally, this function can add a pointer with connection
* state to the connection.
*
* \param conn A pointer to the TCP connection.
*
* \param appstate An opaque pointer that will be passed to the
* process whenever an event occurs on the connection.
*
*/
CCIF void tcp_attach(struct uip_conn *conn,
void *appstate);
#define tcp_markconn(conn, appstate) tcp_attach(conn, appstate)
/**
* Open a TCP port.
*
* This function opens a TCP port for listening. When a TCP connection
* request occurs for the port, the process will be sent a tcpip_event
* with the new connection request.
*
* \note Port numbers must always be given in network byte order. The
* functions UIP_HTONS() and uip_htons() can be used to convert port numbers
* from host byte order to network byte order.
*
* \param port The port number in network byte order.
*
*/
CCIF void tcp_listen(uint16_t port, struct process *handler);
/**
* Close a listening TCP port.
*
* This function closes a listening TCP port.
*
* \note Port numbers must always be given in network byte order. The
* functions UIP_HTONS() and uip_htons() can be used to convert port numbers
* from host byte order to network byte order.
*
* \param port The port number in network byte order.
*
*/
CCIF void tcp_unlisten(uint16_t port, struct process *handler);
/**
* Open a TCP connection to the specified IP address and port.
*
* This function opens a TCP connection to the specified port at the
* host specified with an IP address. Additionally, an opaque pointer
* can be attached to the connection. This pointer will be sent
* together with uIP events to the process.
*
* \note The port number must be provided in network byte order so a
* conversion with UIP_HTONS() usually is necessary.
*
* \note This function will only create the connection. The connection
* is not opened directly. uIP will try to open the connection the
* next time the uIP stack is scheduled by Contiki.
*
* \param ripaddr Pointer to the IP address of the remote host.
* \param port Port number in network byte order.
* \param appstate Pointer to application defined data.
*
* \return A pointer to the newly created connection, or NULL if
* memory could not be allocated for the connection.
*
*/
CCIF struct uip_conn *tcp_connect(const uip_ipaddr_t *ripaddr, uint16_t port,
void *appstate, struct process *process);
/**
* Cause a specified TCP connection to be polled.
*
* This function causes uIP to poll the specified TCP connection. The
* function is used when the application has data that is to be sent
* immediately and do not wish to wait for the periodic uIP polling
* mechanism.
*
* \param conn A pointer to the TCP connection that should be polled.
*
*/
void tcpip_poll_tcp(struct uip_conn *conn);
void tcpip_resend_syn(struct uip_conn *conn, struct net_buf *buf);
/** @} */
/**
* \name UDP functions
* @{
*/
struct uip_udp_conn;
/**
* Attach the current process to a UDP connection
*
* This function attaches the current process to a UDP
* connection. Each UDP connection must have a process attached to it
* in order for the process to be able to receive and send data over
* the connection. Additionally, this function can add a pointer with
* connection state to the connection.
*
* \param conn A pointer to the UDP connection.
*
* \param appstate An opaque pointer that will be passed to the
* process whenever an event occurs on the connection.
*
*/
void udp_attach(struct uip_udp_conn *conn,
void *appstate);
#define udp_markconn(conn, appstate) udp_attach(conn, appstate)
/**
* Create a new UDP connection.
*
* This function creates a new UDP connection with the specified
* remote endpoint.
*
* \note The port number must be provided in network byte order so a
* conversion with UIP_HTONS() usually is necessary.
*
* \sa udp_bind()
*
* \param ripaddr Pointer to the IP address of the remote host.
* \param port Port number in network byte order.
* \param appstate Pointer to application defined data.
*
* \return A pointer to the newly created connection, or NULL if
* memory could not be allocated for the connection.
*/
CCIF struct uip_udp_conn *udp_new(const uip_ipaddr_t *ripaddr, uint16_t port,
void *appstate);
/**
* Create a new UDP broadcast connection.
*
* This function creates a new (link-local) broadcast UDP connection
* to a specified port.
*
* \param port Port number in network byte order.
* \param appstate Pointer to application defined data.
*
* \return A pointer to the newly created connection, or NULL if
* memory could not be allocated for the connection.
*/
struct uip_udp_conn *udp_broadcast_new(uint16_t port, void *appstate);
/**
* Bind a UDP connection to a local port.
*
* This function binds a UDP connection to a specified local port.
*
* When a connection is created with udp_new(), it gets a local port
* number assigned automatically. If the application needs to bind the
* connection to a specified local port, this function should be used.
*
* \note The port number must be provided in network byte order so a
* conversion with UIP_HTONS() usually is necessary.
*
* \param conn A pointer to the UDP connection that is to be bound.
* \param port The port number in network byte order to which to bind
* the connection.
*/
#define udp_bind(conn, port) uip_udp_bind(conn, port)
/**
* Unbind a UDP connection.
*
* This function unbinds a UDP connection.
*
* When a connection is created with udp_new(), it gets a local port
* number assigned automatically. If the application needs to unbind the
* connection from local port, this function should be used.
*
* \param conn A pointer to the UDP connection that is to be bound.
*/
#define udp_unbind(conn) uip_udp_remove(conn)
/**
* Cause a specified UDP connection to be polled.
*
* This function causes uIP to poll the specified UDP connection. The
* function is used when the application has data that is to be sent
* immediately and do not wish to wait for the periodic uIP polling
* mechanism.
*
* \param conn A pointer to the UDP connection that should be polled.
*
*/
CCIF void tcpip_poll_udp(struct uip_udp_conn *conn);
/** @} */
/**
* \name ICMPv6 functions
* @{
*/
#if UIP_CONF_ICMP6
/**
* The ICMP6 event.
*
* This event is posted to a process whenever a uIP ICMP event has occurred.
*/
CCIF extern process_event_t tcpip_icmp6_event;
/**
* \brief register an ICMPv6 callback
* \return 0 if success, 1 if failure (one application already registered)
*
* This function just registers a process to be polled when
* an ICMPv6 message is received.
* If no application registers, some ICMPv6 packets will be
* processed by the "kernel" as usual (NS, NA, RS, RA, Echo request),
* others will be dropped.
* If an application registers here, it will be polled with a
* process_post_synch every time an ICMPv6 packet is received.
*/
uint8_t icmp6_new(void *appstate);
/**
* This function is called at reception of an ICMPv6 packet
* If an application registered as an ICMPv6 listener (with
* icmp6_new), it will be called through a process_post_synch()
*/
void tcpip_icmp6_call(uint8_t type);
#endif /*UIP_CONF_ICMP6*/
/** @} */
/**
* The uIP event.
*
* This event is posted to a process whenever a uIP event has occurred.
*/
CCIF extern process_event_t tcpip_event;
/**
* \name TCP/IP packet processing
* @{
*/
/**
* \brief Deliver an incoming packet to the TCP/IP stack
*
* This function is called by network device drivers to
* deliver an incoming packet to the TCP/IP stack. The
* incoming packet must be present in the uip_buf buffer,
* and the length of the packet must be in the global
* uip_len variable. If 0 is returned, then there was
* an error in the packet and it is discarded. The caller
* can then release the net_buf
*/
CCIF uint8_t tcpip_input(struct net_buf *buf);
/**
* \brief Output packet to layer 2
* The eventual parameter is the MAC address of the destination.
*/
uint8_t tcpip_output(struct net_buf *buf, const uip_lladdr_t *);
void tcpip_set_outputfunc(uint8_t (* f)(struct net_buf *buf, const uip_lladdr_t *));
/**
* \brief This function does address resolution and then calls tcpip_output
*/
#if NETSTACK_CONF_WITH_IPV6
uint8_t tcpip_ipv6_output(struct net_buf *buf);
#endif
/**
* \brief Is forwarding generally enabled?
*/
extern unsigned char tcpip_do_forwarding;
/*
* Are we at the moment forwarding the contents of uip_buf[]?
*/
extern unsigned char tcpip_is_forwarding;
#define tcpip_set_forwarding(forwarding) tcpip_do_forwarding = (forwarding)
/** @} */
PROCESS_NAME(tcpip_process);
#endif /* TCPIP_H_ */
/** @} */
/** @} */

View file

@ -1,207 +0,0 @@
/*
* Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <net/ip_buf.h>
#include "contiki-net.h"
#include "udp-socket.h"
#include <string.h>
PROCESS(udp_socket_process, "UDP socket process");
#if 0
/* Moved to net_buf */
static uint8_t buf[UIP_BUFSIZE];
#endif
#define UIP_IP_BUF(buf) ((struct uip_udpip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
/*---------------------------------------------------------------------------*/
static void
init(void)
{
static uint8_t inited = 0;
if(!inited) {
inited = 1;
process_start(&udp_socket_process, NULL, NULL);
}
}
/*---------------------------------------------------------------------------*/
int
udp_socket_register(struct udp_socket *c,
void *ptr,
udp_socket_input_callback_t input_callback)
{
init();
if(c == NULL) {
return -1;
}
c->ptr = ptr;
c->input_callback = input_callback;
c->p = PROCESS_CURRENT();
PROCESS_CONTEXT_BEGIN(&udp_socket_process);
c->udp_conn = udp_new(NULL, 0, c);
PROCESS_CONTEXT_END();
if(c->udp_conn == NULL) {
return -1;
}
return 1;
}
/*---------------------------------------------------------------------------*/
int
udp_socket_close(struct udp_socket *c)
{
if(c == NULL) {
return -1;
}
if(c->udp_conn != NULL) {
uip_udp_remove(c->udp_conn);
return 1;
}
return -1;
}
/*---------------------------------------------------------------------------*/
int
udp_socket_bind(struct udp_socket *c,
uint16_t local_port)
{
if(c == NULL || c->udp_conn == NULL) {
return -1;
}
udp_bind(c->udp_conn, UIP_HTONS(local_port));
return 1;
}
/*---------------------------------------------------------------------------*/
int
udp_socket_connect(struct udp_socket *c,
uip_ipaddr_t *remote_addr,
uint16_t remote_port)
{
if(c == NULL || c->udp_conn == NULL) {
return -1;
}
if(remote_addr != NULL) {
uip_ipaddr_copy(&c->udp_conn->ripaddr, remote_addr);
}
c->udp_conn->rport = UIP_HTONS(remote_port);
return 1;
}
/*---------------------------------------------------------------------------*/
int
udp_socket_send(struct net_buf *buf, struct udp_socket *c,
const void *data, uint16_t datalen)
{
if(c == NULL || c->udp_conn == NULL) {
return -1;
}
uip_udp_packet_send(buf, c->udp_conn, data, datalen);
return datalen;
}
/*---------------------------------------------------------------------------*/
int
udp_socket_sendto(struct net_buf *buf, struct udp_socket *c,
const void *data, uint16_t datalen,
const uip_ipaddr_t *to,
uint16_t port)
{
if(c == NULL || c->udp_conn == NULL) {
return -1;
}
if(c->udp_conn != NULL) {
return uip_udp_packet_sendto(buf, c->udp_conn, data, datalen,
to, UIP_HTONS(port));
}
return -1;
}
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(udp_socket_process, ev, data, buf, user_data)
{
struct udp_socket *c;
PROCESS_BEGIN();
while(1) {
PROCESS_WAIT_EVENT();
if(ev == tcpip_event) {
/* An appstate pointer is passed to use from the IP stack
through the 'data' pointer. We registered this appstate when
we did the udp_new() call in udp_socket_register() as the
struct udp_socket pointer. So we extract this
pointer and use it when calling the reception callback. */
c = (struct udp_socket *)data;
/* Defensive coding: although the appstate *should* be non-null
here, we make sure to avoid the program crashing on us. */
if(c != NULL) {
/* If we were called because of incoming data, we should call
the reception callback. */
if(uip_newdata(buf)) {
/* Copy the data from the uIP data buffer into our own
buffer to avoid the uIP buffer being messed with by the
callee. */
#if 0
/* Note that we cannot do this as the stack is suppose to be
* re-entrant.
*/
memcpy(bad_buf, uip_appdata(buf), uip_datalen(buf));
#endif
/* Call the client process. We use the PROCESS_CONTEXT
mechanism to temporarily switch process context to the
client process. */
if(c->input_callback != NULL) {
PROCESS_CONTEXT_BEGIN(c->p);
c->input_callback(c, c->ptr,
&(UIP_IP_BUF(buf)->srcipaddr),
UIP_HTONS(UIP_IP_BUF(buf)->srcport),
&(UIP_IP_BUF(buf)->destipaddr),
UIP_HTONS(UIP_IP_BUF(buf)->destport),
uip_appdata(buf), uip_datalen(buf));
PROCESS_CONTEXT_END();
}
}
}
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,197 +0,0 @@
/*
* Copyright (c) 2012-2014, Thingsquare, http://www.thingsquare.com/.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef UDP_SOCKET_H
#define UDP_SOCKET_H
#include <net/buf.h>
#include "contiki/ip/uip.h"
struct udp_socket;
/**
* \brief A UDP socket callback function
* \param buf Buffer that received the data
* \param c A pointer to the struct udp_socket that received the data
* \param ptr An opaque pointer that was specified when the UDP socket was registered with udp_socket_register()
* \param source_addr The IP address from which the datagram was sent
* \param source_port The UDP port number, in host byte order, from which the datagram was sent
* \param dest_addr The IP address that this datagram was sent to
* \param dest_port The UDP port number, in host byte order, that the datagram was sent to
* \param data A pointer to the data contents of the UDP datagram
* \param datalen The length of the data being pointed to by the data pointer
*
* Each UDP socket has a callback function that is
* registered as part of the call to
* udp_socket_register(). The callback function gets
* called every time a UDP packet is received.
*/
typedef void (* udp_socket_input_callback_t)(struct udp_socket *c,
void *ptr,
const uip_ipaddr_t *source_addr,
uint16_t source_port,
const uip_ipaddr_t *dest_addr,
uint16_t dest_port,
const uint8_t *data,
uint16_t datalen);
struct udp_socket {
udp_socket_input_callback_t input_callback;
void *ptr;
struct process *p;
struct uip_udp_conn *udp_conn;
};
/**
* \brief Register a UDP socket
* \param c A pointer to the struct udp_socket that should be registered
* \param ptr An opaque pointer that will be passed to callbacks
* \param receive_callback A function pointer to the callback function that will be called when data arrives
* \retval -1 The registration failed
* \retval 1 The registration succeeded
*
* This function registers the UDP socket with the
* system. A UDP socket must be registered before any data
* can be sent or received over the socket.
*
* The caller must allocate memory for the struct
* udp_socket that is to be registered.
*
* A UDP socket can begin to receive data by calling
* udp_socket_bind().
*
*/
int udp_socket_register(struct udp_socket *c,
void *ptr,
udp_socket_input_callback_t receive_callback);
/**
* \brief Bind a UDP socket to a local port
* \param c A pointer to the struct udp_socket that should be bound to a local port
* \param local_port The UDP port number, in host byte order, to bind the UDP socket to
* \retval -1 Binding the UDP socket to the local port failed
* \retval 1 Binding the UDP socket to the local port succeeded
*
* This function binds the UDP socket to a local port so
* that it will begin to receive data that arrives on the
* specified port. A UDP socket will receive data
* addressed to the specified port number on any IP
* address of the host.
*
* A UDP socket that is bound to a local port will use
* this port number as a source port in outgoing UDP
* messages.
*
*/
int udp_socket_bind(struct udp_socket *c,
uint16_t local_port);
/**
* \brief Bind a UDP socket to a remote address and port
* \param c A pointer to the struct udp_socket that should be connected
* \param remote_addr The IP address of the remote host, or NULL if the UDP socket should only be connected to a specific port
* \param remote_port The UDP port number, in host byte order, to which the UDP socket should be connected
* \retval -1 Connecting the UDP socket failed
* \retval 1 Connecting the UDP socket succeeded
*
* This function connects the UDP socket to a specific
* remote port and optional remote IP address. When a UDP
* socket is connected to a remote port and address, it
* will only receive packets that are sent from the remote
* port and address. When sending data over a connected
* UDP socket, the data will be sent to the connected
* remote address.
*
* A UDP socket can be connected to a remote port, but not
* a remote IP address, by providing a NULL parameter as
* the remote_addr parameter. This lets the UDP socket
* receive data from any IP address on the specified port.
*
*/
int udp_socket_connect(struct udp_socket *c,
uip_ipaddr_t *remote_addr,
uint16_t remote_port);
/**
* \brief Send data on a UDP socket
* \param buf Buffer to send
* \param c A pointer to the struct udp_socket on which the data should be sent
* \param data A pointer to the data that should be sent
* \param datalen The length of the data to be sent
* \return The number of bytes sent, or -1 if an error occurred
*
* This function sends data over a UDP socket. The UDP
* socket must have been connected to a remote address and
* port with udp_socket_connect().
*
*/
int udp_socket_send(struct net_buf *buf, struct udp_socket *c,
const void *data, uint16_t datalen);
/**
* \brief Send data on a UDP socket to a specific address and port
* \param buf Buffer to send
* \param c A pointer to the struct udp_socket on which the data should be sent
* \param data A pointer to the data that should be sent
* \param datalen The length of the data to be sent
* \param addr The IP address to which the data should be sent
* \param port The UDP port number, in host byte order, to which the data should be sent
* \return The number of bytes sent, or -1 if an error occurred
*
* This function sends data over a UDP socket to a
* specific address and port.
*
* The UDP socket does not have to be connected to use
* this function.
*
*/
int udp_socket_sendto(struct net_buf *buf, struct udp_socket *c,
const void *data, uint16_t datalen,
const uip_ipaddr_t *addr, uint16_t port);
/**
* \brief Close a UDP socket
* \param c A pointer to the struct udp_socket to be closed
* \retval -1 If closing the UDP socket failed
* \retval 1 If closing the UDP socket succeeded
*
* This function closes a UDP socket that has previously
* been registered with udp_socket_register(). All
* registered UDP sockets must be closed before exiting
* the process that registered them, or undefined behavior
* may occur.
*
*/
int udp_socket_close(struct udp_socket *c);
#endif /* UDP_SOCKET_H */

View file

@ -1,107 +0,0 @@
/*
* Copyright (c) 2010, 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 set of debugging tools
* \author
* Nicolas Tsiftes <nvt@sics.se>
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "contiki/ip/uip-debug.h"
/*---------------------------------------------------------------------------*/
void
uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
{
if(addr == NULL || addr->u8 == NULL) {
printf("(NULL IP addr)");
return;
}
#if NETSTACK_CONF_WITH_IPV6
uint16_t a;
unsigned int i;
int f;
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
a = (addr->u8[i] << 8) + addr->u8[i + 1];
if(a == 0 && f >= 0) {
if(f++ == 0) {
PRINTA("::");
}
} else {
if(f > 0) {
f = -1;
} else if(i > 0) {
PRINTA(":");
}
PRINTA("%x", a);
}
}
#else /* NETSTACK_CONF_WITH_IPV6 */
PRINTA("%u.%u.%u.%u", addr->u8[0], addr->u8[1], addr->u8[2], addr->u8[3]);
#endif /* NETSTACK_CONF_WITH_IPV6 */
}
/*---------------------------------------------------------------------------*/
void
uip_debug_lladdr_print(const uip_lladdr_t *addr)
{
unsigned int i;
for(i = 0; i < sizeof(uip_lladdr_t); i++) {
if(i > 0) {
PRINTA(":");
}
PRINTA("%x", addr->addr[i]);
}
}
/*---------------------------------------------------------------------------*/
void
uip_debug_hex_dump(const unsigned char *buffer, int len)
{
int i = 0;
while (len--) {
if(*buffer <= 0xf)
PRINTA("0%X ", *buffer++);
else
PRINTA("%X ", *buffer++);
i++;
if (i % 8 == 0) {
if (i % 16 == 0) {
PRINTA("\n");
} else {
PRINTA(" ");
}
}
}
}
/*---------------------------------------------------------------------------*/

View file

@ -1,108 +0,0 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* A set of debugging macros.
*
* \author Nicolas Tsiftes <nvt@sics.se>
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#ifndef UIP_DEBUG_H
#define UIP_DEBUG_H
#include "contiki/ip/uip.h"
#include <stdio.h>
void uip_debug_ipaddr_print(const uip_ipaddr_t *addr);
void uip_debug_lladdr_print(const uip_lladdr_t *addr);
void uip_debug_hex_dump(const unsigned char *buffer, int len);
#if defined(CONFIG_STDOUT_CONSOLE)
#include <stdio.h>
#define PRINT printf
#else
#include <misc/printk.h>
#define PRINT printk
#endif
#define DEBUG_NONE 0
#define DEBUG_PRINT 1
#define DEBUG_ANNOTATE 2
#define DEBUG_FULL DEBUG_ANNOTATE | DEBUG_PRINT
#if (DEBUG == 1)
#if defined(CONFIG_NETWORK_IP_STACK_DEBUG_PRINT)
#define _DEBUG_ DEBUG_PRINT
#elif defined(CONFIG_NETWORK_IP_STACK_DEBUG_ANNOTATE)
#define _DEBUG_ DEBUG_ANNOTATE
#elif defined(CONFIG_NETWORK_IP_STACK_DEBUG_FULL)
#define _DEBUG_ DEBUG_FULL
#else
#define _DEBUG_ DEBUG_NONE
#endif
#endif
/* PRINTA will always print if the debug routines are called directly */
#ifdef __AVR__
#include <avr/pgmspace.h>
#define PRINTA(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTA(...) PRINT(__VA_ARGS__)
#endif
#if (_DEBUG_) & DEBUG_ANNOTATE
#ifdef __AVR__
#define ANNOTATE(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define ANNOTATE(...) PRINT(__VA_ARGS__)
#endif
#else
#define ANNOTATE(...)
#endif /* (_DEBUG_) & DEBUG_ANNOTATE */
#if (_DEBUG_) & DEBUG_PRINT
#ifdef __AVR__
#define PRINTF(FORMAT,args...) printf_P(PSTR(FORMAT),##args)
#else
#define PRINTF(...) PRINT(__VA_ARGS__)
#endif
#define PRINT6ADDR(addr) uip_debug_ipaddr_print(addr)
#define PRINTLLADDR(lladdr) uip_debug_lladdr_print(lladdr)
#else
#define PRINTF(...)
#define PRINT6ADDR(addr)
#define PRINTLLADDR(lladdr)
#endif /* (_DEBUG_) & DEBUG_PRINT */
#endif

View file

@ -1,236 +0,0 @@
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* uIP Name Server interface
* \author Víctor Ariño <victor.arino@tado.com>
*/
/*
* Copyright (c) 2014, tado° GmbH.
* 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 "contiki.h"
#include "contiki-net.h"
#include "lib/list.h"
#include "lib/memb.h"
#include <string.h>
/** \brief Nameserver record */
typedef struct uip_nameserver_record {
struct uip_nameserver_record *next;
uip_ipaddr_t ip;
uint32_t added;
uint32_t lifetime;
} uip_nameserver_record;
#if UIP_NAMESERVER_POOL_SIZE > 1
/** \brief Initialization flag */
static uint8_t initialized = 0;
#endif
/** \name List and memory block
* @{
*/
#if UIP_NAMESERVER_POOL_SIZE > 1
LIST(dns);
MEMB(dnsmemb, uip_nameserver_record, UIP_NAMESERVER_POOL_SIZE);
#else /* UIP_NAMESERVER_POOL_SIZE > 1 */
static uip_ipaddr_t serveraddr;
static uint32_t serverlifetime;
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
/** @} */
/** \brief Expiration time in seconds */
#define DNS_EXPIRATION(r) \
(((UIP_NAMESERVER_INFINITE_LIFETIME - r->added) <= r->lifetime) ? \
UIP_NAMESERVER_INFINITE_LIFETIME : r->added + r->lifetime)
/*----------------------------------------------------------------------------*/
/**
* Initialize the module variables
*/
#if UIP_NAMESERVER_POOL_SIZE > 1
static CC_INLINE void
init(void)
{
list_init(dns);
memb_init(&dnsmemb);
initialized = 1;
}
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
/*----------------------------------------------------------------------------*/
void
uip_nameserver_update(uip_ipaddr_t *nameserver, uint32_t lifetime)
{
#if UIP_NAMESERVER_POOL_SIZE > 1
register uip_nameserver_record *e;
if(initialized == 0) {
init();
}
for(e = list_head(dns); e != NULL; e = list_item_next(e)) {
if(uip_ipaddr_cmp(&e->ip, nameserver)) {
break;
/* RFC6106: In case there's no more space, the new servers should replace
* the the eldest ones */
}
}
if(e == NULL) {
if((e = memb_alloc(&dnsmemb)) != NULL) {
list_add(dns, e);
} else {
uip_nameserver_record *p;
for(e = list_head(dns), p = list_head(dns); p != NULL;
p = list_item_next(p)) {
if(DNS_EXPIRATION(p) < DNS_EXPIRATION(e)) {
e = p;
}
}
}
}
/* RFC6106: In case the entry is existing the expiration time must be
* updated. Otherwise, new entries are added. */
if(e != NULL) {
if(lifetime == 0) {
memb_free(&dnsmemb, e);
list_remove(dns, e);
} else {
e->added = clock_seconds();
e->lifetime = lifetime;
uip_ipaddr_copy(&e->ip, nameserver);
}
}
#else /* UIP_NAMESERVER_POOL_SIZE > 1 */
uip_ipaddr_copy(&serveraddr, nameserver);
serverlifetime = lifetime;
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
}
/*----------------------------------------------------------------------------*/
#if UIP_NAMESERVER_POOL_SIZE > 1
/**
* Purge expired records
*/
static void
purge(void)
{
register uip_nameserver_record *e = NULL;
uint32_t time = clock_seconds();
for(e = list_head(dns); e != NULL; e = list_item_next(e)) {
if(DNS_EXPIRATION(e) < time) {
list_remove(dns, e);
memb_free(&dnsmemb, e);
e = list_head(dns);
}
}
}
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
/*----------------------------------------------------------------------------*/
uip_ipaddr_t *
uip_nameserver_get(uint8_t num)
{
#if UIP_NAMESERVER_POOL_SIZE > 1
uint8_t i;
uip_nameserver_record *e = NULL;
if(initialized == 0) {
return NULL;
}
purge();
for(i = 1, e = list_head(dns); e != NULL && i <= num;
i++, e = list_item_next(e)) {
}
if(e != NULL) {
return &e->ip;
}
return NULL;
#else /* UIP_NAMESERVER_POOL_SIZE > 1 */
if(num > 0) {
return NULL;
}
return &serveraddr;
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
}
/*----------------------------------------------------------------------------*/
uint32_t
uip_nameserver_next_expiration(void)
{
#if UIP_NAMESERVER_POOL_SIZE > 1
register uip_nameserver_record *e = NULL;
uint32_t exp = UIP_NAMESERVER_INFINITE_LIFETIME;
uint32_t t;
if(initialized == 0 || list_length(dns) == 0) {
return 0;
}
purge();
for(e = list_head(dns); e != NULL; e = list_item_next(e)) {
t = DNS_EXPIRATION(e);
if(t < exp) {
exp = t;
}
}
return exp;
#else /* UIP_NAMESERVER_POOL_SIZE > 1 */
return serverlifetime;
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
}
/*----------------------------------------------------------------------------*/
uint16_t
uip_nameserver_count(void)
{
#if UIP_NAMESERVER_POOL_SIZE > 1
if(initialized == 0) {
return 0;
}
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;
}
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
}
/*----------------------------------------------------------------------------*/
/** @} */

View file

@ -1,101 +0,0 @@
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* uIP Name Server interface
* \author Víctor Ariño <victor.arino@tado.com>
*/
/*
* Copyright (c) 2014, tado° GmbH.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
#ifndef UIP_NAMESERVER_H_
#define UIP_NAMESERVER_H_
/**
* \name General
* @{
*/
/** \brief Number of Nameservers to keep */
#ifndef UIP_CONF_NAMESERVER_POOL_SIZE
#define UIP_NAMESERVER_POOL_SIZE 1
#else /* UIP_CONF_NAMESERVER_POOL_SIZE */
#define UIP_NAMESERVER_POOL_SIZE UIP_CONF_NAMESERVER_POOL_SIZE
#endif /* UIP_CONF_NAMESERVER_POOL_SIZE */
/** \brief Infinite Lifetime indicator */
#define UIP_NAMESERVER_INFINITE_LIFETIME 0xFFFFFFFF
/** @} */
/**
* \name Nameserver maintenance
* @{
*/
/**
* \brief Insert or update a nameserver into/from the pool
*
* The list is kept according to the RFC6106, which indicates that new entries
* will replace old ones (with lower lifetime) and existing entries will update
* their lifetimes.
*
* \param nameserver Pointer to the nameserver ip address
* \param lifetime Life time of the given address. Minimum is 0, which is
* considered to remove an entry. Maximum is 0xFFFFFFFF which
* is considered infinite.
*/
void uip_nameserver_update(uip_ipaddr_t *nameserver, uint32_t lifetime);
/**
* \brief Get a Nameserver ip address given in RA
*
* \param num The number of the nameserver to obtain, starting at 0 and going
* up to the pool size.
*/
uip_ipaddr_t *uip_nameserver_get(uint8_t num);
/**
* \brief Get next expiration time
*
* The least expiration time is returned
*/
uint32_t uip_nameserver_next_expiration(void);
/**
* \brief Get the number of recorded name servers
*/
uint16_t uip_nameserver_count(void);
/** @} */
#endif /* UIP_NAMESERVER_H_ */
/** @} */

View file

@ -1,85 +0,0 @@
#include <stdio.h>
#include "contiki/ip/uip.h"
#include "lib/memb.h"
#include "contiki/ip/uip-packetqueue.h"
#define MAX_NUM_QUEUED_PACKETS 2
MEMB(packets_memb, struct uip_packetqueue_packet, MAX_NUM_QUEUED_PACKETS);
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_PACKET_QUEUE
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
/*---------------------------------------------------------------------------*/
static void
packet_timedout(struct net_buf *buf, void *ptr)
{
struct uip_packetqueue_handle *h = ptr;
PRINTF("uip_packetqueue_free timed out handle %p, packet %p\n", h, h->packet);
memb_free(&packets_memb, h->packet);
h->packet = NULL;
}
/*---------------------------------------------------------------------------*/
void
uip_packetqueue_new(struct uip_packetqueue_handle *handle)
{
PRINTF("uip_packetqueue_new %p\n", handle);
handle->packet = NULL;
}
/*---------------------------------------------------------------------------*/
struct uip_packetqueue_packet *
uip_packetqueue_alloc(struct net_buf *buf, struct uip_packetqueue_handle *handle, clock_time_t lifetime)
{
PRINTF("uip_packetqueue_alloc %p\n", handle);
if(handle->packet != NULL) {
PRINTF("handle->packet != NULL, so failed to alloc\n");
return NULL;
}
handle->packet = memb_alloc(&packets_memb);
if(handle->packet != NULL) {
PRINTF("uip_packetqueue_alloc packet %p\n", handle->packet);
ctimer_set(buf, &handle->packet->lifetimer, lifetime,
packet_timedout, handle);
} else {
PRINTF("uip_packetqueue_alloc failed\n");
}
return handle->packet;
}
/*---------------------------------------------------------------------------*/
void
uip_packetqueue_free(struct uip_packetqueue_handle *handle)
{
PRINTF("uip_packetqueue_free %p\n", handle);
if(handle->packet != NULL) {
PRINTF("uip_packetqueue_free packet %p\n", handle->packet);
ctimer_stop(&handle->packet->lifetimer);
memb_free(&packets_memb, handle->packet);
handle->packet = NULL;
}
}
/*---------------------------------------------------------------------------*/
uint8_t *
uip_packetqueue_buf(struct uip_packetqueue_handle *h)
{
return h->packet != NULL? h->packet->queue_buf: NULL;
}
/*---------------------------------------------------------------------------*/
uint16_t
uip_packetqueue_buflen(struct uip_packetqueue_handle *h)
{
return h->packet != NULL? h->packet->queue_buf_len: 0;
}
/*---------------------------------------------------------------------------*/
void
uip_packetqueue_set_buflen(struct uip_packetqueue_handle *h, uint16_t len)
{
if(h->packet != NULL) {
h->packet->queue_buf_len = len;
}
}
/*---------------------------------------------------------------------------*/

View file

@ -1,37 +0,0 @@
#include <net/buf.h>
#ifndef UIP_PACKETQUEUE_H
#define UIP_PACKETQUEUE_H
#include "sys/ctimer.h"
struct uip_packetqueue_handle;
struct uip_packetqueue_packet {
struct uip_ds6_queued_packet *next;
uint8_t queue_buf[UIP_BUFSIZE - UIP_LLH_LEN];
uint16_t queue_buf_len;
struct ctimer lifetimer;
struct uip_packetqueue_handle *handle;
};
struct uip_packetqueue_handle {
struct uip_packetqueue_packet *packet;
};
void uip_packetqueue_new(struct uip_packetqueue_handle *handle);
struct uip_packetqueue_packet *
uip_packetqueue_alloc(struct net_buf *buf, struct uip_packetqueue_handle *handle, clock_time_t lifetime);
void
uip_packetqueue_free(struct uip_packetqueue_handle *handle);
uint8_t *uip_packetqueue_buf(struct uip_packetqueue_handle *h);
uint16_t uip_packetqueue_buflen(struct uip_packetqueue_handle *h);
void uip_packetqueue_set_buflen(struct uip_packetqueue_handle *h, uint16_t len);
#endif /* UIP_PACKETQUEUE_H */

View file

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

View file

@ -1,124 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Module for sending UDP packets through uIP.
* \author
* Adam Dunkels <adam@sics.se>
*/
#include <net/ip_buf.h>
#include "contiki-conf.h"
#include "contiki/ip/uip-udp-packet.h"
#include "contiki/ipv6/multicast/uip-mcast6.h"
#include <string.h>
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_UDP_PACKET
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
/*---------------------------------------------------------------------------*/
uint8_t
uip_udp_packet_send(struct net_buf *buf, struct uip_udp_conn *c, const void *data, int len)
{
#if UIP_UDP
if(data != NULL) {
uip_set_udp_conn(buf) = c;
uip_slen(buf) = len;
memcpy(&uip_buf(buf)[UIP_LLH_LEN + UIP_IPUDPH_LEN], data,
len > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN?
UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: len);
if (uip_process(&buf, UIP_UDP_SEND_CONN) == 0) {
/* The packet was dropped, we can return now */
return 0;
}
#if UIP_CONF_IPV6_MULTICAST
/* Let the multicast engine process the datagram before we send it */
if(uip_is_addr_mcast_routable(&uip_udp_conn(buf)->ripaddr)) {
UIP_MCAST6.out();
}
#endif /* UIP_IPV6_MULTICAST */
if (!uip_len(buf)) {
/* Message was successfully sent, just bail out now. */
goto out;
}
#if NETSTACK_CONF_WITH_IPV6
if (!tcpip_ipv6_output(buf)) {
return 0;
}
#else
if(uip_len(buf) > 0) {
tcpip_output(buf, NULL);
}
#endif
}
out:
uip_slen(buf) = 0;
#endif /* UIP_UDP */
return 1;
}
/*---------------------------------------------------------------------------*/
uint8_t
uip_udp_packet_sendto(struct net_buf *buf, struct uip_udp_conn *c, const void *data, int len,
const uip_ipaddr_t *toaddr, uint16_t toport)
{
uip_ipaddr_t curaddr;
uint16_t curport;
uint8_t ret = 0;
if(toaddr != NULL) {
/* Save current IP addr/port. */
uip_ipaddr_copy(&curaddr, &c->ripaddr);
curport = c->rport;
/* Load new IP addr/port */
uip_ipaddr_copy(&c->ripaddr, toaddr);
c->rport = toport;
ret = uip_udp_packet_send(buf, c, data, len);
/* Restore old IP addr/port */
uip_ipaddr_copy(&c->ripaddr, &curaddr);
c->rport = curport;
}
return ret;
}
/*---------------------------------------------------------------------------*/

View file

@ -1,54 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Header file for module for sending UDP packets through uIP.
* \author
* Adam Dunkels <adam@sics.se>
*/
#ifndef UIP_UDP_PACKET_H_
#define UIP_UDP_PACKET_H_
#include <net/buf.h>
#include "contiki/ip/uip.h"
/* Return value: 0 - packet could not be sent, the net_buf is released by API
* 1 - packet sent, caller needs to de-allocate the buf
*/
uint8_t uip_udp_packet_send(struct net_buf *buf, struct uip_udp_conn *c, const void *data, int len);
uint8_t uip_udp_packet_sendto(struct net_buf *buf, struct uip_udp_conn *c, const void *data, int len,
const uip_ipaddr_t *toaddr, uint16_t toport);
#endif /* UIP_UDP_PACKET_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,97 +0,0 @@
/*
* Copyright (c) 2001-2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
*
*/
#ifndef UIPADDR_H_
#define UIPADDR_H_
/**
* Representation of an IP address.
*
*/
typedef union uip_ip4addr_t {
uint8_t u8[4]; /* Initializer, must come first. */
uint16_t u16[2];
} uip_ip4addr_t;
typedef union uip_ip6addr_t {
uint8_t u8[16]; /* Initializer, must come first. */
uint16_t u16[8];
} PACK_ALIAS_STRUCT 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 */
/*---------------------------------------------------------------------------*/
/** \brief 16 bit 802.15.4 address */
typedef struct uip_802154_shortaddr {
uint8_t addr[2];
} uip_802154_shortaddr;
/** \brief 64 bit 802.15.4 address */
typedef struct uip_802154_longaddr {
uint8_t addr[8];
} uip_802154_longaddr;
/** \brief 802.11 address */
typedef struct uip_80211_addr {
uint8_t addr[6];
} uip_80211_addr;
/** \brief 802.3 address */
typedef struct uip_eth_addr {
uint8_t addr[6];
} uip_eth_addr;
#if UIP_CONF_LL_802154
/** \brief 802.15.4 address */
typedef uip_802154_longaddr uip_lladdr_t;
#define UIP_802154_SHORTADDR_LEN 2
#define UIP_802154_LONGADDR_LEN 8
#define UIP_LLADDR_LEN UIP_802154_LONGADDR_LEN
#else /*UIP_CONF_LL_802154*/
#if UIP_CONF_LL_80211
/** \brief 802.11 address */
typedef uip_80211_addr uip_lladdr_t;
#define UIP_LLADDR_LEN 6
#else /*UIP_CONF_LL_80211*/
/** \brief Ethernet address */
typedef uip_eth_addr uip_lladdr_t;
#define UIP_LLADDR_LEN 6
#endif /*UIP_CONF_LL_80211*/
#endif /*UIP_CONF_LL_802154*/
#endif /* UIPADDR_H_ */

View file

@ -1,143 +0,0 @@
/*
* Copyright (c) 2004, Adam Dunkels and the 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. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack and the Contiki operating system.
*
*
*/
#include "contiki/ip/uip.h"
#include "contiki/ip/uiplib.h"
#include <string.h>
#define DEBUG DEBUG_NONE
#include "contiki/ip/uip-debug.h"
/*-----------------------------------------------------------------------------------*/
#if NETSTACK_CONF_WITH_IPV6
int
uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr)
{
uint16_t value;
int tmp, zero;
unsigned int len;
char c = 0; //gcc warning if not initialized
value = 0;
zero = -1;
if(*addrstr == '[') addrstr++;
for(len = 0; len < sizeof(uip_ip6addr_t) - 1; addrstr++) {
c = *addrstr;
if(c == ':' || c == '\0' || c == ']' || c == '/') {
ipaddr->u8[len] = (value >> 8) & 0xff;
ipaddr->u8[len + 1] = value & 0xff;
len += 2;
value = 0;
if(c == '\0' || c == ']' || c == '/') {
break;
}
if(*(addrstr + 1) == ':') {
/* Zero compression */
if(zero < 0) {
zero = len;
}
addrstr++;
}
} else {
if(c >= '0' && c <= '9') {
tmp = c - '0';
} else if(c >= 'a' && c <= 'f') {
tmp = c - 'a' + 10;
} else if(c >= 'A' && c <= 'F') {
tmp = c - 'A' + 10;
} else {
PRINTF("uiplib: illegal char: '%c'\n", c);
return 0;
}
value = (value << 4) + (tmp & 0xf);
}
}
if(c != '\0' && c != ']' && c != '/') {
PRINTF("uiplib: too large address\n");
return 0;
}
if(len < sizeof(uip_ip6addr_t)) {
if(zero < 0) {
PRINTF("uiplib: too short address\n");
return 0;
}
memmove(&ipaddr->u8[zero + sizeof(uip_ip6addr_t) - len],
&ipaddr->u8[zero], len - zero);
memset(&ipaddr->u8[zero], 0, sizeof(uip_ip6addr_t) - len);
}
return 1;
}
#endif /* NETSTACK_CONF_WITH_IPV6 */
/*-----------------------------------------------------------------------------------*/
/* Parse a IPv4-address from a string. Returns the number of characters read
* for the address. */
int
uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *ipaddr)
{
unsigned char tmp;
char c;
unsigned char i, j;
uint8_t charsread = 0;
tmp = 0;
for(i = 0; i < 4; ++i) {
j = 0;
do {
c = *addrstr;
++j;
if(j > 4) {
return 0;
}
if(c == '.' || c == 0 || c == ' ') {
ipaddr->u8[i] = tmp;
tmp = 0;
} else if(c >= '0' && c <= '9') {
tmp = (tmp * 10) + (c - '0');
} else {
return 0;
}
++addrstr;
++charsread;
} while(c != '.' && c != 0 && c != ' ');
}
return charsread-1;
}
/*-----------------------------------------------------------------------------------*/

View file

@ -1,80 +0,0 @@
/*
* Copyright (c) 2002, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the Contiki desktop environment for the C64.
*
*
*/
/**
* \file
* Various uIP library functions.
* \author
* Adam Dunkels <adam@sics.se>
*
*/
#ifndef UIPLIB_H_
#define UIPLIB_H_
#include "contiki/ip/uip.h"
/**
* \addtogroup uipconvfunc
* @{
*/
/**
* Convert a textual representation of an IP address to a numerical representation.
*
* This function takes a textual representation of an IP address in
* the form a.b.c.d for IPv4 or a:b:c:d:e:f:g:h for IPv6 and converts
* it into a numeric IP address representation that can be used by
* other uIP functions.
*
* \param addrstr A pointer to a string containing the IP address in
* textual form.
*
* \param addr A pointer to a uip_ip4addr_t that will be filled in with
* the numerical representation of the address.
*
* \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 */
CCIF int uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *addr);
CCIF int uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *addr);
/** @} */
#endif /* UIPLIB_H_ */

View file

@ -1,684 +0,0 @@
/*
* Copyright (c) 2001-2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
*
*/
/**
* \file
* Configuration options for uIP.
* \author Adam Dunkels <adam@dunkels.com>
*
* This file is used for tweaking various configuration options for
* uIP. You should make a copy of this file into one of your project's
* directories instead of editing this example "uipopt.h" file that
* comes with the uIP distribution.
*/
/**
* \addtogroup uip
* @{
*/
/**
* \defgroup uipopt Configuration options for uIP
* @{
*
* uIP is configured using the per-project configuration file
* "uipopt.h". This file contains all compile-time options for uIP and
* should be tweaked to match each specific project. The uIP
* distribution contains a documented example "uipopt.h" that can be
* copied and modified for each project.
*
* \note Contiki does not use the uipopt.h file to configure uIP, but
* uses a per-port uip-conf.h file that should be edited instead.
*/
#ifndef UIPOPT_H_
#define UIPOPT_H_
#ifndef UIP_LITTLE_ENDIAN
#define UIP_LITTLE_ENDIAN 3412
#endif /* UIP_LITTLE_ENDIAN */
#ifndef UIP_BIG_ENDIAN
#define UIP_BIG_ENDIAN 1234
#endif /* UIP_BIG_ENDIAN */
#include "contiki-conf.h"
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptstaticconf Static configuration options
* @{
*
* These configuration options can be used for setting the IP address
* settings statically, but only if UIP_FIXEDADDR is set to 1. The
* configuration options for a specific node includes IP address,
* netmask and default router as well as the Ethernet address. The
* netmask, default router and Ethernet address are applicable only
* if uIP should be run over Ethernet.
*
* This options are meaningful only for the IPv4 code.
*
* All of these should be changed to suit your project.
*/
/**
* Determines if uIP should use a fixed IP address or not.
*
* If uIP should use a fixed IP address, the settings are set in the
* uipopt.h file. If not, the macros uip_sethostaddr(),
* uip_setdraddr() and uip_setnetmask() should be used instead.
*
* \hideinitializer
*/
#define UIP_FIXEDADDR 0
/**
* Ping IP address assignment.
*
* uIP uses a "ping" packets for setting its own IP address if this
* option is set. If so, uIP will start with an empty IP address and
* the destination IP address of the first incoming "ping" (ICMP echo)
* packet will be used for setting the hosts IP address.
*
* \note This works only if UIP_FIXEDADDR is 0.
*
* \hideinitializer
*/
#ifdef UIP_CONF_PINGADDRCONF
#define UIP_PINGADDRCONF (UIP_CONF_PINGADDRCONF)
#else /* UIP_CONF_PINGADDRCONF */
#define UIP_PINGADDRCONF 0
#endif /* UIP_CONF_PINGADDRCONF */
/**
* Specifies if the uIP ARP module should be compiled with a fixed
* Ethernet MAC address or not.
*
* If this configuration option is 0, the macro uip_setethaddr() can
* be used to specify the Ethernet address at run-time.
*
* \hideinitializer
*/
#define UIP_FIXEDETHADDR 0
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptgeneral General configuration options
* @{
*/
/**
* 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.
*
* The uIP packet buffer should not be smaller than 60 bytes, and does
* not need to be larger than 1514 bytes. Lower size results in lower
* TCP throughput, larger size results in higher TCP throughput.
*
* \hideinitializer
*/
#ifndef UIP_CONF_BUFFER_SIZE
#define UIP_BUFSIZE (UIP_LINK_MTU + UIP_LLH_LEN)
#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.
*
* The statistics is useful for debugging and to show the user.
*
* \hideinitializer
*/
#ifndef UIP_CONF_STATISTICS
#define UIP_STATISTICS 0
#else /* UIP_CONF_STATISTICS */
#define UIP_STATISTICS (UIP_CONF_STATISTICS)
#endif /* UIP_CONF_STATISTICS */
/**
* Determines if logging of certain events should be compiled in.
*
* This is useful mostly for debugging. The function uip_log()
* must be implemented to suit the architecture of the project, if
* logging is turned on.
*
* \hideinitializer
*/
#ifndef UIP_CONF_LOGGING
#define UIP_LOGGING 0
#else /* UIP_CONF_LOGGING */
#define UIP_LOGGING (UIP_CONF_LOGGING)
#endif /* UIP_CONF_LOGGING */
/**
* Broadcast support.
*
* This flag configures IP broadcast support. This is useful only
* together with UDP.
*
* \hideinitializer
*
*/
#ifndef UIP_CONF_BROADCAST
#define UIP_BROADCAST 0
#else /* UIP_CONF_BROADCAST */
#define UIP_BROADCAST (UIP_CONF_BROADCAST)
#endif /* UIP_CONF_BROADCAST */
/**
* Print out a uIP log message.
*
* This function must be implemented by the module that uses uIP, and
* is called by uIP whenever a log message is generated.
*/
void uip_log(char *msg);
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptip IP configuration options
* @{
*
*/
/**
* The IP TTL (time to live) of IP packets sent by uIP.
*
* This should normally not be changed.
*/
#ifdef UIP_CONF_TTL
#define UIP_TTL UIP_CONF_TTL
#else /* UIP_CONF_TTL */
#define UIP_TTL 64
#endif /* UIP_CONF_TTL */
/**
* The maximum time an IP fragment should wait in the reassembly
* buffer before it is dropped.
*
*/
#define UIP_REASS_MAXAGE 60 /*60s*/
/**
* Turn on support for IP packet reassembly.
*
* uIP supports reassembly of fragmented IP packets. This features
* requires an additional amount of RAM to hold the reassembly buffer
* and the reassembly code size is approximately 700 bytes. The
* reassembly buffer is of the same size as the uip_buf buffer
* (configured by UIP_BUFSIZE).
*
* \note IP packet reassembly is not heavily tested.
*
* \hideinitializer
*/
#ifdef UIP_CONF_REASSEMBLY
#define UIP_REASSEMBLY (UIP_CONF_REASSEMBLY)
#else /* UIP_CONF_REASSEMBLY */
#define UIP_REASSEMBLY 0
#endif /* UIP_CONF_REASSEMBLY */
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptipv6 IPv6 configuration options
* @{
*
*/
/** 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
#endif
#ifndef UIP_CONF_IPV6_CHECKS
/** Do we do IPv6 consistency checks (highly recommended, default: yes) */
#define UIP_CONF_IPV6_CHECKS 1
#endif
#ifndef UIP_CONF_IPV6_REASSEMBLY
/** Do we do IPv6 fragmentation (default: no) */
#define UIP_CONF_IPV6_REASSEMBLY 0
#endif
#ifndef UIP_CONF_NETIF_MAX_ADDRESSES
/** Default number of IPv6 addresses associated to the node's interface */
#define UIP_CONF_NETIF_MAX_ADDRESSES 3
#endif
#ifndef UIP_CONF_DS6_PREFIX_NBU
/** Default number of IPv6 prefixes associated to the node's interface */
#define UIP_CONF_DS6_PREFIX_NBU 2
#endif
#ifndef UIP_CONF_DS6_DEFRT_NBU
/** Minimum number of default routers */
#define UIP_CONF_DS6_DEFRT_NBU 2
#endif
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptudp UDP configuration options
* @{
*
* \note The UDP support in uIP is still not entirely complete; there
* is no support for sending or receiving broadcast or multicast
* packets, but it works well enough to support a number of vital
* applications such as DNS queries, though
*/
/**
* Toggles whether UDP support should be compiled in or not.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP
#define UIP_UDP UIP_CONF_UDP
#else /* UIP_CONF_UDP */
#define UIP_UDP 1
#endif /* UIP_CONF_UDP */
/**
* Toggles if UDP checksums should be used or not.
*
* \note Support for UDP checksums is currently not included in uIP,
* so this option has no function.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP_CHECKSUMS
#define UIP_UDP_CHECKSUMS (UIP_CONF_UDP_CHECKSUMS)
#else
#define UIP_UDP_CHECKSUMS (NETSTACK_CONF_WITH_IPV6)
#endif
/**
* The maximum amount of concurrent UDP connections.
*
* \hideinitializer
*/
#ifdef UIP_CONF_UDP_CONNS
#define UIP_UDP_CONNS (UIP_CONF_UDP_CONNS)
#else /* UIP_CONF_UDP_CONNS */
#define UIP_UDP_CONNS 10
#endif /* UIP_CONF_UDP_CONNS */
/**
* The name of the function that should be called when UDP datagrams arrive.
*
* \hideinitializer
*/
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipopttcp TCP configuration options
* @{
*/
/**
* Toggles whether TCP support should be compiled in or not.
*
* \hideinitializer
*/
#ifdef UIP_CONF_TCP
#define UIP_TCP (UIP_CONF_TCP)
#else /* UIP_CONF_TCP */
#define UIP_TCP 1
#endif /* UIP_CONF_TCP */
/**
* Determines if support for opening connections from uIP should be
* compiled in.
*
* If the applications that are running on top of uIP for this project
* do not need to open outgoing TCP connections, this configuration
* option can be turned off to reduce the code size of uIP.
*
* \hideinitializer
*/
#ifndef UIP_CONF_ACTIVE_OPEN
#define UIP_ACTIVE_OPEN 1
#else /* UIP_CONF_ACTIVE_OPEN */
#define UIP_ACTIVE_OPEN (UIP_CONF_ACTIVE_OPEN)
#endif /* UIP_CONF_ACTIVE_OPEN */
/**
* The maximum number of simultaneously open TCP connections.
*
* Since the TCP connections are statically allocated, turning this
* configuration knob down results in less RAM used. Each TCP
* connection requires approximately 30 bytes of memory.
*
* \hideinitializer
*/
#ifndef UIP_CONF_MAX_CONNECTIONS
#define UIP_CONNS 10
#else /* UIP_CONF_MAX_CONNECTIONS */
#define UIP_CONNS (UIP_CONF_MAX_CONNECTIONS)
#endif /* UIP_CONF_MAX_CONNECTIONS */
/**
* The maximum number of simultaneously listening TCP ports.
*
* Each listening TCP port requires 2 bytes of memory.
*
* \hideinitializer
*/
#ifndef UIP_CONF_MAX_LISTENPORTS
#define UIP_LISTENPORTS 20
#else /* UIP_CONF_MAX_LISTENPORTS */
#define UIP_LISTENPORTS (UIP_CONF_MAX_LISTENPORTS)
#endif /* UIP_CONF_MAX_LISTENPORTS */
/**
* Determines if support for TCP urgent data notification should be
* compiled in.
*
* Urgent data (out-of-band data) is a rarely used TCP feature that
* very seldom would be required.
*
* \hideinitializer
*/
#define UIP_URGDATA 0
/**
* The initial retransmission timeout counted in timer pulses.
*
* This should not be changed.
*/
#define UIP_RTO 3
/**
* The maximum number of times a segment should be retransmitted
* before the connection should be aborted.
*
* This should not be changed.
*/
#define UIP_MAXRTX 8
/**
* The maximum number of times a SYN segment should be retransmitted
* before a connection request should be deemed to have been
* unsuccessful.
*
* This should not need to be changed.
*/
#define UIP_MAXSYNRTX 5
/**
* The TCP maximum segment size.
*
* This is should not be to set to more than
* UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
*/
#ifdef UIP_CONF_TCP_MSS
#if UIP_CONF_TCP_MSS > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
#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) */
#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)
#endif /* UIP_CONF_TCP_MSS */
/**
* The size of the advertised receiver's window.
*
* Should be set low (i.e., to the size of the uip_buf buffer) if the
* application is slow to process incoming data, or high (32768 bytes)
* if the application processes data quickly.
*
* \hideinitializer
*/
#ifndef UIP_CONF_RECEIVE_WINDOW
#define UIP_RECEIVE_WINDOW (UIP_TCP_MSS)
#else
#define UIP_RECEIVE_WINDOW (UIP_CONF_RECEIVE_WINDOW)
#endif
/**
* How long a connection should stay in the TIME_WAIT state.
*
* This can be reduced for faster entry into power saving modes.
*/
#ifndef UIP_CONF_WAIT_TIMEOUT
#define UIP_TIME_WAIT_TIMEOUT 120
#else
#define UIP_TIME_WAIT_TIMEOUT UIP_CONF_WAIT_TIMEOUT
#endif
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptarp ARP configuration options
* @{
*/
/**
* The size of the ARP table.
*
* This option should be set to a larger value if this uIP node will
* have many connections from the local network.
*
* \hideinitializer
*/
#ifdef UIP_CONF_ARPTAB_SIZE
#define UIP_ARPTAB_SIZE (UIP_CONF_ARPTAB_SIZE)
#else
#define UIP_ARPTAB_SIZE 8
#endif
/**
* The maximum age of ARP table entries measured in 10ths of seconds.
*
* An UIP_ARP_MAXAGE of 120 corresponds to 20 minutes (BSD
* default).
*/
#define UIP_ARP_MAXAGE 120
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptmac layer 2 options (for ipv6)
* @{
*/
#define UIP_DEFAULT_PREFIX_LEN 64
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptsics 6lowpan options (for ipv6)
* @{
*/
/**
* Timeout for packet reassembly at the 6lowpan layer
* (should be < 60s)
*/
#ifdef SICSLOWPAN_CONF_MAXAGE
#define SICSLOWPAN_REASS_MAXAGE (SICSLOWPAN_CONF_MAXAGE)
#else
#define SICSLOWPAN_REASS_MAXAGE 20
#endif
/**
* Do we compress the IP header or not (default: no)
*/
#ifndef SICSLOWPAN_CONF_COMPRESSION
#define SICSLOWPAN_CONF_COMPRESSION 0
#endif
/**
* If we use IPHC compression, how many address contexts do we support
*/
#ifndef SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1
#endif
/**
* Do we support 6lowpan fragmentation
*/
#ifndef SICSLOWPAN_CONF_FRAG
#define SICSLOWPAN_CONF_FRAG 0
#endif
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptcpu CPU architecture configuration
* @{
*
* The CPU architecture configuration is where the endianess of the
* CPU on which uIP is to be run is specified. Most CPUs today are
* little endian, and the most notable exception are the Motorolas
* which are big endian. The BYTE_ORDER macro should be changed to
* reflect the CPU architecture on which uIP is to be run.
*/
/**
* The byte order of the CPU architecture on which uIP is to be run.
*
* This option can be either UIP_BIG_ENDIAN (Motorola byte order) or
* UIP_LITTLE_ENDIAN (Intel byte order).
*
* \hideinitializer
*/
#ifdef UIP_CONF_BYTE_ORDER
#define UIP_BYTE_ORDER (UIP_CONF_BYTE_ORDER)
#else /* UIP_CONF_BYTE_ORDER */
#define UIP_BYTE_ORDER (UIP_LITTLE_ENDIAN)
#endif /* UIP_CONF_BYTE_ORDER */
/** @} */
/*------------------------------------------------------------------------------*/
/**
* \defgroup uipoptapp Application specific configurations
* @{
*
* An uIP application is implemented using a single application
* function that is called by uIP whenever a TCP/IP event occurs. The
* name of this function must be registered with uIP at compile time
* using the UIP_APPCALL definition.
*
* uIP applications can store the application state within the
* uip_conn structure by specifying the type of the application
* structure by typedef:ing the type uip_tcp_appstate_t and uip_udp_appstate_t.
*
* The file containing the definitions must be included in the
* uipopt.h file.
*
* The following example illustrates how this can look.
\code
void httpd_appcall(void);
#define UIP_APPCALL httpd_appcall
struct httpd_state {
uint8_t state;
uint16_t count;
char *dataptr;
char *script;
};
typedef struct httpd_state uip_tcp_appstate_t
\endcode
*/
/**
* \var #define UIP_APPCALL
*
* The name of the application function that uIP should call in
* response to TCP/IP events.
*
*/
/**
* \var typedef uip_tcp_appstate_t
*
* The type of the application state that is to be stored in the
* uip_conn structure. This usually is typedef:ed to a struct holding
* application state information.
*/
/**
* \var typedef uip_udp_appstate_t
*
* The type of the application state that is to be stored in the
* uip_conn structure. This usually is typedef:ed to a struct holding
* application state information.
*/
/** @} */
#endif /* UIPOPT_H_ */
/** @} */
/** @} */

View file

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

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

@ -1,114 +0,0 @@
README file for Contiki's IPv6 multicast core
Author: George Oikonomou
What does it do
===============
These files, alongside some core modifications, add support for IPv6 multicast
to contiki's uIPv6 engine.
Currently, two modes are supported:
* 'Stateless Multicast RPL Forwarding' (SMRF)
RPL in MOP 3 handles group management as per the RPL docs,
SMRF is a lightweight engine which handles datagram forwarding.
SMRF is documented here:
http://dx.doi.org/10.1007/s11277-013-1250-5
and here:
http://dx.doi.org/10.1109/PerComW.2012.6197494
* 'Multicast Forwarding with Trickle' according to the algorithm described
in the internet draft:
http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
The version of this draft that's currently implementated is documented
in `roll-tm.h`
More engines can (and hopefully will) be added in the future. The first
addition is most likely going to be an updated implementation of MPL
The Big Gotcha
==============
Currently we only support traffic originating and destined inside a single 6LoWPAN
To be able to send multicast traffic from the internet to 6LoWPAN nodes or the other
way round, we need border routers or other gateway devices to be able to achieve
the following:
* Add/Remove Trickle Multicast, RPL or other HBHO headers as necessary for datagrams
entering / exiting the 6LoWPAN
* Advertise multicast group membership to the internet (e.g. with MLD)
These are currently not implemented and are in the ToDo list. Contributions welcome.
Where to Start
==============
The best place in `examples/ipv6/multicast`
There is a cooja example demonstrating basic functionality
How to Use
==========
Look in `core/net/ipv6/multicast/uip-mcast6-engines.h` for a list of supported
multicast engines.
To turn on multicast support, add this line in your `project-` or `contiki-conf.h`
#define UIP_MCAST6_CONF_ENGINE xyz
where xyz is a value from `uip-mcast6-engines.h`
To disable:
#define UIP_MCAST6_CONF_ENGINE 0
You also need to make sure the multicast code gets built. Your example's
(or platform's) Makefile should include this:
MODULES += core/net/ipv6/multicast
How to extend
=============
Let's assume you want to write an engine called foo.
The multicast API defines a multicast engine driver in a fashion similar to
the various NETSTACK layer drivers. This API defines functions for basic
multicast operations (init, in, out).
In order to extend multicast with a new engine, perform the following steps:
- Open `uip-mcast6-engines.h` and assign a unique integer code to your engine
#define UIP_MCAST6_ENGINE_FOO xyz
- Include your engine's `foo.h`
- In `foo.c`, implement:
* `init()`
* `in()`
* `out()`
* Define your driver like so:
`const struct uip_mcast6_driver foo_driver = { ... }`
- If you want to maintain stats:
* Standard multicast stats are maintained in `uip_mcast6_stats`. Don't access
this struct directly, use the macros provided in `uip-mcast6-stats.h` instead
* You can add your own stats extensions. To do so, declare your own stats
struct in your engine's module, e.g `struct foo_stats`
* When you initialise the stats module with `UIP_MCAST6_STATS_INIT`, pass
a pointer to your stats variable as the macro's argument.
An example of how to extend multicast stats, look at the ROLL TM engine
- Open `uip-mcast6.h` and add a section in the `#if` spree. This aims to
configure the uIPv6 core. More specifically, you need to:
* Specify if you want to put RPL in MOP3 by defining
`RPL_CONF_MULTICAST`: 1: MOP 3, 0: non-multicast MOP
* Define your engine details
#define UIP_MCAST6 foo_driver
#define UIP_MCAST6_STATS foo_stats
typedef struct foo_stats uip_mcast6_stats_t;
* Optionally, add a configuration check block to stop builds when the
configuration is not sane.
If you need your engine to perform operations not supported by the generic
UIP_MCAST6 API, you will have to hook those in the uip core manually. As an
example, see how the core is modified so that it can deliver ICMPv6 datagrams
to the ROLL TM engine.

File diff suppressed because it is too large Load diff

View file

@ -1,244 +0,0 @@
/*
* Copyright (c) 2011, Loughborough University - 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.
*/
/**
* \addtogroup uip6-multicast
* @{
*/
/**
* \defgroup roll-tm ROLL Trickle Multicast
*
* IPv6 multicast according to the algorithm in the
* "MCAST Forwarding Using Trickle" internet draft.
*
* The current version of the draft can always be found in
* http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
*
* This implementation is based on the draft version stored in
* ROLL_TM_VER.
*
* In draft v2, the document was renamed to
* "Multicast Protocol for Low power and Lossy Networks (MPL)"
* Due to very significant changes between draft versions 1 and 2,
* MPL will be implemented as a separate engine and this file here
* will provide legacy support for Draft v1.
* @{
*/
/**
* \file
* Header file for the implementation of the ROLL-TM multicast engine
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef ROLL_TM_H_
#define ROLL_TM_H_
#include "contiki-conf.h"
#include "contiki/ipv6/multicast/uip-mcast6-stats.h"
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/* Protocol Constants */
/*---------------------------------------------------------------------------*/
#define ROLL_TM_VER 1 /**< Supported Draft Version */
#define ROLL_TM_ICMP_CODE 0 /**< ROLL TM ICMPv6 code field */
#define ROLL_TM_IP_HOP_LIMIT 0xFF /**< Hop limit for ICMP messages */
#define ROLL_TM_INFINITE_REDUNDANCY 0xFF
#define ROLL_TM_DGRAM_OUT 0
#define ROLL_TM_DGRAM_IN 1
/*
* The draft does not currently specify a default number for the trickle
* interval nor a way to derive it. Examples however hint at 100 msec.
*
* In draft terminology, we use an 'aggressive' policy (M=0) and a conservative
* one (M=1).
*
* When experimenting with the two policies on the sky platform,
* an interval of 125ms proves to be way too low: When we have traffic,
* doublings happen after the interval end and periodics fire after point T
* within the interval (and sometimes even after interval end). When traffic
* settles down, the code compensates the offsets.
*
* We consider 125, 250ms etc because they are nice divisors of 1 sec
* (quotient is power of two). For some machines (e.g sky/msp430,
* sensinode/cc243x), this is also a nice number of clock ticks
*
* After experimentation, the values of Imin leading to best performance are:
* ContikiMAC: Imin=64 (500ms)
* Null RDC: imin=16 (125ms)
*/
/* Configuration for Timer with M=0 (aggressive) */
#ifdef ROLL_TM_CONF_IMIN_0
#define ROLL_TM_IMIN_0 ROLL_TM_CONF_IMIN_0
#else
#define ROLL_TM_IMIN_0 32 /* 250 msec */
#endif
#ifdef ROLL_TM_CONF_IMAX_0
#define ROLL_TM_IMAX_0 ROLL_TM_CONF_IMAX_0
#else
#define ROLL_TM_IMAX_0 1 /* Imax = 500ms */
#endif
#ifdef ROLL_TM_CONF_K_0
#define ROLL_TM_K_0 ROLL_TM_CONF_K_0
#else
#define ROLL_TM_K_0 ROLL_TM_INFINITE_REDUNDANCY
#endif
#ifdef ROLL_TM_CONF_T_ACTIVE_0
#define ROLL_TM_T_ACTIVE_0 ROLL_TM_CONF_T_ACTIVE_0
#else
#define ROLL_TM_T_ACTIVE_0 3
#endif
#ifdef ROLL_TM_CONF_T_DWELL_0
#define ROLL_TM_T_DWELL_0 ROLL_TM_CONF_T_DWELL_0
#else
#define ROLL_TM_T_DWELL_0 11
#endif
/* Configuration for Timer with M=1 (conservative) */
#ifdef ROLL_TM_CONF_IMIN_1
#define ROLL_TM_IMIN_1 ROLL_TM_CONF_IMIN_1
#else
#define ROLL_TM_IMIN_1 64 /* 500 msec */
#endif
#ifdef ROLL_TM_CONF_IMAX_1
#define ROLL_TM_IMAX_1 ROLL_TM_CONF_IMAX_1
#else
#define ROLL_TM_IMAX_1 9 /* Imax = 256 secs */
#endif
#ifdef ROLL_TM_CONF_K_1
#define ROLL_TM_K_1 ROLL_TM_CONF_K_1
#else
#define ROLL_TM_K_1 1
#endif
#ifdef ROLL_TM_CONF_T_ACTIVE_1
#define ROLL_TM_T_ACTIVE_1 ROLL_TM_CONF_T_ACTIVE_1
#else
#define ROLL_TM_T_ACTIVE_1 3
#endif
#ifdef ROLL_TM_CONF_T_DWELL_1
#define ROLL_TM_T_DWELL_1 ROLL_TM_CONF_T_DWELL_1
#else
#define ROLL_TM_T_DWELL_1 12
#endif
/*---------------------------------------------------------------------------*/
/* Configuration */
/*---------------------------------------------------------------------------*/
/**
* Number of Sliding Windows
* In essence: How many unique sources of simultaneous multicast traffic do we
* want to support for our lowpan
* If a node is seeding two multicast streams, parametrized on different M
* values, then this seed will occupy two different sliding windows
*/
#ifdef ROLL_TM_CONF_WINS
#define ROLL_TM_WINS ROLL_TM_CONF_WINS
#else
#define ROLL_TM_WINS 2
#endif
/*---------------------------------------------------------------------------*/
/**
* Maximum Number of Buffered Multicast Messages
* This buffer is shared across all Seed IDs, therefore a new very active Seed
* may eventually occupy all slots. It would make little sense (if any) to
* define support for fewer buffered messages than seeds*2
*/
#ifdef ROLL_TM_CONF_BUFF_NUM
#define ROLL_TM_BUFF_NUM ROLL_TM_CONF_BUFF_NUM
#else
#define ROLL_TM_BUFF_NUM 6
#endif
/*---------------------------------------------------------------------------*/
/**
* Use Short Seed IDs [short: 2, long: 16 (default)]
* It can be argued that we should (and it would be easy to) support both at
* the same time but the draft doesn't list this as a MUST so we opt for
* code/ram savings
*/
#ifdef ROLL_TM_CONF_SHORT_SEEDS
#define ROLL_TM_SHORT_SEEDS ROLL_TM_CONF_SHORT_SEEDS
#else
#define ROLL_TM_SHORT_SEEDS 0
#endif
/*---------------------------------------------------------------------------*/
/**
* Destination address for our ICMPv6 advertisements. The draft gives us a
* choice between LL all-nodes or LL all-routers
*
* We use allrouters unless a conf directive chooses otherwise
*/
#ifdef ROLL_TM_CONF_DEST_ALL_NODES
#define ROLL_TM_DEST_ALL_NODES ROLL_TM_CONF_DEST_ALL_NODES
#else
#define ROLL_TM_DEST_ALL_NODES 0
#endif
/*---------------------------------------------------------------------------*/
/**
* M param for our outgoing messages
* By default, we set the M bit (conservative). Define this as 0 to clear the
* M bit in our outgoing messages (aggressive)
*/
#ifdef ROLL_TM_CONF_SET_M_BIT
#define ROLL_TM_SET_M_BIT ROLL_TM_CONF_SET_M_BIT
#else
#define ROLL_TM_SET_M_BIT 1
#endif
/*---------------------------------------------------------------------------*/
/* Stats datatype */
/*---------------------------------------------------------------------------*/
/**
* \brief Multicast stats extension for the ROLL TM engine
*/
struct roll_tm_stats {
/** Number of received ICMP datagrams */
UIP_MCAST6_STATS_DATATYPE icmp_in;
/** Number of ICMP datagrams sent */
UIP_MCAST6_STATS_DATATYPE icmp_out;
/** Number of malformed ICMP datagrams seen by us */
UIP_MCAST6_STATS_DATATYPE icmp_bad;
};
/*---------------------------------------------------------------------------*/
#endif /* ROLL_TM_H_ */
/*---------------------------------------------------------------------------*/
/** @} */
/** @} */

View file

@ -1,221 +0,0 @@
/*
* Copyright (c) 2010, Loughborough University - 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.
*/
/**
* \addtogroup smrf-multicast
* @{
*/
/**
* \file
* This file implements 'Stateless Multicast RPL Forwarding' (SMRF)
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include <net/ip_buf.h>
#include "contiki.h"
#include "contiki-net.h"
#include "contiki/ipv6/multicast/uip-mcast6.h"
#include "contiki/ipv6/multicast/uip-mcast6-route.h"
#include "contiki/ipv6/multicast/uip-mcast6-stats.h"
#include "contiki/ipv6/multicast/smrf.h"
#include "contiki/rpl/rpl.h"
#include "contiki/netstack.h"
#include "contiki/os/lib/random.h"
#include <string.h>
#define DEBUG DEBUG_NONE
#include "contiki/ip/uip-debug.h"
/*---------------------------------------------------------------------------*/
/* Macros */
/*---------------------------------------------------------------------------*/
/* CCI */
#define SMRF_FWD_DELAY() NETSTACK_RDC.channel_check_interval()
/* Number of slots in the next 500ms */
#define SMRF_INTERVAL_COUNT ((CLOCK_SECOND >> 2) / fwd_delay)
/*---------------------------------------------------------------------------*/
/* Internal Data */
/*---------------------------------------------------------------------------*/
static struct ctimer mcast_periodic;
static uint8_t fwd_delay;
static uint8_t fwd_spread;
/*---------------------------------------------------------------------------*/
/* uIPv6 Pointers */
/*---------------------------------------------------------------------------*/
#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
/*---------------------------------------------------------------------------*/
static void
mcast_fwd(struct net_buf *buf, void *p)
{
UIP_IP_BUF(buf)->ttl--;
tcpip_output(buf, NULL);
uip_len(buf) = 0;
uip_ext_len(buf) = 0;
}
/*---------------------------------------------------------------------------*/
static uint8_t
in(struct net_buf *buf)
{
rpl_dag_t *d; /* Our DODAG */
uip_ipaddr_t *parent_ipaddr; /* Our pref. parent's IPv6 address */
const uip_lladdr_t *parent_lladdr; /* Our pref. parent's LL address */
struct net_buf *netbuf;
/*
* Fetch a pointer to the LL address of our preferred parent
*
* ToDo: This rpl_get_any_dag() call is a dirty replacement of the previous
* rpl_get_dag(RPL_DEFAULT_INSTANCE);
* so that things can compile with the new RPL code. This needs updated to
* read instance ID from the RPL HBHO and use the correct parent accordingly
*/
d = rpl_get_any_dag();
if(!d) {
UIP_MCAST6_STATS_ADD(mcast_dropped);
return UIP_MCAST6_DROP;
}
/* Retrieve our preferred parent's LL address */
parent_ipaddr = rpl_get_parent_ipaddr(d->preferred_parent);
parent_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(parent_ipaddr);
if(parent_lladdr == NULL) {
UIP_MCAST6_STATS_ADD(mcast_dropped);
return UIP_MCAST6_DROP;
}
/*
* We accept a datagram if it arrived from our preferred parent, discard
* otherwise.
*/
if(memcmp(parent_lladdr, &ip_buf_ll_src(buf),
UIP_LLADDR_LEN)) {
PRINTF("SMRF: Routable in but SMRF ignored it\n");
UIP_MCAST6_STATS_ADD(mcast_dropped);
return UIP_MCAST6_DROP;
}
if(UIP_IP_BUF(buf)->ttl <= 1) {
UIP_MCAST6_STATS_ADD(mcast_dropped);
return UIP_MCAST6_DROP;
}
UIP_MCAST6_STATS_ADD(mcast_in_all);
UIP_MCAST6_STATS_ADD(mcast_in_unique);
/* If we have an entry in the mcast routing table, something with
* a higher RPL rank (somewhere down the tree) is a group member */
if(uip_mcast6_route_lookup(&UIP_IP_BUF(buf)->destipaddr)) {
/* If we enter here, we will definitely forward */
UIP_MCAST6_STATS_ADD(mcast_fwd);
/*
* Add a delay (D) of at least SMRF_FWD_DELAY() to compensate for how
* contikimac handles broadcasts. We can't start our TX before the sender
* has finished its own.
*/
fwd_delay = SMRF_FWD_DELAY();
/* Finalise D: D = min(SMRF_FWD_DELAY(), SMRF_MIN_FWD_DELAY) */
#if SMRF_MIN_FWD_DELAY
if(fwd_delay < SMRF_MIN_FWD_DELAY) {
fwd_delay = SMRF_MIN_FWD_DELAY;
}
#endif
if(fwd_delay == 0) {
/* No delay required, send it, do it now, why wait? */
UIP_IP_BUF(buf)->ttl--;
tcpip_output(buf, NULL);
UIP_IP_BUF(buf)->ttl++; /* Restore before potential upstack delivery */
} else {
/* Randomise final delay in [D , D*Spread], step D */
fwd_spread = SMRF_INTERVAL_COUNT;
if(fwd_spread > SMRF_MAX_SPREAD) {
fwd_spread = SMRF_MAX_SPREAD;
}
if(fwd_spread) {
fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread));
}
netbuf = net_buf_clone(buf);
if (netbuf) {
memcpy(net_buf_user_data(netbuf), net_buf_user_data(buf),
buf->user_data_size);
ctimer_set(netbuf, &mcast_periodic, fwd_delay, mcast_fwd, NULL);
} else {
PRINTF("SMRF: cannot clone net buffer\n");
}
}
PRINTF("SMRF: %u bytes: fwd in %u [%u]\n",
uip_len(buf), fwd_delay, fwd_spread);
}
/* Done with this packet unless we are a member of the mcast group */
if(!uip_ds6_is_my_maddr(&UIP_IP_BUF(buf)->destipaddr)) {
PRINTF("SMRF: Not a group member. No further processing\n");
return UIP_MCAST6_DROP;
} else {
PRINTF("SMRF: Ours. Deliver to upper layers\n");
UIP_MCAST6_STATS_ADD(mcast_in_ours);
return UIP_MCAST6_ACCEPT;
}
}
/*---------------------------------------------------------------------------*/
static void
init()
{
UIP_MCAST6_STATS_INIT(NULL);
uip_mcast6_route_init();
}
/*---------------------------------------------------------------------------*/
static void
out()
{
return;
}
/*---------------------------------------------------------------------------*/
/**
* \brief The SMRF engine driver
*/
const struct uip_mcast6_driver smrf_driver = {
"SMRF",
init,
out,
in,
};
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,88 +0,0 @@
/*
* Copyright (c) 2011, Loughborough University - 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.
*/
/**
* \addtogroup uip6-multicast
* @{
*/
/**
* \defgroup smrf-multicast 'Stateless Multicast RPL Forwarding' (SMRF)
*
* SMRF will only work in RPL networks in MOP 3 "Storing with Multicast"
* @{
*/
/**
* \file
* Header file for the SMRF forwarding engine
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef SMRF_H_
#define SMRF_H_
#include "contiki-conf.h"
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/* Configuration */
/*---------------------------------------------------------------------------*/
/* Fmin */
#ifdef SMRF_CONF_MIN_FWD_DELAY
#define SMRF_MIN_FWD_DELAY SMRF_CONF_MIN_FWD_DELAY
#else
#define SMRF_MIN_FWD_DELAY 4
#endif
/* Max Spread */
#ifdef SMRF_CONF_MAX_SPREAD
#define SMRF_MAX_SPREAD SMRF_CONF_MAX_SPREAD
#else
#define SMRF_MAX_SPREAD 4
#endif
/*---------------------------------------------------------------------------*/
/* Stats datatype */
/*---------------------------------------------------------------------------*/
struct smrf_stats {
uint16_t mcast_in_unique;
uint16_t mcast_in_all; /* At layer 3 */
uint16_t mcast_in_ours; /* Unique and we are a group member */
uint16_t mcast_fwd; /* Forwarded by us but we are not the seed */
uint16_t mcast_out; /* We are the seed */
uint16_t mcast_bad;
uint16_t mcast_dropped;
};
/*---------------------------------------------------------------------------*/
#endif /* SMRF_H_ */
/*---------------------------------------------------------------------------*/
/** @} */
/** @} */

View file

@ -1,55 +0,0 @@
/*
* Copyright (c) 2011, Loughborough University - 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.
*/
/**
* \addtogroup uip6-multicast
* @{
*/
/**
* \file
* Header file with definition of multicast engine constants
*
* When writing a new engine, add it here with a unique number and
* then modify uip-mcast6.h accordingly
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef UIP_MCAST6_ENGINES_H_
#define UIP_MCAST6_ENGINES_H_
#define UIP_MCAST6_ENGINE_NONE 0 /**< Selecting this disables mcast */
#define UIP_MCAST6_ENGINE_SMRF 1 /**< The SMRF engine */
#define UIP_MCAST6_ENGINE_ROLL_TM 2 /**< The ROLL TM engine */
#endif /* UIP_MCAST6_ENGINES_H_ */
/** @} */

View file

@ -1,135 +0,0 @@
/*
* Copyright (c) 2011, Loughborough University - 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 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.
*/
/**
* \addtogroup uip6-multicast
* @{
*/
/**
* \file
* Multicast routing table manipulation
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "contiki.h"
#include "lib/list.h"
#include "lib/memb.h"
#include "contiki/ip/uip.h"
#include "contiki/ipv6/multicast/uip-mcast6-route.h"
#include <stdint.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
/* Size of the multicast routing table */
#ifdef UIP_MCAST6_ROUTE_CONF_ROUTES
#define UIP_MCAST6_ROUTE_ROUTES UIP_MCAST6_ROUTE_CONF_ROUTES
#else
#define UIP_MCAST6_ROUTE_ROUTES 1
#endif /* UIP_CONF_DS6_MCAST_ROUTES */
/*---------------------------------------------------------------------------*/
LIST(mcast_route_list);
MEMB(mcast_route_memb, uip_mcast6_route_t, UIP_MCAST6_ROUTE_ROUTES);
static uip_mcast6_route_t *locmcastrt;
/*---------------------------------------------------------------------------*/
uip_mcast6_route_t *
uip_mcast6_route_lookup(uip_ipaddr_t *group)
{
locmcastrt = NULL;
for(locmcastrt = list_head(mcast_route_list);
locmcastrt != NULL;
locmcastrt = list_item_next(locmcastrt)) {
if(uip_ipaddr_cmp(&locmcastrt->group, group)) {
return locmcastrt;
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uip_mcast6_route_t *
uip_mcast6_route_add(uip_ipaddr_t *group)
{
/* _lookup must return NULL, i.e. the prefix does not exist in our table */
locmcastrt = uip_mcast6_route_lookup(group);
if(locmcastrt == NULL) {
/* Allocate an entry and add the group to the list */
locmcastrt = memb_alloc(&mcast_route_memb);
if(locmcastrt == NULL) {
return NULL;
}
list_add(mcast_route_list, locmcastrt);
}
/* Reaching here means we either found the prefix or allocated a new one */
uip_ipaddr_copy(&(locmcastrt->group), group);
return locmcastrt;
}
/*---------------------------------------------------------------------------*/
void
uip_mcast6_route_rm(uip_mcast6_route_t *route)
{
/* Make sure it's actually in the list */
for(locmcastrt = list_head(mcast_route_list);
locmcastrt != NULL;
locmcastrt = list_item_next(locmcastrt)) {
if(locmcastrt == route) {
list_remove(mcast_route_list, route);
memb_free(&mcast_route_memb, route);
return;
}
}
}
/*---------------------------------------------------------------------------*/
uip_mcast6_route_t *
uip_mcast6_route_list_head(void)
{
return list_head(mcast_route_list);
}
/*---------------------------------------------------------------------------*/
int
uip_mcast6_route_count(void)
{
return list_length(mcast_route_list);
}
/*---------------------------------------------------------------------------*/
void
uip_mcast6_route_init()
{
memb_init(&mcast_route_memb);
list_init(mcast_route_list);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,110 +0,0 @@
/*
* Copyright (c) 2011, Loughborough University - 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 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.
*/
/**
* \addtogroup uip6-multicast
* @{
*/
/**
* \file
* Header file for multicast routing table manipulation
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef UIP_MCAST6_ROUTE_H_
#define UIP_MCAST6_ROUTE_H_
#include "contiki.h"
#include "contiki/ip/uip.h"
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/** \brief An entry in the multicast routing table */
typedef struct uip_mcast6_route {
struct uip_mcast6_route *next; /**< Routes are arranged in a linked list */
uip_ipaddr_t group; /**< The multicast group */
uint32_t lifetime; /**< Entry lifetime seconds */
void *dag; /**< Pointer to an rpl_dag_t struct */
} uip_mcast6_route_t;
/*---------------------------------------------------------------------------*/
/** \name Multicast Routing Table Manipulation */
/** @{ */
/**
* \brief Lookup a multicast route
* \param group A pointer to the multicast group to be searched for
* \return A pointer to the new routing entry, or NULL if the route could not
* be found
*/
uip_mcast6_route_t *uip_mcast6_route_lookup(uip_ipaddr_t *group);
/**
* \brief Add a multicast route
* \param group A pointer to the multicast group to be added
* \return A pointer to the new route, or NULL if the route could not be added
*/
uip_mcast6_route_t *uip_mcast6_route_add(uip_ipaddr_t *group);
/**
* \brief Remove a multicast route
* \param route A pointer to the route to be removed
*/
void uip_mcast6_route_rm(uip_mcast6_route_t *route);
/**
* \brief Retrieve the count of multicast routes
* \return The number of multicast routes
*/
int uip_mcast6_route_count(void);
/**
* \brief Retrieve a pointer to the start of the multicast routes list
* \return A pointer to the start of the multicast routes
*
* If the multicast routes list is empty, this function will return NULL
*/
uip_mcast6_route_t *uip_mcast6_route_list_head(void);
/*---------------------------------------------------------------------------*/
/**
* \brief Multicast routing table init routine
*
* Multicast routing tables are not necessarily required by all
* multicast engines. For instance, trickle multicast does not rely on
* the existence of a routing table. Therefore, this function here
* should be invoked by each engine's init routine only if the relevant
* functionality is required. This is also why this function should not
* get hooked into the uip-ds6 core.
*/
void uip_mcast6_route_init(void);
/** @} */
#endif /* UIP_MCAST6_ROUTE_H_ */
/** @} */

View file

@ -1,54 +0,0 @@
/*
* Copyright (c) 2014, University of Bristol - http://www.bris.ac.uk
* 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.
*/
/**
* \addtogroup uip6-multicast
* @{
*/
/**
* \file
* IPv6 multicast forwarding stats maintenance
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#include "contiki/ipv6/multicast/uip-mcast6-stats.h"
#include <string.h>
/*---------------------------------------------------------------------------*/
uip_mcast6_stats_t uip_mcast6_stats;
/*---------------------------------------------------------------------------*/
void
uip_mcast6_stats_init(void *stats)
{
memset(&uip_mcast6_stats, 0, sizeof(uip_mcast6_stats));
uip_mcast6_stats.engine_stats = stats;
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,117 +0,0 @@
/*
* Copyright (c) 2014, University of Bristol - http://www.bris.ac.uk
* 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.
*/
/**
* \addtogroup uip6-multicast
* @{
*/
/**
* \file
* Header file for IPv6 multicast forwarding stats maintenance
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef UIP_MCAST6_STATS_H_
#define UIP_MCAST6_STATS_H_
/*---------------------------------------------------------------------------*/
#include "contiki-conf.h"
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/* The platform can override the stats datatype */
#ifdef UIP_MCAST6_CONF_STATS_DATATYPE
#define UIP_MCAST6_STATS_DATATYPE UIP_MCAST6_CONF_STATS_DATATYPE
#else
#define UIP_MCAST6_STATS_DATATYPE uint16_t
#endif
/*---------------------------------------------------------------------------*/
#ifdef UIP_MCAST6_CONF_STATS
#define UIP_MCAST6_STATS UIP_MCAST6_CONF_STATS
#else
#define UIP_MCAST6_STATS 0
#endif
/*---------------------------------------------------------------------------*/
/* Stats datatype */
/*---------------------------------------------------------------------------*/
/**
* \brief A data structure used to maintain multicast stats
*
* Each engine can extend this structure via the engine_stats field
*/
typedef struct uip_mcast6_stats {
/** Count of unique datagrams received */
UIP_MCAST6_STATS_DATATYPE mcast_in_unique;
/** Count of all datagrams received */
UIP_MCAST6_STATS_DATATYPE mcast_in_all;
/** Count of datagrams received for a group that we have joined */
UIP_MCAST6_STATS_DATATYPE mcast_in_ours;
/** Count of datagrams forwarded by us but we are not the seed */
UIP_MCAST6_STATS_DATATYPE mcast_fwd;
/** Count of multicast datagrams originated by us */
UIP_MCAST6_STATS_DATATYPE mcast_out;
/** Count of malformed multicast datagrams seen by us */
UIP_MCAST6_STATS_DATATYPE mcast_bad;
/** Count of multicast datagrams correclty formed but dropped by us */
UIP_MCAST6_STATS_DATATYPE mcast_dropped;
/** Opaque pointer to an engine's additional stats */
void *engine_stats;
} uip_mcast6_stats_t;
/*---------------------------------------------------------------------------*/
/* Access macros */
/*---------------------------------------------------------------------------*/
#if UIP_MCAST6_STATS
/* Don't access this variable directly, use the macros below */
extern uip_mcast6_stats_t uip_mcast6_stats;
#define UIP_MCAST6_STATS_ADD(x) uip_mcast6_stats.x++
#define UIP_MCAST6_STATS_GET(x) uip_mcast6_stats.x
#define UIP_MCAST6_STATS_INIT(s) uip_mcast6_stats_init(s)
#else /* UIP_MCAST6_STATS */
#define UIP_MCAST6_STATS_ADD(x)
#define UIP_MCAST6_STATS_GET(x) 0
#define UIP_MCAST6_STATS_INIT(s)
#endif /* UIP_MCAST6_STATS */
/*---------------------------------------------------------------------------*/
/**
* \brief Initialise multicast stats
* \param stats A pointer to a struct holding an engine's additional statistics
*/
void uip_mcast6_stats_init(void *stats);
/*---------------------------------------------------------------------------*/
#endif /* UIP_MCAST6_STATS_H_ */
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,181 +0,0 @@
/*
* Copyright (c) 2011, Loughborough University - 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.
*/
/**
* \addtogroup uip6
* @{
*/
/**
* \defgroup uip6-multicast IPv6 Multicast Forwarding
*
* We currently support 2 engines:
* - 'Stateless Multicast RPL Forwarding' (SMRF)
* RPL does group management as per the RPL docs, SMRF handles datagram
* forwarding
* - 'Multicast Forwarding with Trickle' according to the algorithm described
* in the internet draft:
* http://tools.ietf.org/html/draft-ietf-roll-trickle-mcast
*
* @{
*/
/**
* \file
* This header file contains configuration directives for uIPv6
* multicast support.
*
* \author
* George Oikonomou - <oikonomou@users.sourceforge.net>
*/
#ifndef UIP_MCAST6_H_
#define UIP_MCAST6_H_
#include <net/buf.h>
#include "contiki-conf.h"
#include "contiki/ipv6/multicast/uip-mcast6-engines.h"
#include "contiki/ipv6/multicast/uip-mcast6-route.h"
#include "contiki/ipv6/multicast/smrf.h"
#include "contiki/ipv6/multicast/roll-tm.h"
#include <string.h>
/*---------------------------------------------------------------------------*/
/* Constants */
/*---------------------------------------------------------------------------*/
#define UIP_MCAST6_DROP 0
#define UIP_MCAST6_ACCEPT 1
/*---------------------------------------------------------------------------*/
/* Multicast Address Scopes (RFC 4291 & draft-ietf-6man-multicast-scopes) */
#define UIP_MCAST6_SCOPE_INTERFACE 0x01
#define UIP_MCAST6_SCOPE_LINK_LOCAL 0x02
#define UIP_MCAST6_SCOPE_REALM_LOCAL 0x03 /* draft-ietf-6man-multicast-scopes */
#define UIP_MCAST6_SCOPE_ADMIN_LOCAL 0x04
#define UIP_MCAST6_SCOPE_SITE_LOCAL 0x05
#define UIP_MCAST6_SCOPE_ORG_LOCAL 0x08
#define UIP_MCAST6_SCOPE_GLOBAL 0x0E
/*---------------------------------------------------------------------------*/
/* Choose an engine or turn off based on user configuration */
/*---------------------------------------------------------------------------*/
#ifdef UIP_MCAST6_CONF_ENGINE
#define UIP_MCAST6_ENGINE UIP_MCAST6_CONF_ENGINE
#else
#define UIP_MCAST6_ENGINE UIP_MCAST6_ENGINE_NONE
#endif
/*---------------------------------------------------------------------------*/
/*
* Multicast API. Similar to NETSTACK, each engine must define a driver and
* populate the fields with suitable function pointers
*/
/**
* \brief The data structure used to represent a multicast engine
*/
struct uip_mcast6_driver {
/** The driver's name */
char *name;
/** Initialize the multicast engine */
void (* init)(void);
/**
* \brief Process an outgoing datagram with a multicast IPv6 destination
* address
*
* This may be needed if the multicast engine needs to, for example,
* add IPv6 extension headers to the datagram, cache it, decide it
* needs dropped etc.
*
* It is sometimes desirable to let the engine handle datagram
* dispatch instead of letting the networking core do it. If the
* engine decides to send the datagram itself, it must afterwards
* set uip_len = 0 to prevent the networking core from sending too
*/
void (* out)(void);
/**
* \brief Process an incoming multicast datagram and determine whether it
* should be delivered up the stack or not.
*
* \return 0: Drop, 1: Deliver
*
*
* When a datagram with a multicast destination address is received,
* the forwarding logic in core is bypassed. Instead, we let the
* multicast engine handle forwarding internally if and as necessary.
* This function is where forwarding logic must be hooked in.
*
* Once the engine is done with forwarding, it must signal via the
* return value whether the datagram needs delivered up the network
* stack.
*/
uint8_t (* in)(struct net_buf *buf);
};
/*---------------------------------------------------------------------------*/
/**
* \brief Get a multicast address' scope.
* a is of type uip_ip6addr_t*
*/
#define uip_mcast6_get_address_scope(a) ((a)->u8[1] & 0x0F)
/*---------------------------------------------------------------------------*/
/* Configure multicast and core/net to play nicely with the selected engine */
#if UIP_MCAST6_ENGINE
/* Enable Multicast hooks in the uip6 core */
#define UIP_CONF_IPV6_MULTICAST 1
#if UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_ROLL_TM
#define RPL_CONF_MULTICAST 0 /* Not used by trickle */
#define UIP_CONF_IPV6_ROLL_TM 1 /* ROLL Trickle ICMP type support */
#define UIP_MCAST6 roll_tm_driver
#elif UIP_MCAST6_ENGINE == UIP_MCAST6_ENGINE_SMRF
#define RPL_CONF_MULTICAST 1
#define UIP_MCAST6 smrf_driver
#else
#error "Multicast Enabled with an Unknown Engine."
#error "Check the value of UIP_MCAST6_CONF_ENGINE in conf files."
#endif
#endif /* UIP_MCAST6_ENGINE */
extern const struct uip_mcast6_driver UIP_MCAST6;
/*---------------------------------------------------------------------------*/
/* Configuration Checks */
/*---------------------------------------------------------------------------*/
#if RPL_CONF_MULTICAST && (!UIP_CONF_IPV6_RPL)
#error "The selected Multicast mode requires UIP_CONF_IPV6_RPL != 0"
#error "Check the value of UIP_CONF_IPV6_RPL in conf files."
#endif
/*---------------------------------------------------------------------------*/
#endif /* UIP_MCAST6_H_ */
/*---------------------------------------------------------------------------*/
/** @} */
/** @} */

View file

@ -1,335 +0,0 @@
/*
* Copyright (c) 2013, 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.
*
*
*/
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* IPv6 Neighbor cache (link-layer/IPv6 address mapping)
* \author Mathilde Durvy <mdurvy@cisco.com>
* \author Julien Abeille <jabeille@cisco.com>
* \author Simon Duquennoy <simonduq@sics.se>
*
*/
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include "lib/list.h"
#include "contiki/linkaddr.h"
#include "contiki/packetbuf.h"
#include "contiki/ipv6/uip-ds6-nbr.h"
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV6_NBR_CACHE
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
#ifdef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED
#define NEIGHBOR_STATE_CHANGED(n) UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED(n)
void NEIGHBOR_STATE_CHANGED(uip_ds6_nbr_t *n);
#else
#define NEIGHBOR_STATE_CHANGED(n)
#endif /* UIP_DS6_CONF_NEIGHBOR_STATE_CHANGED */
#ifdef UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK
#define LINK_NEIGHBOR_CALLBACK(addr, status, numtx) UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK(addr, status, numtx)
void LINK_NEIGHBOR_CALLBACK(const linkaddr_t *addr, int status, int numtx);
#else
#define LINK_NEIGHBOR_CALLBACK(addr, status, numtx)
#endif /* UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK */
NBR_TABLE_GLOBAL(uip_ds6_nbr_t, ds6_neighbors);
/*---------------------------------------------------------------------------*/
void
uip_ds6_neighbors_init(void)
{
nbr_table_register(ds6_neighbors, (nbr_table_callback *)uip_ds6_nbr_rm);
}
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
uint8_t isrouter, uint8_t state)
{
uip_ds6_nbr_t *nbr = nbr_table_add_lladdr(ds6_neighbors, (linkaddr_t*)lladdr);
if(nbr) {
uip_ipaddr_copy(&nbr->ipaddr, ipaddr);
nbr->isrouter = isrouter;
nbr->state = state;
#if UIP_CONF_IPV6_QUEUE_PKT
uip_packetqueue_new(&nbr->packethandle);
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
/* timers are set separately, for now we put them in expired state */
stimer_set(&nbr->reachable, 0);
stimer_set(&nbr->sendns, 0);
nbr->nscount = 0;
PRINTF("Adding neighbor with ip addr ");
PRINT6ADDR(ipaddr);
PRINTF(" link addr ");
PRINTLLADDR(lladdr);
PRINTF(" state %u\n", state);
NEIGHBOR_STATE_CHANGED(nbr);
return nbr;
} else {
PRINTF("uip_ds6_nbr_add drop ip addr ");
PRINT6ADDR(ipaddr);
PRINTF(" link addr (%p) ", lladdr);
PRINTLLADDR(lladdr);
PRINTF(" state %u\n", state);
return NULL;
}
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr)
{
if(nbr != NULL) {
#if UIP_CONF_IPV6_QUEUE_PKT
uip_packetqueue_free(&nbr->packethandle);
#endif /* UIP_CONF_IPV6_QUEUE_PKT */
NEIGHBOR_STATE_CHANGED(nbr);
nbr_table_remove(ds6_neighbors, nbr);
}
return;
}
/*---------------------------------------------------------------------------*/
const uip_ipaddr_t *
uip_ds6_nbr_get_ipaddr(const uip_ds6_nbr_t *nbr)
{
return (nbr != NULL) ? &nbr->ipaddr : NULL;
}
/*---------------------------------------------------------------------------*/
const uip_lladdr_t *
uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr)
{
return (const uip_lladdr_t *)nbr_table_get_lladdr(ds6_neighbors, nbr);
}
/*---------------------------------------------------------------------------*/
int
uip_ds6_nbr_num(void)
{
uip_ds6_nbr_t *nbr;
int num;
num = 0;
for(nbr = nbr_table_head(ds6_neighbors);
nbr != NULL;
nbr = nbr_table_next(ds6_neighbors, nbr)) {
num++;
}
return num;
}
/*---------------------------------------------------------------------------*/
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);
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uip_ds6_nbr_t *
uip_ds6_nbr_ll_lookup(const uip_lladdr_t *lladdr)
{
return nbr_table_get_from_lladdr(ds6_neighbors, (linkaddr_t*)lladdr);
}
/*---------------------------------------------------------------------------*/
uip_ipaddr_t *
uip_ds6_nbr_ipaddr_from_lladdr(const uip_lladdr_t *lladdr)
{
uip_ds6_nbr_t *nbr = uip_ds6_nbr_ll_lookup(lladdr);
return nbr ? &nbr->ipaddr : NULL;
}
/*---------------------------------------------------------------------------*/
const uip_lladdr_t *
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;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_link_neighbor_callback(const linkaddr_t *dest, int status, int numtx)
{
if(linkaddr_cmp(dest, &linkaddr_null)) {
return;
}
LINK_NEIGHBOR_CALLBACK(dest, status, numtx);
#if UIP_DS6_LL_NUD
/* From RFC4861, page 72, last paragraph of section 7.3.3:
*
* "In some cases, link-specific information may indicate that a path to
* a neighbor has failed (e.g., the resetting of a virtual circuit). In
* such cases, link-specific information may be used to purge Neighbor
* Cache entries before the Neighbor Unreachability Detection would do
* so. However, link-specific information MUST NOT be used to confirm
* the reachability of a neighbor; such information does not provide
* end-to-end confirmation between neighboring IP layers."
*
* However, we assume that receiving a link layer ack ensures the delivery
* of the transmitted packed to the IP stack of the neighbour. This is a
* fair assumption and allows battery powered nodes save some battery by
* not re-testing the state of a neighbour periodically if it
* 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);
PRINTF("uip-ds6-neighbor : received a link layer ACK : ");
PRINTLLADDR((uip_lladdr_t *)dest);
PRINTF(" is reachable.\n");
}
}
#endif /* UIP_DS6_LL_NUD */
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_neighbor_periodic(struct net_buf *buf)
{
/* Periodic processing on neighbors */
uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors);
while(nbr != NULL) {
switch(nbr->state) {
case NBR_REACHABLE:
if(stimer_expired(&nbr->reachable)) {
#if UIP_CONF_IPV6_RPL
/* when a neighbor leave it's REACHABLE state and is a default router,
instead of going to STALE state it enters DELAY state in order to
force a NUD on it. Otherwise, if there is no upward traffic, the
node never knows if the default router is still reachable. This
mimics the 6LoWPAN-ND behavior.
*/
if(uip_ds6_defrt_lookup(&nbr->ipaddr) != NULL) {
PRINTF("REACHABLE: defrt moving to DELAY (");
PRINT6ADDR(&nbr->ipaddr);
PRINTF(")\n");
nbr->state = NBR_DELAY;
stimer_set(&nbr->reachable, UIP_ND6_DELAY_FIRST_PROBE_TIME);
nbr->nscount = 0;
} else {
PRINTF("REACHABLE: moving to STALE (");
PRINT6ADDR(&nbr->ipaddr);
PRINTF(")\n");
nbr->state = NBR_STALE;
}
#else /* UIP_CONF_IPV6_RPL */
PRINTF("REACHABLE: moving to STALE (");
PRINT6ADDR(&nbr->ipaddr);
PRINTF(")\n");
nbr->state = NBR_STALE;
#endif /* UIP_CONF_IPV6_RPL */
}
break;
#if UIP_ND6_SEND_NA
case NBR_INCOMPLETE:
if(nbr->nscount >= UIP_ND6_MAX_MULTICAST_SOLICIT) {
uip_ds6_nbr_rm(nbr);
} else if(stimer_expired(&nbr->sendns) && (!buf || uip_len(buf) == 0)) {
nbr->nscount++;
PRINTF("NBR_INCOMPLETE: NS %u\n", nbr->nscount);
uip_nd6_ns_output(buf, NULL, NULL, &nbr->ipaddr);
stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
}
break;
case NBR_DELAY:
if(stimer_expired(&nbr->reachable)) {
nbr->state = NBR_PROBE;
nbr->nscount = 0;
PRINTF("DELAY: moving to PROBE\n");
stimer_set(&nbr->sendns, 0);
}
break;
case NBR_PROBE:
if(nbr->nscount >= UIP_ND6_MAX_UNICAST_SOLICIT) {
uip_ds6_defrt_t *locdefrt;
PRINTF("PROBE END\n");
if((locdefrt = uip_ds6_defrt_lookup(&nbr->ipaddr)) != NULL) {
if (!locdefrt->isinfinite) {
uip_ds6_defrt_rm(locdefrt);
}
}
uip_ds6_nbr_rm(nbr);
} else if(stimer_expired(&nbr->sendns) && (!buf || uip_len(buf) == 0)) {
nbr->nscount++;
PRINTF("PROBE: NS %u\n", nbr->nscount);
uip_nd6_ns_output(buf, NULL, &nbr->ipaddr, &nbr->ipaddr);
stimer_set(&nbr->sendns, uip_ds6_if.retrans_timer / 1000);
}
break;
#endif /* UIP_ND6_SEND_NA */
default:
break;
}
nbr = nbr_table_next(ds6_neighbors, nbr);
}
}
/*---------------------------------------------------------------------------*/
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_expiring = NULL;
while(nbr != NULL) {
if(nbr_expiring != NULL) {
clock_time_t curr = stimer_remaining(&nbr->reachable);
if(curr < stimer_remaining(&nbr->reachable)) {
nbr_expiring = nbr;
}
} else {
nbr_expiring = nbr;
}
nbr = nbr_table_next(ds6_neighbors, nbr);
}
return nbr_expiring;
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,114 +0,0 @@
/*
* Copyright (c) 2013, 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.
*
*
*/
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* IPv6 Neighbor cache (link-layer/IPv6 address mapping)
* \author Mathilde Durvy <mdurvy@cisco.com>
* \author Julien Abeille <jabeille@cisco.com>
* \author Simon Duquennoy <simonduq@sics.se>
*
*/
#include <net/buf.h>
#include "contiki/ip/uip.h"
#include "contiki/nbr-table.h"
#include "sys/stimer.h"
#include "contiki/ipv6/uip-ds6.h"
#include "contiki/nbr-table.h"
#if UIP_CONF_IPV6_QUEUE_PKT
#include "contiki/ip/uip-packetqueue.h"
#endif /*UIP_CONF_QUEUE_PKT */
#ifndef UIP_DS6_NEIGHBOR_H_
#define UIP_DS6_NEIGHBOR_H_
/*--------------------------------------------------*/
/** \brief Possible states for the nbr cache entries */
#define NBR_INCOMPLETE 0
#define NBR_REACHABLE 1
#define NBR_STALE 2
#define NBR_DELAY 3
#define NBR_PROBE 4
NBR_TABLE_DECLARE(ds6_neighbors);
/** \brief An entry in the nbr cache */
typedef struct uip_ds6_nbr {
uip_ipaddr_t ipaddr;
struct stimer reachable;
struct stimer sendns;
uint8_t nscount;
uint8_t isrouter;
uint8_t state;
uint16_t link_metric;
#if UIP_CONF_IPV6_QUEUE_PKT
struct uip_packetqueue_handle packethandle;
#define UIP_DS6_NBR_PACKET_LIFETIME CLOCK_SECOND * 4
#endif /*UIP_CONF_QUEUE_PKT */
} uip_ds6_nbr_t;
void uip_ds6_neighbors_init(void);
/** \brief Neighbor Cache basic routines */
uip_ds6_nbr_t *uip_ds6_nbr_add(const uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr,
uint8_t isrouter, uint8_t state);
void uip_ds6_nbr_rm(uip_ds6_nbr_t *nbr);
const uip_lladdr_t *uip_ds6_nbr_get_ll(const uip_ds6_nbr_t *nbr);
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);
const uip_lladdr_t *uip_ds6_nbr_lladdr_from_ipaddr(const uip_ipaddr_t *ipaddr);
void uip_ds6_link_neighbor_callback(const linkaddr_t *dest, int status, int numtx);
void uip_ds6_neighbor_periodic(struct net_buf *buf);
int uip_ds6_nbr_num(void);
/**
* \brief
* This searches inside the neighbor table for the neighbor that is about to
* expire the next.
*
* \return
* A reference to the neighbor about to expire the next or NULL if
* table is empty.
*/
uip_ds6_nbr_t *uip_ds6_get_least_lifetime_neighbor(void);
#endif /* UIP_DS6_NEIGHBOR_H_ */
/** @} */

View file

@ -1,649 +0,0 @@
/*
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* Routing table manipulation
*/
#include "contiki/ipv6/uip-ds6.h"
#include "contiki/ip/uip.h"
#include "lib/list.h"
#include "lib/memb.h"
#include "contiki/nbr-table.h"
#include <string.h>
/* The nbr_routes holds a neighbor table to be able to maintain
information about what routes go through what neighbor. This
neighbor table is registered with the central nbr-table repository
so that it will be maintained along with the rest of the neighbor
tables in the system. */
NBR_TABLE(struct uip_ds6_route_neighbor_routes, nbr_routes);
MEMB(neighborroutememb, struct uip_ds6_route_neighbor_route, UIP_DS6_ROUTE_NB);
/* Each route is repressented by a uip_ds6_route_t structure and
memory for each route is allocated from the routememb memory
block. These routes are maintained on the routelist. */
LIST(routelist);
MEMB(routememb, uip_ds6_route_t, UIP_DS6_ROUTE_NB);
/* Default routes are held on the defaultrouterlist and their
structures are allocated from the defaultroutermemb memory block.*/
LIST(defaultrouterlist);
MEMB(defaultroutermemb, uip_ds6_defrt_t, UIP_DS6_DEFRT_NB);
#if UIP_DS6_NOTIFICATIONS
LIST(notificationlist);
#endif
static int num_routes = 0;
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV6_ROUTE
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
static void rm_routelist_callback(nbr_table_item_t *ptr);
/*---------------------------------------------------------------------------*/
#if DEBUG != DEBUG_NONE
static void
assert_nbr_routes_list_sane(void)
{
uip_ds6_route_t *r;
int count;
/* Check if the route list has an infinite loop. */
for(r = uip_ds6_route_head(),
count = 0;
r != NULL &&
count < UIP_DS6_ROUTE_NB * 2;
r = uip_ds6_route_next(r),
count++);
if(count > UIP_DS6_ROUTE_NB) {
printf("uip-ds6-route.c: assert_nbr_routes_list_sane route list is in infinite loop\n");
}
/* Make sure that the route list has as many entries as the
num_routes vairable. */
if(count < num_routes) {
printf("uip-ds6-route.c: assert_nbr_routes_list_sane too few entries on route list: should be %d, is %d, max %d\n",
num_routes, count, UIP_CONF_MAX_ROUTES);
}
}
#endif /* DEBUG != DEBUG_NONE */
/*---------------------------------------------------------------------------*/
#if UIP_DS6_NOTIFICATIONS
static void
call_route_callback(int event, uip_ipaddr_t *route,
uip_ipaddr_t *nexthop)
{
int num;
struct uip_ds6_notification *n;
for(n = list_head(notificationlist);
n != NULL;
n = list_item_next(n)) {
if(event == UIP_DS6_NOTIFICATION_DEFRT_ADD ||
event == UIP_DS6_NOTIFICATION_DEFRT_RM) {
num = list_length(defaultrouterlist);
} else {
num = num_routes;
}
n->callback(event, route, nexthop, num);
}
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_notification_add(struct uip_ds6_notification *n,
uip_ds6_notification_callback c)
{
if(n != NULL && c != NULL) {
n->callback = c;
list_add(notificationlist, n);
}
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_notification_rm(struct uip_ds6_notification *n)
{
list_remove(notificationlist, n);
}
#endif
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_init(void)
{
memb_init(&routememb);
list_init(routelist);
nbr_table_register(nbr_routes,
(nbr_table_callback *)rm_routelist_callback);
memb_init(&defaultroutermemb);
list_init(defaultrouterlist);
#if UIP_DS6_NOTIFICATIONS
list_init(notificationlist);
#endif
}
/*---------------------------------------------------------------------------*/
static uip_lladdr_t *
uip_ds6_route_nexthop_lladdr(uip_ds6_route_t *route)
{
if(route != NULL) {
return (uip_lladdr_t *)nbr_table_get_lladdr(nbr_routes,
route->neighbor_routes);
} else {
return NULL;
}
}
/*---------------------------------------------------------------------------*/
uip_ipaddr_t *
uip_ds6_route_nexthop(uip_ds6_route_t *route)
{
if(route != NULL) {
return uip_ds6_nbr_ipaddr_from_lladdr(uip_ds6_route_nexthop_lladdr(route));
} else {
return NULL;
}
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_head(void)
{
return list_head(routelist);
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_next(uip_ds6_route_t *r)
{
if(r != NULL) {
uip_ds6_route_t *n = list_item_next(r);
return n;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
int
uip_ds6_route_num_routes(void)
{
return num_routes;
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_lookup(uip_ipaddr_t *addr)
{
uip_ds6_route_t *r;
uip_ds6_route_t *found_route;
uint8_t longestmatch;
PRINTF("uip-ds6-route: Looking up route for ");
PRINT6ADDR(addr);
PRINTF("\n");
found_route = NULL;
longestmatch = 0;
for(r = uip_ds6_route_head();
r != NULL;
r = uip_ds6_route_next(r)) {
if(r->length >= longestmatch &&
uip_ipaddr_prefixcmp(addr, &r->ipaddr, r->length)) {
longestmatch = r->length;
found_route = r;
/* check if total match - e.g. all 128 bits do match */
if(longestmatch == 128) {
break;
}
}
}
if(found_route != NULL) {
PRINTF("uip-ds6-route: Found route: ");
PRINT6ADDR(addr);
PRINTF(" via ");
PRINT6ADDR(uip_ds6_route_nexthop(found_route));
PRINTF("\n");
} else {
PRINTF("uip-ds6-route: No route found\n");
}
if(found_route != NULL && found_route != list_head(routelist)) {
/* If we found a route, we put it at the start of the routeslist
list. The list is ordered by how recently we looked them up:
the least recently used route will be at the end of the
list - for fast lookups (assuming multiple packets to the same node). */
list_remove(routelist, found_route);
list_push(routelist, found_route);
}
return found_route;
}
/*---------------------------------------------------------------------------*/
uip_ds6_route_t *
uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
uip_ipaddr_t *nexthop)
{
uip_ds6_route_t *r;
struct uip_ds6_route_neighbor_route *nbrr;
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
/* Get link-layer address of next hop, make sure it is in neighbor table */
const uip_lladdr_t *nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop);
if(nexthop_lladdr == NULL) {
PRINTF("uip_ds6_route_add: neighbor link-local address unknown for ");
PRINT6ADDR(nexthop);
PRINTF("\n");
return NULL;
}
/* First make sure that we don't add a route twice. If we find an
existing route for our destination, we'll delete the old
one first. */
r = uip_ds6_route_lookup(ipaddr);
if(r != NULL) {
uip_ipaddr_t *current_nexthop;
current_nexthop = uip_ds6_route_nexthop(r);
if(current_nexthop != NULL && uip_ipaddr_cmp(nexthop, current_nexthop)) {
/* no need to update route - already correct! */
return r;
}
PRINTF("uip_ds6_route_add: old route for ");
PRINT6ADDR(ipaddr);
PRINTF(" found, deleting it\n");
uip_ds6_route_rm(r);
}
{
struct uip_ds6_route_neighbor_routes *routes;
/* If there is no routing entry, create one. We first need to
check if we have room for this route. If not, we remove the
least recently used one we have. */
if(uip_ds6_route_num_routes() == UIP_DS6_ROUTE_NB) {
/* Removing the oldest route entry from the route table. The
least recently used route is the first route on the list. */
uip_ds6_route_t *oldest;
oldest = list_tail(routelist); /* uip_ds6_route_head(); */
PRINTF("uip_ds6_route_add: dropping route to ");
PRINT6ADDR(&oldest->ipaddr);
PRINTF("\n");
uip_ds6_route_rm(oldest);
}
/* Every neighbor on our neighbor table holds a struct
uip_ds6_route_neighbor_routes which holds a list of routes that
go through the neighbor. We add our route entry to this list.
We first check to see if we already have this neighbor in our
nbr_route table. If so, the neighbor already has a route entry
list.
*/
routes = nbr_table_get_from_lladdr(nbr_routes,
(linkaddr_t *)nexthop_lladdr);
if(routes == NULL) {
/* If the neighbor did not have an entry in our neighbor table,
we create one. The nbr_table_add_lladdr() function returns a
pointer to a pointer that we may use for our own purposes. We
initialize this pointer with the list of routing entries that
are attached to this neighbor. */
routes = nbr_table_add_lladdr(nbr_routes,
(linkaddr_t *)nexthop_lladdr);
if(routes == NULL) {
/* This should not happen, as we explicitly deallocated one
route table entry above. */
PRINTF("uip_ds6_route_add: could not allocate neighbor table entry\n");
return NULL;
}
LIST_STRUCT_INIT(routes, route_list);
}
/* Allocate a routing entry and populate it. */
r = memb_alloc(&routememb);
if(r == NULL) {
/* This should not happen, as we explicitly deallocated one
route table entry above. */
PRINTF("uip_ds6_route_add: could not allocate route\n");
return NULL;
}
/* add new routes first - assuming that there is a reason to add this
and that there is a packet coming soon. */
list_push(routelist, r);
nbrr = memb_alloc(&neighborroutememb);
if(nbrr == NULL) {
/* This should not happen, as we explicitly deallocated one
route table entry above. */
PRINTF("uip_ds6_route_add: could not allocate neighbor route list entry\n");
memb_free(&routememb, r);
return NULL;
}
nbrr->route = r;
/* Add the route to this neighbor */
list_add(routes->route_list, nbrr);
r->neighbor_routes = routes;
num_routes++;
PRINTF("uip_ds6_route_add num %d\n", num_routes);
}
uip_ipaddr_copy(&(r->ipaddr), ipaddr);
r->length = length;
#ifdef UIP_DS6_ROUTE_STATE_TYPE
memset(&r->state, 0, sizeof(UIP_DS6_ROUTE_STATE_TYPE));
#endif
PRINTF("uip_ds6_route_add: adding route: ");
PRINT6ADDR(ipaddr);
PRINTF(" via ");
PRINT6ADDR(nexthop);
PRINTF("\n");
ANNOTATE("#L %u 1;blue\n", nexthop->u8[sizeof(uip_ipaddr_t) - 1]);
#if UIP_DS6_NOTIFICATIONS
call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_ADD, ipaddr, nexthop);
#endif
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
return r;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_rm(uip_ds6_route_t *route)
{
struct uip_ds6_route_neighbor_route *neighbor_route;
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
if(route != NULL && route->neighbor_routes != NULL) {
PRINTF("uip_ds6_route_rm: removing route: ");
PRINT6ADDR(&route->ipaddr);
PRINTF("\n");
/* Remove the route from the route list */
list_remove(routelist, route);
/* Find the corresponding neighbor_route and remove it. */
for(neighbor_route = list_head(route->neighbor_routes->route_list);
neighbor_route != NULL && neighbor_route->route != route;
neighbor_route = list_item_next(neighbor_route));
if(neighbor_route == NULL) {
PRINTF("uip_ds6_route_rm: neighbor_route was NULL for ");
uip_debug_ipaddr_print(&route->ipaddr);
PRINTF("\n");
}
list_remove(route->neighbor_routes->route_list, neighbor_route);
if(list_head(route->neighbor_routes->route_list) == NULL) {
/* If this was the only route using this neighbor, remove the
neibhor from the table */
PRINTF("uip_ds6_route_rm: removing neighbor too\n");
nbr_table_remove(nbr_routes, route->neighbor_routes->route_list);
}
memb_free(&routememb, route);
memb_free(&neighborroutememb, neighbor_route);
num_routes--;
PRINTF("uip_ds6_route_rm num %d\n", num_routes);
#if UIP_DS6_NOTIFICATIONS
call_route_callback(UIP_DS6_NOTIFICATION_ROUTE_RM,
&route->ipaddr, uip_ds6_route_nexthop(route));
#endif
#if 0 //(DEBUG & DEBUG_ANNOTATE) == DEBUG_ANNOTATE
/* we need to check if this was the last route towards "nexthop" */
/* if so - remove that link (annotation) */
uip_ds6_route_t *r;
for(r = uip_ds6_route_head();
r != NULL;
r = uip_ds6_route_next(r)) {
uip_ipaddr_t *nextr, *nextroute;
nextr = uip_ds6_route_nexthop(r);
nextroute = uip_ds6_route_nexthop(route);
if(nextr != NULL &&
nextroute != NULL &&
uip_ipaddr_cmp(nextr, nextroute)) {
/* we found another link using the specific nexthop, so keep the #L */
return;
}
}
ANNOTATE("#L %u 0\n", uip_ds6_route_nexthop(route)->u8[sizeof(uip_ipaddr_t) - 1]);
#endif
}
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
return;
}
/*---------------------------------------------------------------------------*/
static void
rm_routelist(struct uip_ds6_route_neighbor_routes *routes)
{
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
PRINTF("uip_ds6_route_rm_routelist\n");
if(routes != NULL && routes->route_list != NULL) {
struct uip_ds6_route_neighbor_route *r;
r = list_head(routes->route_list);
while(r != NULL) {
uip_ds6_route_rm(r->route);
r = list_head(routes->route_list);
}
nbr_table_remove(nbr_routes, routes);
}
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
}
/*---------------------------------------------------------------------------*/
static void
rm_routelist_callback(nbr_table_item_t *ptr)
{
rm_routelist((struct uip_ds6_route_neighbor_routes *)ptr);
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop)
{
/* Get routing entry list of this neighbor */
const uip_lladdr_t *nexthop_lladdr;
struct uip_ds6_route_neighbor_routes *routes;
nexthop_lladdr = uip_ds6_nbr_lladdr_from_ipaddr(nexthop);
routes = nbr_table_get_from_lladdr(nbr_routes,
(linkaddr_t *)nexthop_lladdr);
rm_routelist(routes);
}
/*---------------------------------------------------------------------------*/
uip_ds6_defrt_t *
uip_ds6_defrt_add(uip_ipaddr_t *ipaddr, unsigned long interval)
{
uip_ds6_defrt_t *d;
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
PRINTF("uip_ds6_defrt_add\n");
d = uip_ds6_defrt_lookup(ipaddr);
if(d == NULL) {
d = memb_alloc(&defaultroutermemb);
if(d == NULL) {
PRINTF("uip_ds6_defrt_add: could not add default route to ");
PRINT6ADDR(ipaddr);
PRINTF(", out of memory\n");
return NULL;
} else {
PRINTF("uip_ds6_defrt_add: adding default route to ");
PRINT6ADDR(ipaddr);
PRINTF("\n");
}
list_push(defaultrouterlist, d);
}
uip_ipaddr_copy(&d->ipaddr, ipaddr);
if(interval != 0) {
stimer_set(&d->lifetime, interval);
d->isinfinite = 0;
} else {
d->isinfinite = 1;
}
ANNOTATE("#L %u 1\n", ipaddr->u8[sizeof(uip_ipaddr_t) - 1]);
#if UIP_DS6_NOTIFICATIONS
call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_ADD, ipaddr, ipaddr);
#endif
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
return d;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt)
{
uip_ds6_defrt_t *d;
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
/* Make sure that the defrt is in the list before we remove it. */
for(d = list_head(defaultrouterlist);
d != NULL;
d = list_item_next(d)) {
if(d == defrt) {
PRINTF("Removing default route\n");
list_remove(defaultrouterlist, defrt);
memb_free(&defaultroutermemb, defrt);
ANNOTATE("#L %u 0\n", defrt->ipaddr.u8[sizeof(uip_ipaddr_t) - 1]);
#if UIP_DS6_NOTIFICATIONS
call_route_callback(UIP_DS6_NOTIFICATION_DEFRT_RM,
&defrt->ipaddr, &defrt->ipaddr);
#endif
return;
}
}
#if DEBUG != DEBUG_NONE
assert_nbr_routes_list_sane();
#endif /* DEBUG != DEBUG_NONE */
}
/*---------------------------------------------------------------------------*/
uip_ds6_defrt_t *
uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr)
{
uip_ds6_defrt_t *d;
for(d = list_head(defaultrouterlist);
d != NULL;
d = list_item_next(d)) {
if(uip_ipaddr_cmp(&d->ipaddr, ipaddr)) {
return d;
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uip_ipaddr_t *
uip_ds6_defrt_choose(void)
{
uip_ds6_defrt_t *d;
uip_ds6_nbr_t *bestnbr;
uip_ipaddr_t *addr;
addr = NULL;
for(d = list_head(defaultrouterlist);
d != NULL;
d = list_item_next(d)) {
PRINTF("Defrt, IP address ");
PRINT6ADDR(&d->ipaddr);
PRINTF("\n");
bestnbr = uip_ds6_nbr_lookup(&d->ipaddr);
if(bestnbr != NULL && bestnbr->state != NBR_INCOMPLETE) {
PRINTF("Defrt found, IP address ");
PRINT6ADDR(&d->ipaddr);
PRINTF("\n");
return &d->ipaddr;
} else {
addr = &d->ipaddr;
PRINTF("Defrt INCOMPLETE found, IP address ");
PRINT6ADDR(&d->ipaddr);
PRINTF("\n");
}
}
return addr;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_defrt_periodic(void)
{
uip_ds6_defrt_t *d;
d = list_head(defaultrouterlist);
while(d != NULL) {
if(!d->isinfinite &&
stimer_expired(&d->lifetime)) {
PRINTF("uip_ds6_defrt_periodic: defrt lifetime expired\n");
uip_ds6_defrt_rm(d);
d = list_head(defaultrouterlist);
} else {
d = list_item_next(d);
}
}
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,169 +0,0 @@
/*
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* Header file for routing table manipulation
*/
#ifndef UIP_DS6_ROUTE_H
#define UIP_DS6_ROUTE_H
#include "sys/stimer.h"
#include "lib/list.h"
void uip_ds6_route_init(void);
#ifndef UIP_CONF_UIP_DS6_NOTIFICATIONS
#define UIP_DS6_NOTIFICATIONS 1
#else
#define UIP_DS6_NOTIFICATIONS UIP_CONF_UIP_DS6_NOTIFICATIONS
#endif
#if UIP_DS6_NOTIFICATIONS
/* Event constants for the uip-ds6 route notification interface. The
notification interface allows for a user program to be notified via
a callback when a route has been added or removed and when the
system has added or removed a default route. */
#define UIP_DS6_NOTIFICATION_DEFRT_ADD 0
#define UIP_DS6_NOTIFICATION_DEFRT_RM 1
#define UIP_DS6_NOTIFICATION_ROUTE_ADD 2
#define UIP_DS6_NOTIFICATION_ROUTE_RM 3
typedef void (* uip_ds6_notification_callback)(int event,
uip_ipaddr_t *route,
uip_ipaddr_t *nexthop,
int num_routes);
struct uip_ds6_notification {
struct uip_ds6_notification *next;
uip_ds6_notification_callback callback;
};
void uip_ds6_notification_add(struct uip_ds6_notification *n,
uip_ds6_notification_callback c);
void uip_ds6_notification_rm(struct uip_ds6_notification *n);
/*--------------------------------------------------*/
#endif
/* Routing table */
#ifndef UIP_CONF_MAX_ROUTES
#ifdef UIP_CONF_DS6_ROUTE_NBU
#define UIP_DS6_ROUTE_NB UIP_CONF_DS6_ROUTE_NBU
#else /* UIP_CONF_DS6_ROUTE_NBU */
#define UIP_DS6_ROUTE_NB 4
#endif /* UIP_CONF_DS6_ROUTE_NBU */
#else /* UIP_CONF_MAX_ROUTES */
#define UIP_DS6_ROUTE_NB UIP_CONF_MAX_ROUTES
#endif /* UIP_CONF_MAX_ROUTES */
/** \brief define some additional RPL related route state and
* neighbor callback for RPL - if not a DS6_ROUTE_STATE is already set */
#ifndef UIP_DS6_ROUTE_STATE_TYPE
#define UIP_DS6_ROUTE_STATE_TYPE rpl_route_entry_t
/* Needed for the extended route entry state when using ContikiRPL */
typedef struct rpl_route_entry {
uint32_t lifetime;
void *dag;
uint8_t learned_from;
uint8_t nopath_received;
} rpl_route_entry_t;
#endif /* UIP_DS6_ROUTE_STATE_TYPE */
/** \brief The neighbor routes hold a list of routing table entries
that are attached to a specific neihbor. */
struct uip_ds6_route_neighbor_routes {
LIST_STRUCT(route_list);
};
/** \brief An entry in the routing table */
typedef struct uip_ds6_route {
struct uip_ds6_route *next;
/* Each route entry belongs to a specific neighbor. That neighbor
holds a list of all routing entries that go through it. The
routes field point to the uip_ds6_route_neighbor_routes that
belong to the neighbor table entry that this routing table entry
uses. */
struct uip_ds6_route_neighbor_routes *neighbor_routes;
uip_ipaddr_t ipaddr;
#ifdef UIP_DS6_ROUTE_STATE_TYPE
UIP_DS6_ROUTE_STATE_TYPE state;
#endif
uint8_t length;
} uip_ds6_route_t;
/** \brief A neighbor route list entry, used on the
uip_ds6_route->neighbor_routes->route_list list. */
struct uip_ds6_route_neighbor_route {
struct uip_ds6_route_neighbor_route *next;
struct uip_ds6_route *route;
};
/** \brief An entry in the default router list */
typedef struct uip_ds6_defrt {
struct uip_ds6_defrt *next;
uip_ipaddr_t ipaddr;
struct stimer lifetime;
uint8_t isinfinite;
} uip_ds6_defrt_t;
/** \name Default router list basic routines */
/** @{ */
uip_ds6_defrt_t *uip_ds6_defrt_add(uip_ipaddr_t *ipaddr,
unsigned long interval);
void uip_ds6_defrt_rm(uip_ds6_defrt_t *defrt);
uip_ds6_defrt_t *uip_ds6_defrt_lookup(uip_ipaddr_t *ipaddr);
uip_ipaddr_t *uip_ds6_defrt_choose(void);
void uip_ds6_defrt_periodic(void);
/** @} */
/** \name Routing Table basic routines */
/** @{ */
uip_ds6_route_t *uip_ds6_route_lookup(uip_ipaddr_t *destipaddr);
uip_ds6_route_t *uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length,
uip_ipaddr_t *next_hop);
void uip_ds6_route_rm(uip_ds6_route_t *route);
void uip_ds6_route_rm_by_nexthop(uip_ipaddr_t *nexthop);
uip_ipaddr_t *uip_ds6_route_nexthop(uip_ds6_route_t *);
int uip_ds6_route_num_routes(void);
uip_ds6_route_t *uip_ds6_route_head(void);
uip_ds6_route_t *uip_ds6_route_next(uip_ds6_route_t *);
/** @} */
#endif /* UIP_DS6_ROUTE_H */
/** @} */

View file

@ -1,737 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* IPv6 data structure manipulation.
* Comprises part of the Neighbor discovery (RFC 4861)
* and auto configuration (RFC 4862) state machines.
* \author Mathilde Durvy <mdurvy@cisco.com>
* \author Julien Abeille <jabeille@cisco.com>
*/
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include "lib/random.h"
#include "contiki/ipv6/uip-nd6.h"
#include "contiki/ipv6/uip-ds6.h"
#include "contiki/ip/uip-packetqueue.h"
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV6_DS
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
struct etimer uip_ds6_timer_periodic; /** \brief Timer for maintenance of data structures */
#if UIP_CONF_ROUTER
struct stimer uip_ds6_timer_ra; /** \brief RA timer, to schedule RA sending */
#if UIP_ND6_SEND_RA
static uint8_t racount; /** \brief number of RA already sent */
static uint16_t rand_time; /** \brief random time value for timers */
#endif
#else /* UIP_CONF_ROUTER */
struct etimer uip_ds6_timer_rs; /** \brief RS timer, to schedule RS sending */
static uint8_t rscount; /** \brief number of rs already sent */
#endif /* UIP_CONF_ROUTER */
/** \name "DS6" Data structures */
/** @{ */
uip_ds6_netif_t uip_ds6_if; /** \brief The single interface */
uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB]; /** \brief Prefix list */
/* Used by Cooja to enable extraction of addresses from memory.*/
uint8_t uip_ds6_addr_size;
uint8_t uip_ds6_netif_addr_list_offset;
/** @} */
/* "full" (as opposed to pointer) ip address used in this file, */
static uip_ipaddr_t loc_fipaddr;
/* Pointers used in this file */
/* FIXME - we cannot do this as would prevent re-entrancy */
static uip_ds6_addr_t *locaddr;
static uip_ds6_maddr_t *locmaddr;
static uip_ds6_aaddr_t *locaaddr;
static uip_ds6_prefix_t *locprefix;
/*---------------------------------------------------------------------------*/
void
uip_ds6_init(void)
{
uip_ds6_neighbors_init();
uip_ds6_route_init();
PRINTF("Init of IPv6 data structures\n");
PRINTF("%u neighbors\n%u default routers\n%u prefixes\n%u routes\n%u unicast addresses\n%u multicast addresses\n%u anycast addresses\n",
NBR_TABLE_MAX_NEIGHBORS, UIP_DS6_DEFRT_NB, UIP_DS6_PREFIX_NB, UIP_DS6_ROUTE_NB,
UIP_DS6_ADDR_NB, UIP_DS6_MADDR_NB, UIP_DS6_AADDR_NB);
memset(uip_ds6_prefix_list, 0, sizeof(uip_ds6_prefix_list));
memset(&uip_ds6_if, 0, sizeof(uip_ds6_if));
uip_ds6_addr_size = sizeof(struct uip_ds6_addr);
uip_ds6_netif_addr_list_offset = offsetof(struct uip_ds6_netif, addr_list);
/* Set interface parameters */
uip_ds6_if.link_mtu = UIP_LINK_MTU;
uip_ds6_if.cur_hop_limit = UIP_TTL;
uip_ds6_if.base_reachable_time = UIP_ND6_REACHABLE_TIME;
uip_ds6_if.reachable_time = uip_ds6_compute_reachable_time();
uip_ds6_if.retrans_timer = UIP_ND6_RETRANS_TIMER;
uip_ds6_if.maxdadns = UIP_ND6_DEF_MAXDADNS;
uip_ds6_set_lladdr(&uip_lladdr);
#if UIP_CONF_ROUTER
#if UIP_ND6_SEND_RA
stimer_set(&uip_ds6_timer_ra, 2); /* wait to have a link local IP address */
#endif /* UIP_ND6_SEND_RA */
#else /* UIP_CONF_ROUTER */
etimer_set(&uip_ds6_timer_rs,
random_rand() % (UIP_ND6_MAX_RTR_SOLICITATION_DELAY *
CLOCK_SECOND),
&tcpip_process);
#endif /* UIP_CONF_ROUTER */
etimer_set(&uip_ds6_timer_periodic, UIP_DS6_PERIOD, &tcpip_process);
return;
}
/*---------------------------------------------------------------------------*/
void uip_ds6_set_lladdr(uip_lladdr_t *lladdr)
{
/* First remove the current address from system as this function
* can be called many times.
*/
uip_ds6_addr_rm(uip_ds6_addr_lookup(&loc_fipaddr));
/* Create link local address, prefix, multicast addresses,
* anycast addresses
*/
uip_create_linklocal_prefix(&loc_fipaddr);
#if UIP_CONF_ROUTER
uip_ds6_prefix_add(&loc_fipaddr, UIP_DEFAULT_PREFIX_LEN, 0, 0, 0, 0);
#else /* UIP_CONF_ROUTER */
uip_ds6_prefix_add(&loc_fipaddr, UIP_DEFAULT_PREFIX_LEN, 0);
#endif /* UIP_CONF_ROUTER */
memcpy(&uip_lladdr, lladdr, sizeof(uip_lladdr));
uip_ds6_set_addr_iid(&loc_fipaddr, &uip_lladdr);
uip_ds6_addr_add(&loc_fipaddr, 0, ADDR_AUTOCONF);
uip_create_linklocal_allnodes_mcast(&loc_fipaddr);
uip_ds6_maddr_add(&loc_fipaddr);
#if UIP_CONF_ROUTER
uip_create_linklocal_allrouters_mcast(&loc_fipaddr);
uip_ds6_maddr_add(&loc_fipaddr);
#endif /* UIP_CONF_ROUTER */
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_periodic(struct net_buf *buf)
{
uip_ds6_addr_t *locaddr;
uip_ds6_prefix_t *locprefix;
/* Periodic processing on unicast addresses */
for(locaddr = uip_ds6_if.addr_list;
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
if(locaddr->isused) {
if((!locaddr->isinfinite) && (stimer_expired(&locaddr->vlifetime))) {
uip_ds6_addr_rm(locaddr);
#if UIP_ND6_DEF_MAXDADNS > 0
} else if((locaddr->state == ADDR_TENTATIVE)
&& (locaddr->dadnscount <= uip_ds6_if.maxdadns)
&& (timer_expired(&locaddr->dadtimer))) {
uip_ds6_dad(NULL, locaddr);
#endif /* UIP_ND6_DEF_MAXDADNS > 0 */
}
}
}
/* Periodic processing on default routers */
uip_ds6_defrt_periodic();
/* for(locdefrt = uip_ds6_defrt_list;
locdefrt < uip_ds6_defrt_list + UIP_DS6_DEFRT_NB; locdefrt++) {
if((locdefrt->isused) && (!locdefrt->isinfinite) &&
(stimer_expired(&(locdefrt->lifetime)))) {
uip_ds6_defrt_rm(locdefrt);
}
}*/
#if !UIP_CONF_ROUTER
/* Periodic processing on prefixes */
for(locprefix = uip_ds6_prefix_list;
locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB;
locprefix++) {
if(locprefix->isused && !locprefix->isinfinite
&& stimer_expired(&(locprefix->vlifetime))) {
uip_ds6_prefix_rm(locprefix);
}
}
#endif /* !UIP_CONF_ROUTER */
uip_ds6_neighbor_periodic(buf);
#if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
/* Periodic RA sending */
if(stimer_expired(&uip_ds6_timer_ra) && (uip_len == 0)) {
uip_ds6_send_ra_periodic();
}
#endif /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */
etimer_reset(&uip_ds6_timer_periodic);
return;
}
/*---------------------------------------------------------------------------*/
uint8_t
uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size,
uint16_t elementsize, uip_ipaddr_t *ipaddr,
uint8_t ipaddrlen, uip_ds6_element_t **out_element)
{
uip_ds6_element_t *element;
*out_element = NULL;
for(element = list;
element <
(uip_ds6_element_t *)((uint8_t *)list + (size * elementsize));
element = (uip_ds6_element_t *)((uint8_t *)element + elementsize)) {
if(element->isused) {
if(uip_ipaddr_prefixcmp(&element->ipaddr, ipaddr, ipaddrlen)) {
*out_element = element;
return FOUND;
}
} else {
*out_element = element;
}
}
return *out_element != NULL ? FREESPACE : NOSPACE;
}
/*---------------------------------------------------------------------------*/
#if UIP_CONF_ROUTER
/*---------------------------------------------------------------------------*/
uip_ds6_prefix_t *
uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen,
uint8_t advertise, uint8_t flags, unsigned long vtime,
unsigned long ptime)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_prefix_list, UIP_DS6_PREFIX_NB,
sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen,
(uip_ds6_element_t **)&locprefix) == FREESPACE) {
locprefix->isused = 1;
uip_ipaddr_copy(&locprefix->ipaddr, ipaddr);
locprefix->length = ipaddrlen;
locprefix->advertise = advertise;
locprefix->l_a_reserved = flags;
locprefix->vlifetime = vtime;
locprefix->plifetime = ptime;
PRINTF("Adding prefix ");
PRINT6ADDR(&locprefix->ipaddr);
PRINTF(" length %u, flags %x, Valid lifetime %lx, Preffered lifetime %lx\n",
ipaddrlen, flags, vtime, ptime);
return locprefix;
} else {
PRINTF("No more space in Prefix list\n");
}
return NULL;
}
#else /* UIP_CONF_ROUTER */
uip_ds6_prefix_t *
uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen,
unsigned long interval)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_prefix_list, UIP_DS6_PREFIX_NB,
sizeof(uip_ds6_prefix_t), ipaddr, ipaddrlen,
(uip_ds6_element_t **)&locprefix) == FREESPACE) {
locprefix->isused = 1;
uip_ipaddr_copy(&locprefix->ipaddr, ipaddr);
locprefix->length = ipaddrlen;
if(interval != 0) {
stimer_set(&(locprefix->vlifetime), interval);
locprefix->isinfinite = 0;
} else {
locprefix->isinfinite = 1;
}
PRINTF("Adding prefix ");
PRINT6ADDR(&locprefix->ipaddr);
PRINTF(" length %u, vlifetime %lu\n", ipaddrlen, interval);
}
return NULL;
}
#endif /* UIP_CONF_ROUTER */
/*---------------------------------------------------------------------------*/
void
uip_ds6_prefix_rm(uip_ds6_prefix_t *prefix)
{
if(prefix != NULL) {
prefix->isused = 0;
}
return;
}
/*---------------------------------------------------------------------------*/
uip_ds6_prefix_t *
uip_ds6_prefix_lookup(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen)
{
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_prefix_list,
UIP_DS6_PREFIX_NB, sizeof(uip_ds6_prefix_t),
ipaddr, ipaddrlen,
(uip_ds6_element_t **)&locprefix) == FOUND) {
return locprefix;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uint8_t
uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr)
{
for(locprefix = uip_ds6_prefix_list;
locprefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; locprefix++) {
if(locprefix->isused &&
uip_ipaddr_prefixcmp(&locprefix->ipaddr, ipaddr, locprefix->length)) {
return 1;
}
}
return 0;
}
/*---------------------------------------------------------------------------*/
uip_ds6_addr_t *
uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_if.addr_list, UIP_DS6_ADDR_NB,
sizeof(uip_ds6_addr_t), ipaddr, 128,
(uip_ds6_element_t **)&locaddr) == FREESPACE) {
locaddr->isused = 1;
uip_ipaddr_copy(&locaddr->ipaddr, ipaddr);
locaddr->type = type;
PRINTF("Adding addr ");
PRINT6ADDR(&locaddr->ipaddr);
PRINTF(" lifetime %d type %d\n", vlifetime, type);
if(vlifetime == 0) {
locaddr->isinfinite = 1;
} else {
locaddr->isinfinite = 0;
stimer_set(&(locaddr->vlifetime), vlifetime);
}
#if UIP_ND6_DEF_MAXDADNS > 0
locaddr->state = ADDR_TENTATIVE;
timer_set(&locaddr->dadtimer,
random_rand() % (UIP_ND6_MAX_RTR_SOLICITATION_DELAY *
CLOCK_SECOND));
locaddr->dadnscount = 0;
#else /* UIP_ND6_DEF_MAXDADNS > 0 */
locaddr->state = ADDR_PREFERRED;
#endif /* UIP_ND6_DEF_MAXDADNS > 0 */
uip_create_solicited_node(ipaddr, &loc_fipaddr);
uip_ds6_maddr_add(&loc_fipaddr);
return locaddr;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_addr_rm(uip_ds6_addr_t *addr)
{
if(addr != NULL) {
uip_create_solicited_node(&addr->ipaddr, &loc_fipaddr);
if((locmaddr = uip_ds6_maddr_lookup(&loc_fipaddr)) != NULL) {
uip_ds6_maddr_rm(locmaddr);
}
addr->isused = 0;
}
return;
}
/*---------------------------------------------------------------------------*/
uip_ds6_addr_t *
uip_ds6_addr_lookup(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_if.addr_list, UIP_DS6_ADDR_NB,
sizeof(uip_ds6_addr_t), ipaddr, 128,
(uip_ds6_element_t **)&locaddr) == FOUND) {
return locaddr;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
/*
* 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)
{
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_link_local(&locaddr->ipaddr))) {
return locaddr;
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
/*
* get a global address -
* state = -1 => any address is ok. Otherwise state = desired state of addr.
* (TENTATIVE, PREFERRED, DEPRECATED)
*/
uip_ds6_addr_t *
uip_ds6_get_global(int8_t state)
{
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_link_local(&locaddr->ipaddr))) {
return locaddr;
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uip_ds6_maddr_t *
uip_ds6_maddr_add(const uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB,
sizeof(uip_ds6_maddr_t), (void*)ipaddr, 128,
(uip_ds6_element_t **)&locmaddr) == FREESPACE) {
locmaddr->isused = 1;
uip_ipaddr_copy(&locmaddr->ipaddr, ipaddr);
PRINTF("Adding maddr ");
PRINT6ADDR(&locmaddr->ipaddr);
PRINTF("\n");
return locmaddr;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_maddr_rm(uip_ds6_maddr_t *maddr)
{
if(maddr != NULL) {
maddr->isused = 0;
}
return;
}
/*---------------------------------------------------------------------------*/
uip_ds6_maddr_t *
uip_ds6_maddr_lookup(const uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_if.maddr_list, UIP_DS6_MADDR_NB,
sizeof(uip_ds6_maddr_t), (void*)ipaddr, 128,
(uip_ds6_element_t **)&locmaddr) == FOUND) {
return locmaddr;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uip_ds6_aaddr_t *
uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop
((uip_ds6_element_t *)uip_ds6_if.aaddr_list, UIP_DS6_AADDR_NB,
sizeof(uip_ds6_aaddr_t), ipaddr, 128,
(uip_ds6_element_t **)&locaaddr) == FREESPACE) {
locaaddr->isused = 1;
uip_ipaddr_copy(&locaaddr->ipaddr, ipaddr);
return locaaddr;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_aaddr_rm(uip_ds6_aaddr_t *aaddr)
{
if(aaddr != NULL) {
aaddr->isused = 0;
}
return;
}
/*---------------------------------------------------------------------------*/
uip_ds6_aaddr_t *
uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr)
{
if(uip_ds6_list_loop((uip_ds6_element_t *)uip_ds6_if.aaddr_list,
UIP_DS6_AADDR_NB, sizeof(uip_ds6_aaddr_t), ipaddr, 128,
(uip_ds6_element_t **)&locaaddr) == FOUND) {
return locaaddr;
}
return NULL;
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst)
{
uint8_t best = 0; /* number of bit in common with best match */
uint8_t n = 0;
uip_ds6_addr_t *matchaddr = NULL;
if(!uip_is_addr_link_local(dst) && !uip_is_addr_mcast(dst)) {
/* find longest match */
for(locaddr = uip_ds6_if.addr_list;
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
/* Only preferred global (not link-local) addresses */
if(locaddr->isused && locaddr->state == ADDR_PREFERRED &&
!uip_is_addr_link_local(&locaddr->ipaddr)) {
n = get_match_length(dst, &locaddr->ipaddr);
if(n >= best) {
best = n;
matchaddr = locaddr;
}
}
}
#if UIP_IPV6_MULTICAST
} else if(uip_is_addr_mcast_routable(dst)) {
matchaddr = uip_ds6_get_global(ADDR_PREFERRED);
#endif
} else {
matchaddr = uip_ds6_get_link_local(ADDR_PREFERRED);
}
/* use the :: (unspecified address) as source if no match found */
if(matchaddr == NULL) {
uip_create_unspecified(src);
} else {
uip_ipaddr_copy(src, &matchaddr->ipaddr);
}
}
/*---------------------------------------------------------------------------*/
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, (uint8_t *)lladdr + 3, 3);
ipaddr->u8[8] ^= 0x02;
#else
#error uip-ds6.c cannot build interface address when UIP_LLADDR_LEN is not 6 or 8
#endif
}
/*---------------------------------------------------------------------------*/
uint8_t
get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst)
{
uint8_t j, k, x_or;
uint8_t len = 0;
for(j = 0; j < 16; j++) {
if(src->u8[j] == dst->u8[j]) {
len += 8;
} else {
x_or = src->u8[j] ^ dst->u8[j];
for(k = 0; k < 8; k++) {
if((x_or & 0x80) == 0) {
len++;
x_or <<= 1;
} else {
break;
}
}
break;
}
}
return len;
}
/*---------------------------------------------------------------------------*/
#if UIP_ND6_DEF_MAXDADNS > 0
void
uip_ds6_dad(struct net_buf *buf, uip_ds6_addr_t *addr)
{
/* send maxdadns NS for DAD */
if(addr->dadnscount < uip_ds6_if.maxdadns) {
uip_nd6_ns_output(buf, NULL, NULL, &addr->ipaddr);
addr->dadnscount++;
timer_set(&addr->dadtimer,
uip_ds6_if.retrans_timer / 1000 * CLOCK_SECOND);
return;
}
/*
* If we arrive here it means DAD succeeded, otherwise the dad process
* would have been interrupted in ds6_dad_ns/na_input
*/
PRINTF("DAD succeeded, ipaddr:");
PRINT6ADDR(&addr->ipaddr);
PRINTF("\n");
addr->state = ADDR_PREFERRED;
return;
}
/*---------------------------------------------------------------------------*/
/*
* Calling code must handle when this returns 0 (e.g. link local
* address can not be used).
*/
int
uip_ds6_dad_failed(uip_ds6_addr_t *addr)
{
if(uip_is_addr_link_local(&addr->ipaddr)) {
PRINTF("Contiki shutdown, DAD for link local address failed\n");
return 0;
}
uip_ds6_addr_rm(addr);
return 1;
}
#endif /*UIP_ND6_DEF_MAXDADNS > 0 */
/*---------------------------------------------------------------------------*/
#if UIP_CONF_ROUTER
#if UIP_ND6_SEND_RA
void
uip_ds6_send_ra_sollicited(void)
{
/* We have a pb here: RA timer max possible value is 1800s,
* hence we have to use stimers. However, when receiving a RS, we
* should delay the reply by a random value between 0 and 500ms timers.
* stimers are in seconds, hence we cannot do this. Therefore we just send
* the RA (setting the timer to 0 below). We keep the code logic for
* the days contiki will support appropriate timers */
rand_time = 0;
PRINTF("Solicited RA, random time %u\n", rand_time);
if(stimer_remaining(&uip_ds6_timer_ra) > rand_time) {
if(stimer_elapsed(&uip_ds6_timer_ra) < UIP_ND6_MIN_DELAY_BETWEEN_RAS) {
/* Ensure that the RAs are rate limited */
/* stimer_set(&uip_ds6_timer_ra, rand_time +
UIP_ND6_MIN_DELAY_BETWEEN_RAS -
stimer_elapsed(&uip_ds6_timer_ra));
*/ } else {
stimer_set(&uip_ds6_timer_ra, rand_time);
}
}
}
/*---------------------------------------------------------------------------*/
void
uip_ds6_send_ra_periodic(void)
{
if(racount > 0) {
/* send previously scheduled RA */
uip_nd6_ra_output(NULL);
PRINTF("Sending periodic RA\n");
}
rand_time = UIP_ND6_MIN_RA_INTERVAL + random_rand() %
(uint16_t) (UIP_ND6_MAX_RA_INTERVAL - UIP_ND6_MIN_RA_INTERVAL);
PRINTF("Random time 1 = %u\n", rand_time);
if(racount < UIP_ND6_MAX_INITIAL_RAS) {
if(rand_time > UIP_ND6_MAX_INITIAL_RA_INTERVAL) {
rand_time = UIP_ND6_MAX_INITIAL_RA_INTERVAL;
PRINTF("Random time 2 = %u\n", rand_time);
}
racount++;
}
PRINTF("Random time 3 = %u\n", rand_time);
stimer_set(&uip_ds6_timer_ra, rand_time);
}
#endif /* UIP_ND6_SEND_RA */
#else /* UIP_CONF_ROUTER */
/*---------------------------------------------------------------------------*/
void
uip_ds6_send_rs(struct net_buf *buf)
{
if((uip_ds6_defrt_choose() == NULL)
&& (rscount < UIP_ND6_MAX_RTR_SOLICITATIONS)) {
PRINTF("Sending RS %u\n", rscount);
uip_nd6_rs_output(buf);
rscount++;
etimer_set(&uip_ds6_timer_rs,
UIP_ND6_RTR_SOLICITATION_INTERVAL * CLOCK_SECOND,
&tcpip_process);
} else {
PRINTF("Router found ? (boolean): %u\n",
(uip_ds6_defrt_choose() != NULL));
etimer_stop(&uip_ds6_timer_rs);
}
return;
}
#endif /* UIP_CONF_ROUTER */
/*---------------------------------------------------------------------------*/
uint32_t
uip_ds6_compute_reachable_time(void)
{
return (uint32_t) (UIP_ND6_MIN_RANDOM_FACTOR
(uip_ds6_if.base_reachable_time)) +
((uint16_t) (random_rand() << 8) +
(uint16_t) random_rand()) %
(uint32_t) (UIP_ND6_MAX_RANDOM_FACTOR(uip_ds6_if.base_reachable_time) -
UIP_ND6_MIN_RANDOM_FACTOR(uip_ds6_if.base_reachable_time));
}
/*---------------------------------------------------------------------------*/
/** @}*/

View file

@ -1,350 +0,0 @@
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* Header file for IPv6-related data structures
* \author Mathilde Durvy <mdurvy@cisco.com>
* \author Julien Abeille <jabeille@cisco.com>
*
*/
/*
*
* 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.
*
*
*/
#ifndef UIP_DS6_H_
#define UIP_DS6_H_
#include <net/buf.h>
#include "contiki/ip/uip.h"
#include "sys/stimer.h"
/* The size of uip_ds6_addr_t depends on UIP_ND6_DEF_MAXDADNS. Include uip-nd6.h to define it. */
#include "contiki/ipv6/uip-nd6.h"
#include "contiki/ipv6/uip-ds6-route.h"
#include "contiki/ipv6/uip-ds6-nbr.h"
/*--------------------------------------------------*/
/** Configuration. For all tables (Neighbor cache, Prefix List, Routing Table,
* Default Router List, Unicast address list, multicast address list, anycast address list),
* we define:
* - the number of elements requested by the user in contiki configuration (name suffixed by _NBU)
* - the number of elements assigned by the system (name suffixed by _NBS)
* - the total number of elements is the sum (name suffixed by _NB)
*/
/* Default router list */
#define UIP_DS6_DEFRT_NBS 0
#ifndef UIP_CONF_DS6_DEFRT_NBU
#define UIP_DS6_DEFRT_NBU 2
#else
#define UIP_DS6_DEFRT_NBU UIP_CONF_DS6_DEFRT_NBU
#endif
#define UIP_DS6_DEFRT_NB UIP_DS6_DEFRT_NBS + UIP_DS6_DEFRT_NBU
/* Prefix list */
#define UIP_DS6_PREFIX_NBS 1
#ifndef UIP_CONF_DS6_PREFIX_NBU
#define UIP_DS6_PREFIX_NBU 2
#else
#define UIP_DS6_PREFIX_NBU UIP_CONF_DS6_PREFIX_NBU
#endif
#define UIP_DS6_PREFIX_NB UIP_DS6_PREFIX_NBS + UIP_DS6_PREFIX_NBU
/* Unicast address list*/
#define UIP_DS6_ADDR_NBS 1
#ifndef UIP_CONF_DS6_ADDR_NBU
#define UIP_DS6_ADDR_NBU 2
#else
#define UIP_DS6_ADDR_NBU UIP_CONF_DS6_ADDR_NBU
#endif
#define UIP_DS6_ADDR_NB UIP_DS6_ADDR_NBS + UIP_DS6_ADDR_NBU
/* Multicast address list */
#if UIP_CONF_ROUTER
#define UIP_DS6_MADDR_NBS 2 + UIP_DS6_ADDR_NB /* all routers + all nodes + one solicited per unicast */
#else
#define UIP_DS6_MADDR_NBS 1 + UIP_DS6_ADDR_NB /* all nodes + one solicited per unicast */
#endif
#ifndef UIP_CONF_DS6_MADDR_NBU
#define UIP_DS6_MADDR_NBU 0
#else
#define UIP_DS6_MADDR_NBU UIP_CONF_DS6_MADDR_NBU
#endif
#define UIP_DS6_MADDR_NB UIP_DS6_MADDR_NBS + UIP_DS6_MADDR_NBU
/* Anycast address list */
#if UIP_CONF_ROUTER
#define UIP_DS6_AADDR_NBS UIP_DS6_PREFIX_NB - 1 /* One per non link local prefix (subnet prefix anycast address) */
#else
#define UIP_DS6_AADDR_NBS 0
#endif
#ifndef UIP_CONF_DS6_AADDR_NBU
#define UIP_DS6_AADDR_NBU 0
#else
#define UIP_DS6_AADDR_NBU UIP_CONF_DS6_AADDR_NBU
#endif
#define UIP_DS6_AADDR_NB UIP_DS6_AADDR_NBS + UIP_DS6_AADDR_NBU
/*--------------------------------------------------*/
/* Should we use LinkLayer acks in NUD ?*/
#ifndef UIP_CONF_DS6_LL_NUD
#define UIP_DS6_LL_NUD 0
#else
#define UIP_DS6_LL_NUD UIP_CONF_DS6_LL_NUD
#endif
/** \brief Possible states for the an address (RFC 4862) */
#define ADDR_TENTATIVE 0
#define ADDR_PREFERRED 1
#define ADDR_DEPRECATED 2
/** \brief How the address was acquired: Autoconf, DHCP or manually */
#define ADDR_ANYTYPE 0
#define ADDR_AUTOCONF 1
#define ADDR_DHCP 2
#define ADDR_MANUAL 3
/** \brief General DS6 definitions */
/** Period for uip-ds6 periodic task*/
#ifndef UIP_DS6_CONF_PERIOD
#define UIP_DS6_PERIOD (CLOCK_SECOND/10)
#else
#define UIP_DS6_PERIOD UIP_DS6_CONF_PERIOD
#endif
#define FOUND 0
#define FREESPACE 1
#define NOSPACE 2
/*--------------------------------------------------*/
#if UIP_CONF_IPV6_QUEUE_PKT
#include "contiki/ip/uip-packetqueue.h"
#endif /*UIP_CONF_QUEUE_PKT */
/** \brief A prefix list entry */
#if UIP_CONF_ROUTER
typedef struct uip_ds6_prefix {
uint8_t isused;
uip_ipaddr_t ipaddr;
uint8_t length;
uint8_t advertise;
uint32_t vlifetime;
uint32_t plifetime;
uint8_t l_a_reserved; /**< on-link and autonomous flags + 6 reserved bits */
} uip_ds6_prefix_t;
#else /* UIP_CONF_ROUTER */
typedef struct uip_ds6_prefix {
uint8_t isused;
uip_ipaddr_t ipaddr;
uint8_t length;
struct stimer vlifetime;
uint8_t isinfinite;
} uip_ds6_prefix_t;
#endif /*UIP_CONF_ROUTER */
/** * \brief Unicast address structure */
typedef struct uip_ds6_addr {
uint8_t isused;
uip_ipaddr_t ipaddr;
uint8_t state;
uint8_t type;
uint8_t isinfinite;
struct stimer vlifetime;
#if UIP_ND6_DEF_MAXDADNS > 0
struct timer dadtimer;
uint8_t dadnscount;
#endif /* UIP_ND6_DEF_MAXDADNS > 0 */
} uip_ds6_addr_t;
/** \brief Anycast address */
typedef struct uip_ds6_aaddr {
uint8_t isused;
uip_ipaddr_t ipaddr;
} uip_ds6_aaddr_t;
/** \brief A multicast address */
typedef struct uip_ds6_maddr {
uint8_t isused;
uip_ipaddr_t ipaddr;
} uip_ds6_maddr_t;
/* only define the callback if RPL is active */
#if UIP_CONF_IPV6_RPL
#ifndef UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED
#define UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED rpl_ipv6_neighbor_callback
#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */
#endif /* UIP_CONF_IPV6_RPL */
#if UIP_CONF_IPV6_RPL
#ifndef UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK
#define UIP_CONF_DS6_LINK_NEIGHBOR_CALLBACK rpl_link_neighbor_callback
#endif /* UIP_CONF_DS6_NEIGHBOR_STATE_CHANGED */
#endif /* UIP_CONF_IPV6_RPL */
/** \brief Interface structure (contains all the interface variables) */
typedef struct uip_ds6_netif {
uint32_t link_mtu;
uint8_t cur_hop_limit;
uint32_t base_reachable_time; /* in msec */
uint32_t reachable_time; /* in msec */
uint32_t retrans_timer; /* in msec */
uint8_t maxdadns;
uip_ds6_addr_t addr_list[UIP_DS6_ADDR_NB];
uip_ds6_aaddr_t aaddr_list[UIP_DS6_AADDR_NB];
uip_ds6_maddr_t maddr_list[UIP_DS6_MADDR_NB];
} uip_ds6_netif_t;
/** \brief Generic type for a DS6, to use a common loop though all DS */
typedef struct uip_ds6_element {
uint8_t isused;
uip_ipaddr_t ipaddr;
} uip_ds6_element_t;
/*---------------------------------------------------------------------------*/
extern uip_ds6_netif_t uip_ds6_if;
extern struct etimer uip_ds6_timer_periodic;
#if UIP_CONF_ROUTER
extern uip_ds6_prefix_t uip_ds6_prefix_list[UIP_DS6_PREFIX_NB];
#else /* UIP_CONF_ROUTER */
extern struct etimer uip_ds6_timer_rs;
#endif /* UIP_CONF_ROUTER */
/*---------------------------------------------------------------------------*/
/** \brief Initialize data structures */
void uip_ds6_init(void);
/** \brief Periodic processing of data structures */
void uip_ds6_periodic(struct net_buf *buf);
/** \brief Generic loop routine on an abstract data structure, which generalizes
* all data structures used in DS6 */
uint8_t uip_ds6_list_loop(uip_ds6_element_t *list, uint8_t size,
uint16_t elementsize, uip_ipaddr_t *ipaddr,
uint8_t ipaddrlen,
uip_ds6_element_t **out_element);
/** @} */
/** \name Prefix list basic routines */
/** @{ */
#if UIP_CONF_ROUTER
uip_ds6_prefix_t *uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t length,
uint8_t advertise, uint8_t flags,
unsigned long vtime,
unsigned long ptime);
#else /* UIP_CONF_ROUTER */
uip_ds6_prefix_t *uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t length,
unsigned long interval);
#endif /* UIP_CONF_ROUTER */
void uip_ds6_prefix_rm(uip_ds6_prefix_t *prefix);
uip_ds6_prefix_t *uip_ds6_prefix_lookup(uip_ipaddr_t *ipaddr,
uint8_t ipaddrlen);
uint8_t uip_ds6_is_addr_onlink(uip_ipaddr_t *ipaddr);
/** @} */
/** \name Unicast address list basic routines */
/** @{ */
uip_ds6_addr_t *uip_ds6_addr_add(uip_ipaddr_t *ipaddr,
unsigned long vlifetime, uint8_t type);
void uip_ds6_addr_rm(uip_ds6_addr_t *addr);
uip_ds6_addr_t *uip_ds6_addr_lookup(uip_ipaddr_t *ipaddr);
uip_ds6_addr_t *uip_ds6_get_link_local(int8_t state);
uip_ds6_addr_t *uip_ds6_get_global(int8_t state);
/** @} */
/** \name Multicast address list basic routines */
/** @{ */
uip_ds6_maddr_t *uip_ds6_maddr_add(const uip_ipaddr_t *ipaddr);
void uip_ds6_maddr_rm(uip_ds6_maddr_t *maddr);
uip_ds6_maddr_t *uip_ds6_maddr_lookup(const uip_ipaddr_t *ipaddr);
/** @} */
/** \name Anycast address list basic routines */
/** @{ */
uip_ds6_aaddr_t *uip_ds6_aaddr_add(uip_ipaddr_t *ipaddr);
void uip_ds6_aaddr_rm(uip_ds6_aaddr_t *aaddr);
uip_ds6_aaddr_t *uip_ds6_aaddr_lookup(uip_ipaddr_t *ipaddr);
/** @} */
/** \brief Set the link local IPv6 address according to linkaddr */
void uip_ds6_set_lladdr(uip_lladdr_t *lladdr);
/** \brief set the last 64 bits of an IP address based on the MAC address */
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr);
/** \brief Get the number of matching bits of two addresses */
uint8_t get_match_length(uip_ipaddr_t *src, uip_ipaddr_t *dst);
#if UIP_ND6_DEF_MAXDADNS >0
/** \brief Perform Duplicate Address Selection on one address */
void uip_ds6_dad(struct net_buf *buf, uip_ds6_addr_t *ifaddr);
/** \brief Callback when DAD failed */
int uip_ds6_dad_failed(uip_ds6_addr_t *ifaddr);
#endif /* UIP_ND6_DEF_MAXDADNS */
/** \brief Source address selection, see RFC 3484 */
void uip_ds6_select_src(uip_ipaddr_t *src, uip_ipaddr_t *dst);
#if UIP_CONF_ROUTER
#if UIP_ND6_SEND_RA
/** \brief Send a RA as an asnwer to a RS */
void uip_ds6_send_ra_sollicited(void);
/** \brief Send a periodic RA */
void uip_ds6_send_ra_periodic(void);
#endif /* UIP_ND6_SEND_RA */
#else /* UIP_CONF_ROUTER */
/** \brief Send periodic RS to find router */
void uip_ds6_send_rs(struct net_buf *buf);
#endif /* UIP_CONF_ROUTER */
/** \brief Compute the reachable time based on base reachable time, see RFC 4861*/
uint32_t uip_ds6_compute_reachable_time(void); /** \brief compute random reachable timer */
/** \name Macros to check if an IP address (unicast, multicast or anycast) is mine */
/** @{ */
#define uip_ds6_is_my_addr(addr) (uip_ds6_addr_lookup(addr) != NULL)
#define uip_ds6_is_my_maddr(addr) (uip_ds6_maddr_lookup(addr) != NULL)
#define uip_ds6_is_my_aaddr(addr) (uip_ds6_aaddr_lookup(addr) != NULL)
/** @} */
/** @} */
#endif /* UIP_DS6_H_ */

View file

@ -1,426 +0,0 @@
/*
* Copyright (c) 2001-2003, Adam Dunkels.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This file is part of the uIP TCP/IP stack.
*
*/
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* ICMPv6 (RFC 4443) implementation, with message and error handling
* \author Julien Abeille <jabeille@cisco.com>
* \author Mathilde Durvy <mdurvy@cisco.com>
*/
#include <net/ip_buf.h>
#include <string.h>
#include "contiki/ipv6/uip-ds6.h"
#include "contiki/ipv6/uip-icmp6.h"
#include "contiki-default-conf.h"
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_IPV6_ICMPV6
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
#define UIP_IP_BUF(buf) ((struct uip_ip_hdr *)&uip_buf(buf)[UIP_LLH_LEN])
#define UIP_ICMP_BUF(buf) ((struct uip_icmp_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)])
#define UIP_ICMP6_ERROR_BUF(buf) ((struct uip_icmp6_error *)&uip_buf(buf)[uip_l2_l3_icmp_hdr_len(buf)])
#define UIP_EXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[uip_l2_l3_hdr_len(buf)])
#define UIP_FIRST_EXT_BUF(buf) ((struct uip_ext_hdr *)&uip_buf(buf)[UIP_LLIPH_LEN])
#if UIP_CONF_IPV6_RPL
#include "rpl/rpl.h"
#endif /* UIP_CONF_IPV6_RPL */
#if 0
/* Moved this to individual functions to make the API re-entrant */
/** \brief temporary IP address */
static uip_ipaddr_t tmp_ipaddr;
#endif
LIST(echo_reply_callback_list);
/*---------------------------------------------------------------------------*/
/* List of input handlers */
LIST(input_handler_list);
/*---------------------------------------------------------------------------*/
static uip_icmp6_input_handler_t *
input_handler_lookup(uint8_t type, uint8_t icode)
{
uip_icmp6_input_handler_t *handler = NULL;
for(handler = list_head(input_handler_list);
handler != NULL;
handler = list_item_next(handler)) {
if(handler->type == type &&
(handler->icode == icode ||
handler->icode == UIP_ICMP6_HANDLER_CODE_ANY)) {
return handler;
}
}
return NULL;
}
/*---------------------------------------------------------------------------*/
uint8_t
uip_icmp6_input(struct net_buf *buf, uint8_t type, uint8_t icode)
{
uip_icmp6_input_handler_t *handler = input_handler_lookup(type, icode);
if(handler == NULL) {
return UIP_ICMP6_INPUT_ERROR;
}
if(handler->handler == NULL) {
return UIP_ICMP6_INPUT_ERROR;
}
handler->handler(buf);
return UIP_ICMP6_INPUT_SUCCESS;
}
/*---------------------------------------------------------------------------*/
void
uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler)
{
list_add(input_handler_list, handler);
}
/*---------------------------------------------------------------------------*/
static void
echo_request_input(struct net_buf *buf)
{
#if UIP_CONF_IPV6_RPL
uint8_t temp_ext_len;
#endif /* UIP_CONF_IPV6_RPL */
/*
* we send an echo reply. It is trivial if there was no extension
* headers in the request otherwise we need to remove the extension
* headers and change a few fields
*/
PRINTF("Received Echo Request from ");
PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr);
PRINTF(" to ");
PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr);
PRINTF("\n");
/* IP header */
UIP_IP_BUF(buf)->ttl = uip_ds6_if.cur_hop_limit;
if(uip_is_addr_mcast(&UIP_IP_BUF(buf)->destipaddr)){
uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &UIP_IP_BUF(buf)->srcipaddr);
uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr);
} else {
uip_ipaddr_t tmp_ipaddr;
uip_ipaddr_copy(&tmp_ipaddr, &UIP_IP_BUF(buf)->srcipaddr);
uip_ipaddr_copy(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr);
uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &tmp_ipaddr);
}
if(uip_ext_len(buf) > 0) {
#if UIP_CONF_IPV6_RPL
if((temp_ext_len = rpl_invert_header(buf))) {
/* If there were other extension headers*/
UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6;
if (uip_ext_len(buf) != temp_ext_len) {
uip_len(buf) -= (uip_ext_len(buf) - temp_ext_len);
UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8);
UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - 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 remaining extension headers present
* Note: UIP_ICMP_BUF still points to the echo request at this stage
*/
memmove((uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN - (uip_ext_len(buf) - temp_ext_len),
(uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN,
(uip_len(buf) - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN));
}
uip_ext_len(buf) = temp_ext_len;
} else {
#endif /* UIP_CONF_IPV6_RPL */
/* If there were extension headers*/
UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6;
uip_len(buf) -= uip_ext_len(buf);
UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8);
UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - 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(buf) + UIP_ICMPH_LEN - uip_ext_len(buf),
(uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN,
(uip_len(buf) - UIP_IPH_LEN - UIP_ICMPH_LEN));
uip_ext_len(buf) = 0;
#if UIP_CONF_IPV6_RPL
}
#endif /* UIP_CONF_IPV6_RPL */
}
/* Below is important for the correctness of UIP_ICMP_BUF and the
* checksum
*/
/* Note: now UIP_ICMP_BUF points to the beginning of the echo reply */
UIP_ICMP_BUF(buf)->type = ICMP6_ECHO_REPLY;
UIP_ICMP_BUF(buf)->icode = 0;
UIP_ICMP_BUF(buf)->icmpchksum = 0;
UIP_ICMP_BUF(buf)->icmpchksum = ~uip_icmp6chksum(buf);
PRINTF("Sending Echo Reply to ");
PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr);
PRINTF(" from ");
PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr);
PRINTF("\n");
UIP_STAT(++uip_stat.icmp.sent);
return;
}
/*---------------------------------------------------------------------------*/
void
uip_icmp6_error_output(struct net_buf *buf, uint8_t type, uint8_t code, uint32_t param) {
uip_ipaddr_t tmp_ipaddr;
/* check if originating packet is not an ICMP error*/
if (uip_ext_len(buf)) {
if(UIP_EXT_BUF(buf)->next == UIP_PROTO_ICMP6 && UIP_ICMP_BUF(buf)->type < 128){
uip_len(buf) = 0;
return;
}
} else {
if(UIP_IP_BUF(buf)->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF(buf)->type < 128){
uip_len(buf) = 0;
return;
}
}
#if UIP_CONF_IPV6_RPL
uip_ext_len(buf) = rpl_invert_header(buf);
#else /* UIP_CONF_IPV6_RPL */
uip_ext_len(buf) = 0;
#endif /* UIP_CONF_IPV6_RPL */
/* remember data of original packet before shifting */
uip_ipaddr_copy(&tmp_ipaddr, &UIP_IP_BUF(buf)->destipaddr);
uip_len(buf) += UIP_IPICMPH_LEN + UIP_ICMP6_ERROR_LEN;
if(uip_len(buf) > UIP_LINK_MTU)
uip_len(buf) = UIP_LINK_MTU;
memmove((uint8_t *)UIP_ICMP6_ERROR_BUF(buf) + uip_ext_len(buf) + UIP_ICMP6_ERROR_LEN,
(void *)UIP_IP_BUF(buf), uip_len(buf) - UIP_IPICMPH_LEN - uip_ext_len(buf) - UIP_ICMP6_ERROR_LEN);
UIP_IP_BUF(buf)->vtc = 0x60;
UIP_IP_BUF(buf)->tcflow = 0;
UIP_IP_BUF(buf)->flow = 0;
if (uip_ext_len(buf)) {
UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6;
} else {
UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6;
}
UIP_IP_BUF(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(buf)->srcipaddr)){
uip_len(buf) = 0;
return;
}
uip_ipaddr_copy(&UIP_IP_BUF(buf)->destipaddr, &UIP_IP_BUF(buf)->srcipaddr);
if(uip_is_addr_mcast(&tmp_ipaddr)){
if(type == ICMP6_PARAM_PROB && code == ICMP6_PARAMPROB_OPTION){
uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &tmp_ipaddr);
} else {
uip_len(buf) = 0;
return;
}
} else {
#if UIP_CONF_ROUTER
/* need to pick a source that corresponds to this node */
uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &tmp_ipaddr);
#else
uip_ipaddr_copy(&UIP_IP_BUF(buf)->srcipaddr, &tmp_ipaddr);
#endif
}
UIP_ICMP_BUF(buf)->type = type;
UIP_ICMP_BUF(buf)->icode = code;
UIP_ICMP6_ERROR_BUF(buf)->param = uip_htonl(param);
UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8);
UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - UIP_IPH_LEN) & 0xff);
UIP_ICMP_BUF(buf)->icmpchksum = 0;
UIP_ICMP_BUF(buf)->icmpchksum = ~uip_icmp6chksum(buf);
UIP_STAT(++uip_stat.icmp.sent);
PRINTF("Sending ICMPv6 ERROR message type %d code %d to ", type, code);
PRINT6ADDR(&UIP_IP_BUF(buf)->destipaddr);
PRINTF(" from ");
PRINT6ADDR(&UIP_IP_BUF(buf)->srcipaddr);
PRINTF("\n");
return;
}
/*---------------------------------------------------------------------------*/
void
uip_icmp6_send(struct net_buf *buf, const uip_ipaddr_t *dest, int type, int code, int payload_len)
{
UIP_IP_BUF(buf)->vtc = 0x60;
UIP_IP_BUF(buf)->tcflow = 0;
UIP_IP_BUF(buf)->flow = 0;
UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6;
UIP_IP_BUF(buf)->ttl = uip_ds6_if.cur_hop_limit;
UIP_IP_BUF(buf)->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8;
UIP_IP_BUF(buf)->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff;
memcpy(&UIP_IP_BUF(buf)->destipaddr, dest, sizeof(*dest));
uip_ds6_select_src(&UIP_IP_BUF(buf)->srcipaddr, &UIP_IP_BUF(buf)->destipaddr);
UIP_ICMP_BUF(buf)->type = type;
UIP_ICMP_BUF(buf)->icode = code;
UIP_ICMP_BUF(buf)->icmpchksum = 0;
UIP_ICMP_BUF(buf)->icmpchksum = ~uip_icmp6chksum(buf);
uip_len(buf) = UIP_IPH_LEN + UIP_ICMPH_LEN + payload_len;
net_buf_add(buf, uip_len(buf));
tcpip_ipv6_output(buf);
}
/*---------------------------------------------------------------------------*/
static void
echo_reply_input(struct net_buf *buf)
{
int ttl;
uip_ipaddr_t sender;
#if UIP_CONF_IPV6_RPL
uint8_t temp_ext_len;
#endif /* UIP_CONF_IPV6_RPL */
uip_ipaddr_copy(&sender, &UIP_IP_BUF(buf)->srcipaddr);
ttl = UIP_IP_BUF(buf)->ttl;
if(uip_ext_len(buf) > 0) {
#if UIP_CONF_IPV6_RPL
if((temp_ext_len = rpl_invert_header(buf))) {
/* If there were other extension headers*/
UIP_FIRST_EXT_BUF(buf)->next = UIP_PROTO_ICMP6;
if (uip_ext_len(buf) != temp_ext_len) {
uip_len(buf) -= (uip_ext_len(buf) - temp_ext_len);
UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8);
UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - 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 remaining extension headers
* present Note: UIP_ICMP_BUF still points to the echo reply
* at this stage
*/
memmove((uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN - (uip_ext_len(buf) - temp_ext_len),
(uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN,
(uip_len(buf) - UIP_IPH_LEN - temp_ext_len - UIP_ICMPH_LEN));
}
uip_ext_len(buf) = temp_ext_len;
uip_len(buf) -= uip_ext_len(buf);
} else {
#endif /* UIP_CONF_IPV6_RPL */
/* If there were extension headers*/
UIP_IP_BUF(buf)->proto = UIP_PROTO_ICMP6;
uip_len(buf) -= uip_ext_len(buf);
UIP_IP_BUF(buf)->len[0] = ((uip_len(buf) - UIP_IPH_LEN) >> 8);
UIP_IP_BUF(buf)->len[1] = ((uip_len(buf) - 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(buf) + UIP_ICMPH_LEN - uip_ext_len(buf),
(uint8_t *)UIP_ICMP_BUF(buf) + UIP_ICMPH_LEN,
(uip_len(buf) - UIP_IPH_LEN - UIP_ICMPH_LEN));
uip_ext_len(buf) = 0;
#if UIP_CONF_IPV6_RPL
}
#endif /* UIP_CONF_IPV6_RPL */
}
/* Call all registered applications to let them know an echo reply
has been received. */
{
struct uip_icmp6_echo_reply_notification *n;
for(n = list_head(echo_reply_callback_list);
n != NULL;
n = list_item_next(n)) {
if(n->callback != NULL) {
n->callback(&sender, ttl,
(uint8_t *)&UIP_ICMP_BUF(buf)[sizeof(struct uip_icmp_hdr)],
uip_len(buf) - sizeof(struct uip_icmp_hdr) - UIP_IPH_LEN);
}
}
}
uip_len(buf) = 0;
return;
}
/*---------------------------------------------------------------------------*/
void
uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n,
uip_icmp6_echo_reply_callback_t c)
{
if(n != NULL && c != NULL) {
n->callback = c;
list_add(echo_reply_callback_list, n);
}
}
/*---------------------------------------------------------------------------*/
void
uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n)
{
list_remove(echo_reply_callback_list, n);
}
/*---------------------------------------------------------------------------*/
UIP_ICMP6_HANDLER(echo_request_handler, ICMP6_ECHO_REQUEST,
UIP_ICMP6_HANDLER_CODE_ANY, echo_request_input);
UIP_ICMP6_HANDLER(echo_reply_handler, ICMP6_ECHO_REPLY,
UIP_ICMP6_HANDLER_CODE_ANY, echo_reply_input);
/*---------------------------------------------------------------------------*/
void
uip_icmp6_init()
{
/* Register Echo Request and Reply handlers */
uip_icmp6_register_input_handler(&echo_request_handler);
uip_icmp6_register_input_handler(&echo_reply_handler);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,243 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* Header file for ICMPv6 message and error handing (RFC 4443)
* \author Julien Abeille <jabeille@cisco.com>
* \author Mathilde Durvy <mdurvy@cisco.com>
*/
#include <net/buf.h>
#ifndef ICMP6_H_
#define ICMP6_H_
#include "contiki/ip/uip.h"
/** \name ICMPv6 message types */
/** @{ */
#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_ECHO_REQUEST 128 /**< Echo request */
#define ICMP6_ECHO_REPLY 129 /**< Echo reply */
#define ICMP6_RS 133 /**< Router Solicitation */
#define ICMP6_RA 134 /**< Router Advertisement */
#define ICMP6_NS 135 /**< Neighbor Solicitation */
#define ICMP6_NA 136 /**< Neighbor advertisement */
#define ICMP6_REDIRECT 137 /**< Redirect */
#define ICMP6_RPL 155 /**< RPL */
#define ICMP6_PRIV_EXP_100 100 /**< Private Experimentation */
#define ICMP6_PRIV_EXP_101 101 /**< Private Experimentation */
#define ICMP6_PRIV_EXP_200 200 /**< Private Experimentation */
#define ICMP6_PRIV_EXP_201 201 /**< Private Experimentation */
#define ICMP6_ROLL_TM ICMP6_PRIV_EXP_200 /**< ROLL Trickle Multicast */
/** @} */
/** \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_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_NOPORT 4 /**< port unreachable */
/** @} */
/** \name ICMPv6 Time Exceeded message codes*/
/** @{ */
#define ICMP6_TIME_EXCEED_TRANSIT 0 /**< ttl==0 in transit */
#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /**< ttl==0 in reass */
/** @} */
/** \name ICMPv6 Parameter Problem message codes*/
/** @{ */
#define ICMP6_PARAMPROB_HEADER 0 /**< erroneous header field */
#define ICMP6_PARAMPROB_NEXTHEADER 1 /**< unrecognized next header */
#define ICMP6_PARAMPROB_OPTION 2 /**< unrecognized option */
/** @} */
/** \brief Echo Request constant part length */
#define UIP_ICMP6_ECHO_REQUEST_LEN 4
/** \brief ICMPv6 Error message constant part length */
#define UIP_ICMP6_ERROR_LEN 4
/** \brief ICMPv6 Error message constant part */
typedef struct uip_icmp6_error{
uint32_t param;
} PACK_ALIAS_STRUCT uip_icmp6_error;
/** \name ICMPv6 RFC4443 Message processing and sending */
/** @{ */
/**
* \brief Send an icmpv6 error message
* \param type type of the error message
* \param code of the error message
* \param param 32 bit parameter of the error message, semantic depends on error
*/
void
uip_icmp6_error_output(struct net_buf *buf, uint8_t type, uint8_t code, uint32_t param);
/**
* \brief Send an icmpv6 message
* \param dest destination address of the message
* \param type type of the message
* \param code of the message
* \param payload_len length of the payload
*/
void
uip_icmp6_send(struct net_buf *buf, const uip_ipaddr_t *dest, int type, int code, int payload_len);
typedef void (* uip_icmp6_echo_reply_callback_t)(uip_ipaddr_t *source,
uint8_t ttl,
uint8_t *data,
uint16_t datalen);
struct uip_icmp6_echo_reply_notification {
struct uip_icmp6_echo_reply_notification *next;
uip_icmp6_echo_reply_callback_t callback;
};
/**
* \brief Add a callback function for ping replies
* \param n A struct uip_icmp6_echo_reply_notification that must have been allocated by the caller
* \param c A pointer to the callback function to be called
*
* This function adds a callback function to the list of
* callback functions that are called when an ICMP echo
* reply (ping reply) is received. This is used when
* implementing a ping protocol: attach a callback
* function to the ping reply, then send out a ping packet
* with uip_icmp6_send().
*
* The caller must have statically allocated a struct
* uip_icmp6_echo_reply_notification to hold the internal
* state of the callback function.
*
* When a ping reply packet is received, all registered
* callback functions are called. The callback functions
* must not modify the contents of the uIP buffer.
*/
void
uip_icmp6_echo_reply_callback_add(struct uip_icmp6_echo_reply_notification *n,
uip_icmp6_echo_reply_callback_t c);
/**
* \brief Remove a callback function for ping replies
* \param n A struct uip_icmp6_echo_reply_notification that must have been previously added with uip_icmp6_echo_reply_callback_add()
*
* This function removes a callback function from the list of
* callback functions that are called when an ICMP echo
* reply (ping reply) is received.
*/
void
uip_icmp6_echo_reply_callback_rm(struct uip_icmp6_echo_reply_notification *n);
/* Generic ICMPv6 input handers */
typedef struct uip_icmp6_input_handler {
struct uip_icmp6_input_handler *next;
uint8_t type;
uint8_t icode;
void (*handler)(struct net_buf *buf);
} uip_icmp6_input_handler_t;
#define UIP_ICMP6_INPUT_SUCCESS 0
#define UIP_ICMP6_INPUT_ERROR 1
#define UIP_ICMP6_HANDLER_CODE_ANY 0xFF /* Handle all codes for this type */
/*
* Initialise a variable of type uip_icmp6_input_handler, to be used later as
* the argument to uip_icmp6_register_input_handler
*
* The function pointer stored in this variable will get called and will be
* expected to handle incoming ICMPv6 datagrams of the specified type/code
*
* If code has a value of UIP_ICMP6_HANDLER_CODE_ANY, the same function
* will handle all codes for this type. In other words, the ICMPv6
* message's code is "don't care"
*/
#define UIP_ICMP6_HANDLER(name, type, code, func) \
static uip_icmp6_input_handler_t name = { NULL, type, code, func }
/**
* \brief Handle an incoming ICMPv6 message
* \param type The ICMPv6 message type
* \param icode The ICMPv6 message code
* \return Success: UIP_ICMP6_INPUT_SUCCESS, Error: UIP_ICMP6_INPUT_ERROR
*
* Generic handler for unknown ICMPv6 types. It will lookup for a registered
* function capable of handing this message type. The function must have first
* been registered with uip_icmp6_register_input_handler. The function is in
* charge of setting uip_len to 0, otherwise the uIPv6 core will attempt to
* send whatever remains in the UIP_IP_BUF.
*
* A return value of UIP_ICMP6_INPUT_ERROR means that a handler could not be
* invoked. This is most likely because the ICMPv6 type does not have a valid
* handler associated with it.
* UIP_ICMP6_INPUT_SUCCESS signifies that a handler was found for this ICMPv6
* type and that it was invoked. It does NOT provide any indication whatsoever
* regarding whether the handler itself succeeded.
*/
uint8_t uip_icmp6_input(struct net_buf *buf, uint8_t type, uint8_t icode);
/**
* \brief Register a handler which can handle a specific ICMPv6 message type
* \param handler A pointer to the handler
*/
void uip_icmp6_register_input_handler(uip_icmp6_input_handler_t *handler);
/**
* \brief Initialise the uIP ICMPv6 core
*/
void uip_icmp6_init(void);
/** @} */
#endif /*ICMP6_H_*/
/** @} */

File diff suppressed because it is too large Load diff

View file

@ -1,577 +0,0 @@
/*
* Copyright (c) 2006, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \addtogroup uip6
* @{
*/
/**
* \file
* Header file for IPv6 Neighbor discovery (RFC 4861)
* \author Julien Abeille <jabeille@cisco.com>
* \author Mathilde Durvy <mdurvy@cisco.com>
*/
#ifndef UIP_ND6_H_
#define UIP_ND6_H_
#include <net/ip_buf.h>
#include "contiki/ip/uip.h"
#include "sys/stimer.h"
/**
* \name General
* @{
*/
/** \brief HOP LIMIT to be used when sending ND messages (255) */
#define UIP_ND6_HOP_LIMIT 255
/** \brief INFINITE lifetime */
#define UIP_ND6_INFINITE_LIFETIME 0xFFFFFFFF
/** @} */
/** \name RFC 4861 Host constant */
/** @{ */
#define UIP_ND6_MAX_RTR_SOLICITATION_DELAY 1
#define UIP_ND6_RTR_SOLICITATION_INTERVAL 4
#define UIP_ND6_MAX_RTR_SOLICITATIONS 3
/** @} */
/** \name RFC 4861 Router constants */
/** @{ */
#ifndef UIP_CONF_ND6_SEND_RA
#define UIP_ND6_SEND_RA 1 /* enable/disable RA sending */
#else
#define UIP_ND6_SEND_RA UIP_CONF_ND6_SEND_RA
#endif
#ifndef UIP_CONF_ND6_SEND_NA
#define UIP_ND6_SEND_NA 1 /* enable/disable NA sending */
#else
#define UIP_ND6_SEND_NA UIP_CONF_ND6_SEND_NA
#endif
#ifndef UIP_CONF_ND6_MAX_RA_INTERVAL
#define UIP_ND6_MAX_RA_INTERVAL 600
#else
#define UIP_ND6_MAX_RA_INTERVAL UIP_CONF_ND6_MAX_RA_INTERVAL
#endif
#ifndef UIP_CONF_ND6_MIN_RA_INTERVAL
#define UIP_ND6_MIN_RA_INTERVAL (UIP_ND6_MAX_RA_INTERVAL / 3)
#else
#define UIP_ND6_MIN_RA_INTERVAL UIP_CONF_ND6_MIN_RA_INTERVAL
#endif
#define UIP_ND6_M_FLAG 0
#define UIP_ND6_O_FLAG (UIP_ND6_RA_RDNSS || UIP_ND6_RA_DNSSL)
#define UIP_ND6_ROUTER_LIFETIME 3 * UIP_ND6_MAX_RA_INTERVAL
#define UIP_ND6_MAX_INITIAL_RA_INTERVAL 16 /*seconds*/
#define UIP_ND6_MAX_INITIAL_RAS 3 /*transmissions*/
#ifndef UIP_CONF_ND6_MIN_DELAY_BETWEEN_RAS
#define UIP_ND6_MIN_DELAY_BETWEEN_RAS 3 /*seconds*/
#else
#define UIP_ND6_MIN_DELAY_BETWEEN_RAS UIP_CONF_ND6_MIN_DELAY_BETWEEN_RAS
#endif
//#define UIP_ND6_MAX_RA_DELAY_TIME 0.5 /*seconds*/
#define UIP_ND6_MAX_RA_DELAY_TIME_MS 500 /*milli seconds*/
/** @} */
#ifndef UIP_CONF_ND6_DEF_MAXDADNS
/** \brief Do not try DAD when using EUI-64 as allowed by draft-ietf-6lowpan-nd-15 section 8.2 */
#if UIP_CONF_LL_802154
#define UIP_ND6_DEF_MAXDADNS 0
#else /* UIP_CONF_LL_802154 */
#define UIP_ND6_DEF_MAXDADNS UIP_ND6_SEND_NA
#endif /* UIP_CONF_LL_802154 */
#else /* UIP_CONF_ND6_DEF_MAXDADNS */
#define UIP_ND6_DEF_MAXDADNS UIP_CONF_ND6_DEF_MAXDADNS
#endif /* UIP_CONF_ND6_DEF_MAXDADNS */
/** \name RFC 4861 Node constant */
#define UIP_ND6_MAX_MULTICAST_SOLICIT 3
#ifdef UIP_CONF_ND6_MAX_UNICAST_SOLICIT
#define UIP_ND6_MAX_UNICAST_SOLICIT UIP_CONF_ND6_MAX_UNICAST_SOLICIT
#else /* UIP_CONF_ND6_MAX_UNICAST_SOLICIT */
#define UIP_ND6_MAX_UNICAST_SOLICIT 3
#endif /* UIP_CONF_ND6_MAX_UNICAST_SOLICIT */
#ifdef UIP_CONF_ND6_REACHABLE_TIME
#define UIP_ND6_REACHABLE_TIME UIP_CONF_ND6_REACHABLE_TIME
#else
#define UIP_ND6_REACHABLE_TIME 30000
#endif
#ifdef UIP_CONF_ND6_RETRANS_TIMER
#define UIP_ND6_RETRANS_TIMER UIP_CONF_ND6_RETRANS_TIMER
#else
#define UIP_ND6_RETRANS_TIMER 1000
#endif
#define UIP_ND6_DELAY_FIRST_PROBE_TIME 5
#define UIP_ND6_MIN_RANDOM_FACTOR(x) (x / 2)
#define UIP_ND6_MAX_RANDOM_FACTOR(x) ((x) + (x) / 2)
/** @} */
/** \name RFC 6106 RA DNS Options Constants */
/** @{ */
#ifndef UIP_CONF_ND6_RA_RDNSS
#define UIP_ND6_RA_RDNSS 0
#else
#define UIP_ND6_RA_RDNSS UIP_CONF_ND6_RA_RDNSS
#endif
#ifndef UIP_CONF_ND6_RA_DNSSL
#define UIP_ND6_RA_DNSSL 0
#else
#error Not implemented
#define UIP_ND6_RA_DNSSL UIP_CONF_ND6_RA_DNSSL
#endif
/** @} */
/** \name ND6 option types */
/** @{ */
#define UIP_ND6_OPT_SLLAO 1
#define UIP_ND6_OPT_TLLAO 2
#define UIP_ND6_OPT_PREFIX_INFO 3
#define UIP_ND6_OPT_REDIRECTED_HDR 4
#define UIP_ND6_OPT_MTU 5
#define UIP_ND6_OPT_RDNSS 25
#define UIP_ND6_OPT_DNSSL 31
/** @} */
/** \name ND6 option types */
/** @{ */
#define UIP_ND6_OPT_TYPE_OFFSET 0
#define UIP_ND6_OPT_LEN_OFFSET 1
#define UIP_ND6_OPT_DATA_OFFSET 2
/** \name ND6 message length (excluding options) */
/** @{ */
#define UIP_ND6_NA_LEN 20
#define UIP_ND6_NS_LEN 20
#define UIP_ND6_RA_LEN 12
#define UIP_ND6_RS_LEN 4
/** @} */
/** \name ND6 option length in bytes */
/** @{ */
#define UIP_ND6_OPT_HDR_LEN 2
#define UIP_ND6_OPT_PREFIX_INFO_LEN 32
#define UIP_ND6_OPT_MTU_LEN 8
#define UIP_ND6_OPT_RDNSS_LEN 1
#define UIP_ND6_OPT_DNSSL_LEN 1
/* Length of TLLAO and SLLAO options, it is L2 dependant */
#if UIP_CONF_LL_802154
/* If the interface is 802.15.4. For now we use only long addresses */
#define UIP_ND6_OPT_SHORT_LLAO_LEN 8
#define UIP_ND6_OPT_LONG_LLAO_LEN 16
/** \brief length of a ND6 LLAO option for 802.15.4 */
#define UIP_ND6_OPT_LLAO_LEN UIP_ND6_OPT_LONG_LLAO_LEN
#else /*UIP_CONF_LL_802154*/
#if UIP_CONF_LL_80211
/* If the interface is 802.11 */
/** \brief length of a ND6 LLAO option for 802.11 */
#define UIP_ND6_OPT_LLAO_LEN 8
#else /*UIP_CONF_LL_80211*/
/** \brief length of a ND6 LLAO option for default L2 type (e.g. Ethernet) */
#define UIP_ND6_OPT_LLAO_LEN 8
#endif /*UIP_CONF_LL_80211*/
#endif /*UIP_CONF_LL_802154*/
/** @} */
/** \name Neighbor Advertisement flags masks */
/** @{ */
#define UIP_ND6_NA_FLAG_ROUTER 0x80
#define UIP_ND6_NA_FLAG_SOLICITED 0x40
#define UIP_ND6_NA_FLAG_OVERRIDE 0x20
#define UIP_ND6_RA_FLAG_ONLINK 0x80
#define UIP_ND6_RA_FLAG_AUTONOMOUS 0x40
/** @} */
/**
* \name ND message structures
* @{
*/
/**
* \brief A neighbor solicitation constant part
*
* Possible option is: SLLAO
*/
typedef struct uip_nd6_ns {
uint32_t reserved;
uip_ipaddr_t tgtipaddr;
} PACK_ALIAS_STRUCT uip_nd6_ns;
/**
* \brief A neighbor advertisement constant part.
*
* Possible option is: TLLAO
*/
typedef struct uip_nd6_na {
uint8_t flagsreserved;
uint8_t reserved[3];
uip_ipaddr_t tgtipaddr;
} PACK_ALIAS_STRUCT uip_nd6_na;
/**
* \brief A router solicitation constant part
*
* Possible option is: SLLAO
*/
typedef struct uip_nd6_rs {
uint32_t reserved;
} uip_nd6_rs;
/**
* \brief A router advertisement constant part
*
* Possible options are: SLLAO, MTU, Prefix Information
*/
typedef struct uip_nd6_ra {
uint8_t cur_ttl;
uint8_t flags_reserved;
uint16_t router_lifetime;
uint32_t reachable_time;
uint32_t retrans_timer;
} PACK_ALIAS_STRUCT uip_nd6_ra;
/**
* \brief A redirect message constant part
*
* Possible options are: TLLAO, redirected header
*/
typedef struct uip_nd6_redirect {
uint32_t reserved;
uip_ipaddr_t tgtipaddress;
uip_ipaddr_t destipaddress;
} uip_nd6_redirect;
/** @} */
/**
* \name ND Option structures
* @{
*/
/** \brief ND option header */
typedef struct uip_nd6_opt_hdr {
uint8_t type;
uint8_t len;
} PACK_ALIAS_STRUCT uip_nd6_opt_hdr;
/** \brief ND option prefix information */
typedef struct uip_nd6_opt_prefix_info {
uint8_t type;
uint8_t len;
uint8_t preflen;
uint8_t flagsreserved1;
uint32_t validlt;
uint32_t preferredlt;
uint32_t reserved2;
uip_ipaddr_t prefix;
} uip_nd6_opt_prefix_info ;
/** \brief ND option MTU */
typedef struct uip_nd6_opt_mtu {
uint8_t type;
uint8_t len;
uint16_t reserved;
uint32_t mtu;
} PACK_ALIAS_STRUCT uip_nd6_opt_mtu;
/** \brief ND option RDNSS */
typedef struct uip_nd6_opt_dns {
uint8_t type;
uint8_t len;
uint16_t reserved;
uint32_t lifetime;
uip_ipaddr_t ip;
} uip_nd6_opt_dns;
/** \struct Redirected header option */
typedef struct uip_nd6_opt_redirected_hdr {
uint8_t type;
uint8_t len;
uint8_t reserved[6];
} uip_nd6_opt_redirected_hdr;
/** @} */
/**
* \name ND Messages Processing and Generation
* @{
*/
/**
* \brief Process a neighbor solicitation
*
* The NS can be received in 3 cases (procedures):
* - sender is performing DAD (ip src = unspecified, no SLLAO option)
* - sender is performing NUD (ip dst = unicast)
* - sender is performing address resolution (ip dest = solicited node mcast
* address)
*
* We do:
* - if the tgt belongs to me, reply, otherwise ignore
* - if i was performing DAD for the same address, two cases:
* -- I already sent a NS, hence I win
* -- I did not send a NS yet, hence I lose
*
* If we need to send a NA in response (i.e. the NS was done for NUD, or
* address resolution, or DAD and there is a conflict), we do it in this
* function: set src, dst, tgt address in the three cases, then for all cases
* set the rest, including SLLAO
*
*/
void
uip_nd6_ns_input(void);
/**
* \brief Send a neighbor solicitation, send a Neighbor Advertisement
* \param src pointer to the src of the NS if known
* \param dest pointer to ip address to send the NS, for DAD or ADDR Resol,
* MUST be NULL, for NUD, must be correct unicast dest
* \param tgt pointer to ip address to fill the target address field, must
* not be NULL
*
* - RFC 4861, 7.2.2 :
* "If the source address of the packet prompting the solicitation is the
* same as one of the addresses assigned to the outgoing interface, that
* address SHOULD be placed in the IP Source Address of the outgoing
* solicitation. Otherwise, any one of the addresses assigned to the
* interface should be used."
* This is why we have a src ip address as argument. If NULL, we will do
* src address selection, otherwise we use the argument.
*
* - we check if it is a NS for Address resolution or NUD, if yes we include
* a SLLAO option, otherwise no.
*/
void
uip_nd6_ns_output(struct net_buf *buf, uip_ipaddr_t *src, uip_ipaddr_t *dest, uip_ipaddr_t *tgt);
#if UIP_CONF_ROUTER
#if UIP_ND6_SEND_RA
/**
* \brief send a Router Advertisement
*
* Only for router, for periodic as well as sollicited RA
*/
void uip_nd6_ra_output(uip_ipaddr_t *dest);
#endif /* UIP_ND6_SEND_RA */
#endif /*UIP_CONF_ROUTER*/
/**
* \brief Send a Router Solicitation
*
* src is chosen through the uip_netif_select_src function. If src is
* unspecified (i.e. we do not have a preferred address yet), then we do not
* put a SLLAO option (MUST NOT in RFC 4861). Otherwise we do.
*
* RS message format,
* possible option is SLLAO, MUST NOT be included if source = unspecified
* SHOULD be included otherwise
*/
void uip_nd6_rs_output(struct net_buf *buf);
/**
* \brief Initialise the uIP ND core
*/
void uip_nd6_init(void);
/** @} */
void
uip_appserver_addr_get(uip_ipaddr_t *ipaddr);
/*--------------------------------------*/
/** ANNEX - message formats ********/
/*--------------------------------------*/
/*
* RS format. possible option is SLLAO
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Code | Checksum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Options ...
* +-+-+-+-+-+-+-+-+-+-+-+-
*
*
* RA format. possible options: prefix information, MTU, SLLAO
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Code | Checksum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Cur Hop Limit |M|O| Reserved | Router Lifetime |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reachable Time |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Retrans Timer |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Options ...
* +-+-+-+-+-+-+-+-+-+-+-+-
*
*
* NS format: options should be SLLAO
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Code | Checksum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | |
* + Target Address +
* | |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Options ...
* +-+-+-+-+-+-+-+-+-+-+-+-
*
*
* NA message format. possible options is TLLAO
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Code | Checksum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* |R|S|O| Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | |
* + Target Address +
* | |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Options ...
* +-+-+-+-+-+-+-+-+-+-+-+-
*
*
* Redirect message format. Possible options are TLLAO and Redirected header
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Code | Checksum |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | |
* + Target Address +
* | |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | |
* + Destination Address +
* | |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Options ...
* +-+-+-+-+-+-+-+-+-+-+-+-
*
*
* SLLAO/TLLAO option:
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length | Link-Layer Address ...
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*
* Prefix information option
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length | Prefix Length |L|A| Reserved1 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Valid Lifetime |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Preferred Lifetime |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved2 |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + +
* | |
* + Prefix +
* | |
* + +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*
* MTU option
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | MTU |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*
* Redirected header option
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Length | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* ~ IP header + data ~
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*
*/
#endif /* UIP_ND6_H_ */
/** @} */

File diff suppressed because it is too large Load diff

View file

@ -1,90 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Functions for manipulating Rime addresses
* \author
* Adam Dunkels <adam@sics.se>
*/
/**
* \addtogroup linkaddr
* @{
*/
#include "contiki/linkaddr.h"
#include <string.h>
linkaddr_t linkaddr_node_addr;
#if LINKADDR_SIZE == 2
const linkaddr_t linkaddr_null = { { 0, 0 } };
#else /*LINKADDR_SIZE == 2*/
#if LINKADDR_SIZE == 8
const linkaddr_t linkaddr_null = { { 0, 0, 0, 0, 0, 0, 0, 0 } };
#else /*LINKADDR_SIZE == 8*/
#if LINKADDR_SIZE == 6
const linkaddr_t linkaddr_null = { { 0, 0, 0, 0, 0, 0 } };
#endif /*LINKADDR_SIZE == 6*/
#endif /*LINKADDR_SIZE == 8*/
#endif /*LINKADDR_SIZE == 2*/
/*---------------------------------------------------------------------------*/
void
linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
{
memcpy(dest, src, LINKADDR_SIZE);
}
/*---------------------------------------------------------------------------*/
int
linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
{
return (memcmp(addr1, addr2, LINKADDR_SIZE) == 0);
}
/*---------------------------------------------------------------------------*/
void
linkaddr_set_node_addr(linkaddr_t *t)
{
linkaddr_copy(&linkaddr_node_addr, t);
}
/*---------------------------------------------------------------------------*/
linkaddr_t *linkaddr_get_node_addr(int *addr_len)
{
if (addr_len) {
*addr_len = LINKADDR_SIZE;
}
return &linkaddr_node_addr;
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,140 +0,0 @@
/*
* Copyright (c) 2007, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* Header file for the Rime address representation
* \author
* Adam Dunkels <adam@sics.se>
*/
/**
* \addtogroup rime
* @{
*/
/**
* \defgroup linkaddr Rime addresses
* @{
*
* The linkaddr module is an abstract representation of addresses in
* Rime.
*
*/
#ifndef LINKADDR_H_
#define LINKADDR_H_
#include "contiki-conf.h"
#ifdef LINKADDR_CONF_SIZE
#define LINKADDR_SIZE LINKADDR_CONF_SIZE
#else /* LINKADDR_SIZE */
#define LINKADDR_SIZE 2
#endif /* LINKADDR_SIZE */
typedef union {
unsigned char u8[LINKADDR_SIZE];
#if LINKADDR_SIZE == 2
uint16_t u16;
#endif /* LINKADDR_SIZE == 2 */
} linkaddr_t;
typedef union {
uint8_t u8[8];
uint16_t u16[4];
} linkaddr_extended_t;
/**
* \brief Copy a Rime address
* \param dest The destination
* \param from The source
*
* This function copies a Rime address from one location
* to another.
*
*/
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *from);
/**
* \brief Compare two Rime addresses
* \param addr1 The first address
* \param addr2 The second address
* \return Non-zero if the addresses are the same, zero if they are different
*
* This function compares two Rime addresses and returns
* the result of the comparison. The function acts like
* the '==' operator and returns non-zero if the addresses
* are the same, and zero if the addresses are different.
*
*/
int linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2);
/**
* \brief Set the address of the current node
* \param addr The address
*
* This function sets the Rime address of the node.
*
*/
void linkaddr_set_node_addr(linkaddr_t *addr);
linkaddr_t *linkaddr_get_node_addr(int *addr_len);
/**
* \brief The Rime address of the node
*
* This variable contains the Rime address of the
* node. This variable should not be changed directly;
* rather, the linkaddr_set_node_addr() function should be
* used.
*
*/
extern linkaddr_t linkaddr_node_addr;
/**
* \brief The null Rime address
*
* This variable contains the null Rime address. The null
* address is used in route tables to indicate that the
* table entry is unused. Nodes with no configured address
* has the null address. Nodes with their node address set
* to the null address will have problems communicating
* with other nodes.
*
*/
extern const linkaddr_t linkaddr_null;
#endif /* LINKADDR_H_ */
/** @} */
/** @} */

View file

@ -1,112 +0,0 @@
/*
* 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 llsec802154
* @{
*/
#include <net/l2_buf.h>
#include "contiki/llsec/anti-replay.h"
#include "contiki/packetbuf.h"
/* This node's current frame counter value */
static uint32_t counter;
/*---------------------------------------------------------------------------*/
void
anti_replay_set_counter(struct net_buf *buf)
{
frame802154_frame_counter_t reordered_counter;
reordered_counter.u32 = LLSEC802154_HTONL(++counter);
packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, reordered_counter.u16[0]);
packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, reordered_counter.u16[1]);
}
/*---------------------------------------------------------------------------*/
uint32_t
anti_replay_get_counter(struct net_buf *buf)
{
frame802154_frame_counter_t disordered_counter;
disordered_counter.u16[0] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1);
disordered_counter.u16[1] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3);
return LLSEC802154_HTONL(disordered_counter.u32);
}
/*---------------------------------------------------------------------------*/
void
anti_replay_init_info(struct net_buf *buf, struct anti_replay_info *info)
{
info->last_broadcast_counter
= info->last_unicast_counter
= anti_replay_get_counter(buf);
}
/*---------------------------------------------------------------------------*/
int
anti_replay_was_replayed(struct net_buf *buf, struct anti_replay_info *info)
{
uint32_t received_counter;
received_counter = anti_replay_get_counter(buf);
if(packetbuf_holds_broadcast(buf)) {
/* 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;
}
}
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,82 +0,0 @@
/*
* 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
* Interface to anti-replay mechanisms.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
/**
* \addtogroup llsec802154
* @{
*/
#ifndef ANTI_REPLAY_H
#define ANTI_REPLAY_H
#include <net/l2_buf.h>
#include "contiki.h"
struct anti_replay_info {
uint32_t last_broadcast_counter;
uint32_t last_unicast_counter;
};
/**
* \brief Sets the frame counter packetbuf attributes.
*/
void anti_replay_set_counter(struct net_buf *buf);
/**
* \brief Gets the frame counter from packetbuf.
*/
uint32_t anti_replay_get_counter(struct net_buf *buf);
/**
* \brief Initializes the anti-replay information about the sender
* \param info Anti-replay information about the sender
*/
void anti_replay_init_info(struct net_buf *buf, struct anti_replay_info *info);
/**
* \brief Checks if received frame was replayed
* \param info Anti-replay information about the sender
* \retval 0 <-> received frame was not replayed
*/
int anti_replay_was_replayed(struct net_buf *buf, struct anti_replay_info *info);
#endif /* ANTI_REPLAY_H */
/** @} */

View file

@ -1,192 +0,0 @@
/*
* 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
* AES_128-based CCM* implementation.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
/**
* \addtogroup llsec802154
* @{
*/
#include <net/l2_buf.h>
#include "contiki/llsec/ccm-star.h"
#include "contiki/llsec/llsec802154.h"
#include "contiki/packetbuf.h"
#include "lib/aes-128.h"
#include <string.h>
/*---------------------------------------------------------------------------*/
static void
set_nonce(struct net_buf *buf, uint8_t *nonce,
uint8_t flags,
const uint8_t *extended_source_address,
uint8_t counter)
{
/* 1 byte|| 8 bytes || 4 bytes || 1 byte || 2 bytes */
/* flags || extended_source_address || frame_counter || sec_lvl || counter */
nonce[0] = flags;
memcpy(nonce + 1, extended_source_address, 8);
nonce[9] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8;
nonce[10] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff;
nonce[11] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8;
nonce[12] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff;
nonce[13] = packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL);
nonce[14] = 0;
nonce[15] = counter;
}
/*---------------------------------------------------------------------------*/
/* XORs the block m[pos] ... m[pos + 15] with K_{counter} */
static void
ctr_step(struct net_buf *buf, const uint8_t *extended_source_address,
uint8_t pos,
uint8_t *m_and_result,
uint8_t m_len,
uint8_t counter)
{
uint8_t a[AES_128_BLOCK_SIZE];
uint8_t i;
set_nonce(buf, a, CCM_STAR_ENCRYPTION_FLAGS, extended_source_address, counter);
AES_128.encrypt(a);
for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
m_and_result[pos + i] ^= a[i];
}
}
/*---------------------------------------------------------------------------*/
static void
mic(struct net_buf *buf, const uint8_t *extended_source_address,
uint8_t *result,
uint8_t mic_len)
{
uint8_t x[AES_128_BLOCK_SIZE];
uint8_t pos;
uint8_t i;
uint8_t a_len;
uint8_t *a;
#if LLSEC802154_USES_ENCRYPTION
uint8_t shall_encrypt;
uint8_t m_len;
uint8_t *m;
shall_encrypt = packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL) & (1 << 2);
if(shall_encrypt) {
a_len = packetbuf_hdrlen(buf);
m_len = packetbuf_datalen(buf);
} else {
a_len = packetbuf_totlen(buf);
m_len = 0;
}
set_nonce(x,
CCM_STAR_AUTH_FLAGS(a_len, mic_len),
extended_source_address,
m_len);
#else /* LLSEC802154_USES_ENCRYPTION */
a_len = packetbuf_totlen(buf);
set_nonce(buf, x,
CCM_STAR_AUTH_FLAGS(a_len, mic_len),
extended_source_address,
0);
#endif /* LLSEC802154_USES_ENCRYPTION */
AES_128.encrypt(x);
a = packetbuf_hdrptr(buf);
if(a_len) {
x[1] = x[1] ^ a_len;
for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) {
x[i] ^= a[i - 2];
}
AES_128.encrypt(x);
pos = 14;
while(pos < a_len) {
for(i = 0; (pos + i < a_len) && (i < AES_128_BLOCK_SIZE); i++) {
x[i] ^= a[pos + i];
}
pos += AES_128_BLOCK_SIZE;
AES_128.encrypt(x);
}
}
#if LLSEC802154_USES_ENCRYPTION
if(shall_encrypt) {
m = a + a_len;
pos = 0;
while(pos < m_len) {
for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
x[i] ^= m[pos + i];
}
pos += AES_128_BLOCK_SIZE;
AES_128.encrypt(x);
}
}
#endif /* LLSEC802154_USES_ENCRYPTION */
ctr_step(buf, extended_source_address, 0, x, AES_128_BLOCK_SIZE, 0);
memcpy(result, x, mic_len);
}
/*---------------------------------------------------------------------------*/
static void
ctr(struct net_buf *buf, const uint8_t *extended_source_address)
{
uint8_t m_len;
uint8_t *m;
uint8_t pos;
uint8_t counter;
m_len = packetbuf_datalen(buf);
m = (uint8_t *) packetbuf_dataptr(buf);
pos = 0;
counter = 1;
while(pos < m_len) {
ctr_step(buf, extended_source_address, pos, m, m_len, counter++);
pos += AES_128_BLOCK_SIZE;
}
}
/*---------------------------------------------------------------------------*/
const struct ccm_star_driver ccm_star_driver = {
mic,
ctr
};
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,87 +0,0 @@
/*
* 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* header file.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
/**
* \addtogroup llsec802154
* @{
*/
#ifndef CCM_STAR_H_
#define CCM_STAR_H_
#include <net/l2_buf.h>
#include "contiki.h"
#include "contiki/mac/frame802154.h"
/* see RFC 3610 */
#define CCM_STAR_AUTH_FLAGS(Adata, M) ((Adata ? (1 << 6) : 0) | (((M - 2) >> 1) << 3) | 1)
#define CCM_STAR_ENCRYPTION_FLAGS 1
#ifdef CCM_STAR_CONF
#define CCM_STAR CCM_STAR_CONF
#else /* CCM_STAR_CONF */
#define CCM_STAR ccm_star_driver
#endif /* CCM_STAR_CONF */
/**
* Structure of CCM* drivers.
*/
struct ccm_star_driver {
/**
* \brief Generates a MIC over the frame in the packetbuf.
* \param result The generated MIC will be put here
* \param mic_len <= 16; set to LLSEC802154_MIC_LENGTH to be compliant
*/
void (* mic)(struct net_buf *buf, const uint8_t *extended_source_address,
uint8_t *result,
uint8_t mic_len);
/**
* \brief XORs the frame in the packetbuf with the key stream.
*/
void (* ctr)(struct net_buf *buf, const uint8_t *extended_source_address);
};
extern const struct ccm_star_driver CCM_STAR;
#endif /* CCM_STAR_H_ */
/** @} */

View file

@ -1,99 +0,0 @@
/*
* 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
* Link layer security header file.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
/**
* \ingroup net
* \defgroup llsec Link Layer Security
*
* Layer for implementing link layer security.
*
* NETSTACK_LLSEC sits in between NETSTACK_MAC and NETSTACK_NETWORK
* protocols. All NETSTACK_MAC protocols invoke NETSTACK_LLSEC.input()
* for incoming packets. Likewise, all NETSTACK_NETWORK protocols
* invoke NETSTACK_LLSEC.send(...) for outgoing packets.
*
* The bootstrap function of llsec_drivers can be used to defer the start
* of upper layers so as to bootstrap pairwise keys. Only contiki-sky-main.c
* supports this at the moment.
*
* @{
*/
#include <stdbool.h>
#include <net/buf.h>
#include "contiki/mac/mac.h"
#ifndef LLSEC_H_
#define LLSEC_H_
typedef void (* llsec_on_bootstrapped_t)(void);
/**
* The structure of a link layer security driver.
*/
struct llsec_driver {
char *name;
/** Bootstraps link layer security and thereafter starts upper layers. */
void (* bootstrap)(llsec_on_bootstrapped_t on_bootstrapped);
/** Secures outgoing frames before passing them to NETSTACK_MAC. */
uint8_t (* send)(struct net_buf *buf, mac_callback_t sent_callback,
bool last_fragment, void *ptr);
/**
* Once the NETSTACK_FRAMER wrote the headers, the LLSEC driver
* can generate a MIC over the entire frame.
* \return Returns != 0 <-> success
*/
int (* on_frame_created)(void);
/**
* Decrypts incoming frames;
* filters out injected or replayed frames.
*/
uint8_t (* input)(struct net_buf *buf);
/** Returns the security-related overhead per frame in bytes */
uint8_t (* get_overhead)(void);
};
#endif /* LLSEC_H_ */
/** @} */

View file

@ -1,99 +0,0 @@
/*
* 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
* Common functionality of 802.15.4-compliant llsec_drivers.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
/**
* \addtogroup llsec
* @{
*/
/**
* \defgroup llsec802154 Link Layer Security Common Functionality
*
* Common functionality of 802.15.4-compliant llsec_drivers.
*
* @{
*/
#ifndef LLSEC802154_H_
#define LLSEC802154_H_
#include "contiki/mac/frame802154.h"
#include "contiki/ip/uip.h"
#ifdef LLSEC802154_CONF_SECURITY_LEVEL
#define LLSEC802154_SECURITY_LEVEL LLSEC802154_CONF_SECURITY_LEVEL
#else /* LLSEC802154_CONF_SECURITY_LEVEL */
#define LLSEC802154_SECURITY_LEVEL FRAME802154_SECURITY_LEVEL_NONE
#endif /* LLSEC802154_CONF_SECURITY_LEVEL */
#if ((LLSEC802154_SECURITY_LEVEL < 0) || (LLSEC802154_SECURITY_LEVEL > 7))
#error "unsupported security level"
#endif
#define LLSEC802154_SECURITY_LEVEL_MIC (LLSEC802154_SECURITY_LEVEL & 3)
#if LLSEC802154_SECURITY_LEVEL_MIC
#define LLSEC802154_MIC_LENGTH (2 << LLSEC802154_SECURITY_LEVEL_MIC)
#else
#define LLSEC802154_MIC_LENGTH 0
#endif
#ifdef LLSEC802154_CONF_USES_ENCRYPTION
#define LLSEC802154_USES_ENCRYPTION LLSEC802154_CONF_USES_ENCRYPTION
#else /* LLSEC802154_CONF_USES_ENCRYPTION */
#define LLSEC802154_USES_ENCRYPTION (LLSEC802154_SECURITY_LEVEL & (1 << 2))
#endif /* LLSEC802154_CONF_USES_ENCRYPTION */
#ifdef LLSEC802154_CONF_USES_EXPLICIT_KEYS
#define LLSEC802154_USES_EXPLICIT_KEYS LLSEC802154_CONF_USES_EXPLICIT_KEYS
#else /* LLSEC802154_CONF_USES_EXPLICIT_KEYS */
#define LLSEC802154_USES_EXPLICIT_KEYS 0
#endif /* LLSEC802154_CONF_USES_EXPLICIT_KEYS */
#if UIP_BYTE_ORDER == UIP_LITTLE_ENDIAN
#define LLSEC802154_HTONS(n) (n)
#define LLSEC802154_HTONL(n) (n)
#else /* UIP_CONF_BYTE_ORDER == UIP_LITTLE_ENDIAN */
#define LLSEC802154_HTONS(n) (uint16_t)((((uint16_t) (n)) << 8) | (((uint16_t) (n)) >> 8))
#define LLSEC802154_HTONL(n) (((uint32_t)UIP_HTONS(n) << 16) | UIP_HTONS((uint32_t)(n) >> 16))
#endif /* UIP_CONF_BYTE_ORDER == UIP_LITTLE_ENDIAN */
#endif /* LLSEC802154_H_ */
/** @} */
/** @} */

View file

@ -1,105 +0,0 @@
/*
* 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
* Insecure link layer security driver.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
/**
* \addtogroup nullsec
* @{
*/
#include <net/l2_buf.h>
#include "contiki/llsec/nullsec.h"
#include "contiki/mac/frame802154.h"
#include "contiki/netstack.h"
#include "contiki/packetbuf.h"
#define DEBUG 0
#include "contiki/ip/uip-debug.h"
#if UIP_LOGGING
#include <stdio.h>
void uip_log(char *msg);
#define UIP_LOG(m) uip_log(m)
#else
#define UIP_LOG(m)
#endif
/*---------------------------------------------------------------------------*/
static void
bootstrap(llsec_on_bootstrapped_t on_bootstrapped)
{
on_bootstrapped();
}
/*---------------------------------------------------------------------------*/
static uint8_t
send(struct net_buf *buf, mac_callback_t sent, bool last_fragment, void *ptr)
{
packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_TYPE, FRAME802154_DATAFRAME);
return NETSTACK_MAC.send(buf, sent, last_fragment, ptr);
}
/*---------------------------------------------------------------------------*/
static int
on_frame_created(void)
{
return 1;
}
/*---------------------------------------------------------------------------*/
static uint8_t
input(struct net_buf *buf)
{
return NETSTACK_FRAGMENT.reassemble(buf);
}
/*---------------------------------------------------------------------------*/
static uint8_t
get_overhead(void)
{
return 0;
}
/*---------------------------------------------------------------------------*/
const struct llsec_driver nullsec_driver = {
"nullsec",
bootstrap,
send,
on_frame_created,
input,
get_overhead
};
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -1,63 +0,0 @@
/*
* 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
* Insecure link layer security driver.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
*/
/**
* \addtogroup llsec
* @{
*/
/**
* \defgroup nullsec LLSEC driver with zero security (NULLSEC)
*
* Insecure link layer security driver.
*
* @{
*/
#ifndef NULLSEC_H_
#define NULLSEC_H_
#include "contiki/llsec/llsec.h"
extern const struct llsec_driver nullsec_driver;
#endif /* NULLSEC_H_ */
/** @} */
/** @} */

View file

@ -1,479 +0,0 @@
/*
* Copyright (c) 2010, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the Contiki operating system.
*
*/
/**
* \file
* A Carrier Sense Multiple Access (CSMA) MAC layer
* \author
* Adam Dunkels <adam@sics.se>
*/
#include <net/l2_buf.h>
#include "contiki/mac/csma.h"
#include "contiki/packetbuf.h"
#include "contiki/queuebuf.h"
#include "sys/ctimer.h"
#include "sys/clock.h"
#include "lib/random.h"
#include "contiki/netstack.h"
#include "lib/list.h"
#include "lib/memb.h"
#include <string.h>
#include <stdio.h>
#if UIP_LOGGING
#include <stdio.h>
void uip_log(char *msg);
#define UIP_LOG(m) uip_log(m)
#else
#define UIP_LOG(m)
#endif
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_15_4_MAC
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
#if UIP_LOGGING
#include <stdio.h>
void uip_log(char *msg);
#define UIP_LOG(m) uip_log(m)
#else
#define UIP_LOG(m)
#endif
#ifndef CSMA_MAX_BACKOFF_EXPONENT
#ifdef CSMA_CONF_MAX_BACKOFF_EXPONENT
#define CSMA_MAX_BACKOFF_EXPONENT CSMA_CONF_MAX_BACKOFF_EXPONENT
#else
#define CSMA_MAX_BACKOFF_EXPONENT 3
#endif /* CSMA_CONF_MAX_BACKOFF_EXPONENT */
#endif /* CSMA_MAX_BACKOFF_EXPONENT */
#ifndef CSMA_MAX_MAC_TRANSMISSIONS
#ifdef CSMA_CONF_MAX_MAC_TRANSMISSIONS
#define CSMA_MAX_MAC_TRANSMISSIONS CSMA_CONF_MAX_MAC_TRANSMISSIONS
#else
#define CSMA_MAX_MAC_TRANSMISSIONS 3
#endif /* CSMA_CONF_MAX_MAC_TRANSMISSIONS */
#endif /* CSMA_MAX_MAC_TRANSMISSIONS */
#if CSMA_MAX_MAC_TRANSMISSIONS < 1
#error CSMA_CONF_MAX_MAC_TRANSMISSIONS must be at least 1.
#error Change CSMA_CONF_MAX_MAC_TRANSMISSIONS in contiki-conf.h or in your Makefile.
#endif /* CSMA_CONF_MAX_MAC_TRANSMISSIONS < 1 */
/* Packet metadata */
struct qbuf_metadata {
mac_callback_t sent;
void *cptr;
uint8_t max_transmissions;
};
/* Every neighbor has its own packet queue */
struct neighbor_queue {
struct neighbor_queue *next;
linkaddr_t addr;
struct ctimer transmit_timer;
uint8_t transmissions;
uint8_t collisions, deferrals;
LIST_STRUCT(queued_packet_list);
};
/* The maximum number of co-existing neighbor queues */
#ifdef CSMA_CONF_MAX_NEIGHBOR_QUEUES
#define CSMA_MAX_NEIGHBOR_QUEUES CSMA_CONF_MAX_NEIGHBOR_QUEUES
#else
#define CSMA_MAX_NEIGHBOR_QUEUES 2
#endif /* CSMA_CONF_MAX_NEIGHBOR_QUEUES */
/* The maximum number of pending packet per neighbor */
#ifdef CSMA_CONF_MAX_PACKET_PER_NEIGHBOR
#define CSMA_MAX_PACKET_PER_NEIGHBOR CSMA_CONF_MAX_PACKET_PER_NEIGHBOR
#else
#define CSMA_MAX_PACKET_PER_NEIGHBOR MAX_QUEUED_PACKETS
#endif /* CSMA_CONF_MAX_PACKET_PER_NEIGHBOR */
#define MAX_QUEUED_PACKETS QUEUEBUF_NUM
MEMB(neighbor_memb, struct neighbor_queue, CSMA_MAX_NEIGHBOR_QUEUES);
MEMB(packet_memb, struct rdc_buf_list, MAX_QUEUED_PACKETS);
MEMB(metadata_memb, struct qbuf_metadata, MAX_QUEUED_PACKETS);
static void packet_sent(struct net_buf *buf, void *ptr, int status, int num_transmissions);
static void transmit_packet_list(struct net_buf *buf, void *ptr);
/*---------------------------------------------------------------------------*/
static struct neighbor_queue *
neighbor_queue_from_addr(struct net_buf *buf, const linkaddr_t *addr)
{
struct neighbor_queue *n = list_head(uip_neighbor_list(buf));
while(n != NULL) {
if(linkaddr_cmp(&n->addr, addr)) {
return n;
}
n = list_item_next(n);
}
return NULL;
}
/*---------------------------------------------------------------------------*/
static clock_time_t
default_timebase(void)
{
clock_time_t time;
/* The retransmission time must be proportional to the channel
check interval of the underlying radio duty cycling layer. */
time = NETSTACK_RDC.channel_check_interval();
/* If the radio duty cycle has no channel check interval (i.e., it
does not turn the radio off), we make the retransmission time
proportional to the configured MAC channel check rate. */
if(time == 0) {
time = CLOCK_SECOND / NETSTACK_RDC_CHANNEL_CHECK_RATE;
}
return time;
}
/*---------------------------------------------------------------------------*/
static void
free_packet(struct net_buf *buf, struct neighbor_queue *n, struct rdc_buf_list *p)
{
if(p != NULL) {
/* Remove packet from list and deallocate */
list_remove(n->queued_packet_list, p);
queuebuf_free(p->buf);
memb_free(&metadata_memb, p->ptr);
memb_free(&packet_memb, p);
PRINTF("csma: free_queued_packet, queue length %d, free packets %d\n",
list_length(n->queued_packet_list), memb_numfree(&packet_memb));
if(list_head(n->queued_packet_list) != NULL) {
/* There is a next packet. We reset current tx information */
n->transmissions = 0;
n->collisions = 0;
n->deferrals = 0;
transmit_packet_list(buf, n);
} else {
/* This was the last packet in the queue, we free the neighbor */
list_remove(uip_neighbor_list(buf), n);
memb_free(&neighbor_memb, n);
}
}
}
/*---------------------------------------------------------------------------*/
static void
transmit_packet_list(struct net_buf *buf, void *ptr)
{
struct neighbor_queue *n = ptr;
if(n) {
struct rdc_buf_list *q = list_head(n->queued_packet_list);
if(q != NULL) {
PRINTF("csma: preparing number %d %p, queue len %d\n", n->transmissions, q,
list_length(n->queued_packet_list));
/* Send packets in the neighbor's list */
NETSTACK_RDC.send_list(buf, packet_sent, n, q);
}
}
}
/*---------------------------------------------------------------------------*/
static void
packet_sent(struct net_buf *buf, void *ptr, int status, int num_transmissions)
{
struct neighbor_queue *n;
struct rdc_buf_list *q;
struct qbuf_metadata *metadata;
clock_time_t time = 0;
mac_callback_t sent;
void *cptr;
int num_tx;
int backoff_exponent;
int backoff_transmissions;
n = ptr;
if(n == NULL) {
return;
}
switch(status) {
case MAC_TX_OK:
case MAC_TX_NOACK:
n->transmissions += num_transmissions;
break;
case MAC_TX_COLLISION:
n->collisions += num_transmissions;
n->transmissions += num_transmissions;
break;
case MAC_TX_DEFERRED:
n->deferrals += num_transmissions;
break;
}
/* Find out what packet this callback refers to */
for(q = list_head(n->queued_packet_list);
q != NULL; q = list_item_next(q)) {
if(queuebuf_attr(q->buf, PACKETBUF_ATTR_MAC_SEQNO) ==
packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO)) {
break;
}
}
if(q != NULL) {
metadata = (struct qbuf_metadata *)q->ptr;
if(metadata != NULL) {
sent = metadata->sent;
cptr = metadata->cptr;
num_tx = n->transmissions;
if(status == MAC_TX_COLLISION ||
status == MAC_TX_NOACK) {
/* If the transmission was not performed because of a
collision or noack, we must retransmit the packet. */
switch(status) {
case MAC_TX_COLLISION:
PRINTF("csma: rexmit collision %d transmission %d\n",
n->collisions, n->transmissions);
break;
case MAC_TX_NOACK:
PRINTF("csma: rexmit noack %d\n", n->transmissions);
break;
default:
PRINTF("csma: rexmit err %d, %d\n", status, n->transmissions);
}
/* The retransmission time must be proportional to the channel
check interval of the underlying radio duty cycling layer. */
time = default_timebase();
/* The retransmission time uses a truncated exponential backoff
* so that the interval between the transmissions increase with
* each retransmit. */
backoff_exponent = num_tx;
/* Truncate the exponent if needed. */
if(backoff_exponent > CSMA_MAX_BACKOFF_EXPONENT) {
backoff_exponent = CSMA_MAX_BACKOFF_EXPONENT;
}
/* Proceed to exponentiation. */
backoff_transmissions = 1 << backoff_exponent;
/* Pick a time for next transmission, within the interval:
* [time, time + 2^backoff_exponent * time[ */
time = time + (random_rand() % (backoff_transmissions * time));
if(n->transmissions < metadata->max_transmissions) {
PRINTF("csma: retransmitting with time %lu %p\n", time, q);
ctimer_set(buf, &n->transmit_timer, time,
transmit_packet_list, n);
/* This is needed to correctly attribute energy that we spent
transmitting this packet. */
queuebuf_update_attr_from_packetbuf(buf, q->buf);
} else {
PRINTF("csma: drop with status %d after %d transmissions, %d collisions\n",
status, n->transmissions, n->collisions);
free_packet(buf, n, q);
mac_call_sent_callback(buf, sent, cptr, status, num_tx);
}
} else {
if(status == MAC_TX_OK) {
PRINTF("csma: rexmit ok %d\n", n->transmissions);
} else {
PRINTF("csma: rexmit failed %d: %d\n", n->transmissions, status);
}
free_packet(buf, n, q);
mac_call_sent_callback(buf, sent, cptr, status, num_tx);
}
} else {
PRINTF("csma: no metadata\n");
}
} else {
PRINTF("csma: seqno %d not found\n", packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO));
}
}
/*---------------------------------------------------------------------------*/
static uint8_t
send_packet(struct net_buf *buf, mac_callback_t sent, bool last_fragment, void *ptr)
{
struct rdc_buf_list *q;
struct neighbor_queue *n;
static uint8_t initialized = 0;
static uint16_t seqno;
const linkaddr_t *addr = packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER);
if (!buf) {
UIP_LOG("csma: send_packet(): net_buf is NULL, cannot send packet");
return 0;
}
if(!initialized) {
initialized = 1;
/* Initialize the sequence number to a random value as per 802.15.4. */
seqno = random_rand();
}
if(seqno == 0) {
/* PACKETBUF_ATTR_MAC_SEQNO cannot be zero, due to a pecuilarity
in framer-802154.c. */
seqno++;
}
packetbuf_set_attr(buf, PACKETBUF_ATTR_MAC_SEQNO, seqno++);
/* Look for the neighbor entry */
n = neighbor_queue_from_addr(buf, addr);
if(n == NULL) {
/* Allocate a new neighbor entry */
n = memb_alloc(&neighbor_memb);
if(n != NULL) {
/* Init neighbor entry */
linkaddr_copy(&n->addr, addr);
n->transmissions = 0;
n->collisions = 0;
n->deferrals = 0;
/* Init packet list for this neighbor */
LIST_STRUCT_INIT(n, queued_packet_list);
/* Add neighbor to the list */
list_add(uip_neighbor_list(buf), n);
}
}
if(n != NULL) {
/* Add packet to the neighbor's queue */
if(list_length(n->queued_packet_list) < CSMA_MAX_PACKET_PER_NEIGHBOR) {
q = memb_alloc(&packet_memb);
if(q != NULL) {
q->ptr = memb_alloc(&metadata_memb);
if(q->ptr != NULL) {
q->buf = queuebuf_new_from_packetbuf(buf);
if(q->buf != NULL) {
struct qbuf_metadata *metadata = (struct qbuf_metadata *)q->ptr;
/* Neighbor and packet successfully allocated */
if(packetbuf_attr(buf, PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS) == 0) {
/* Use default configuration for max transmissions */
metadata->max_transmissions = CSMA_MAX_MAC_TRANSMISSIONS;
} else {
metadata->max_transmissions =
packetbuf_attr(buf, PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS);
}
metadata->sent = sent;
metadata->cptr = ptr;
if(packetbuf_attr(buf, PACKETBUF_ATTR_PACKET_TYPE) ==
PACKETBUF_ATTR_PACKET_TYPE_ACK) {
list_push(n->queued_packet_list, q);
} else {
list_add(n->queued_packet_list, q);
}
PRINTF("csma: send_packet, queue length %d, free packets %d\n",
list_length(n->queued_packet_list), memb_numfree(&packet_memb));
/* if received packet is last fragment/only one packet start sending
* packets in list, do not start any timer.*/
if (last_fragment) {
transmit_packet_list(buf, n);
}
return 1;
}
memb_free(&metadata_memb, q->ptr);
PRINTF("csma: could not allocate queuebuf, dropping packet\n");
}
memb_free(&packet_memb, q);
PRINTF("csma: could not allocate queuebuf, dropping packet\n");
}
/* The packet allocation failed. Remove and free neighbor entry if empty. */
if(list_length(n->queued_packet_list) == 0) {
list_remove(uip_neighbor_list(buf), n);
memb_free(&neighbor_memb, n);
}
} else {
PRINTF("csma: Neighbor queue full\n");
}
PRINTF("csma: could not allocate packet, dropping packet\n");
} else {
PRINTF("csma: could not allocate neighbor, dropping packet\n");
}
mac_call_sent_callback(buf, sent, ptr, MAC_TX_ERR, 1);
return 0;
}
/*---------------------------------------------------------------------------*/
static uint8_t
input_packet(struct net_buf *buf)
{
return NETSTACK_LLSEC.input(buf);
}
/*---------------------------------------------------------------------------*/
static int
on(void)
{
return NETSTACK_RDC.on();
}
/*---------------------------------------------------------------------------*/
static int
off(int keep_radio_on)
{
return NETSTACK_RDC.off(keep_radio_on);
}
/*---------------------------------------------------------------------------*/
static unsigned short
channel_check_interval(void)
{
if(NETSTACK_RDC.channel_check_interval) {
return NETSTACK_RDC.channel_check_interval();
}
return 0;
}
/*---------------------------------------------------------------------------*/
static void
init(void)
{
queuebuf_init();
memb_init(&packet_memb);
memb_init(&metadata_memb);
memb_init(&neighbor_memb);
}
/*---------------------------------------------------------------------------*/
const struct mac_driver csma_driver = {
"CSMA",
init,
send_packet,
input_packet,
on,
off,
channel_check_interval,
};
/*---------------------------------------------------------------------------*/

View file

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

View file

@ -1,404 +0,0 @@
/*
*
* Copyright (c) 2008, Swedish Institute of Computer Science
* All rights reserved.
*
* Additional fixes for AVR contributed 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
*
* Additional fixes for MSP430 contributed by:
* Joakim Eriksson
* Niclas Finne
* Nicolas Tsiftes
*
* 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.
*
*/
/*
* \brief This file is where the main functions that relate to frame
* manipulation will reside.
*/
/**
* \file
* \brief 802.15.4 frame creation and parsing functions
*
* This file converts to and from a structure to a packed 802.15.4
* frame.
*/
/**
* \addtogroup frame802154
* @{
*/
#include "sys/cc.h"
#include "contiki/mac/frame802154.h"
#include "contiki/llsec/llsec802154.h"
#include "contiki/linkaddr.h"
#include <string.h>
/**
* \brief Structure that contains the lengths of the various addressing and security fields
* in the 802.15.4 header. This structure is used in \ref frame802154_create()
*/
typedef struct {
uint8_t dest_pid_len; /**< Length (in bytes) of destination PAN ID field */
uint8_t dest_addr_len; /**< Length (in bytes) of destination address field */
uint8_t src_pid_len; /**< Length (in bytes) of source PAN ID field */
uint8_t src_addr_len; /**< Length (in bytes) of source address field */
uint8_t aux_sec_len; /**< Length (in bytes) of aux security header field */
} field_length_t;
/*----------------------------------------------------------------------------*/
CC_INLINE static uint8_t
addr_len(uint8_t mode)
{
switch(mode) {
case FRAME802154_SHORTADDRMODE: /* 16-bit address */
return 2;
case FRAME802154_LONGADDRMODE: /* 64-bit address */
return 8;
default:
return 0;
}
}
/*----------------------------------------------------------------------------*/
#if LLSEC802154_USES_EXPLICIT_KEYS
static uint8_t
get_key_id_len(uint8_t key_id_mode)
{
switch(key_id_mode) {
case FRAME802154_1_BYTE_KEY_ID_MODE:
return 1;
case FRAME802154_5_BYTE_KEY_ID_MODE:
return 5;
case FRAME802154_9_BYTE_KEY_ID_MODE:
return 9;
default:
return 0;
}
}
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
/*----------------------------------------------------------------------------*/
static void
field_len(frame802154_t *p, field_length_t *flen)
{
/* init flen to zeros */
memset(flen, 0, sizeof(field_length_t));
/* Determine lengths of each field based on fcf and other args */
if(p->fcf.dest_addr_mode & 3) {
flen->dest_pid_len = 2;
}
if(p->fcf.src_addr_mode & 3) {
flen->src_pid_len = 2;
}
/* Set PAN ID compression bit if src pan id matches dest pan id. */
if(p->fcf.dest_addr_mode & 3 && p->fcf.src_addr_mode & 3 &&
p->src_pid == p->dest_pid) {
p->fcf.panid_compression = 1;
/* compressed header, only do dest pid */
flen->src_pid_len = 0;
} else {
p->fcf.panid_compression = 0;
}
/* determine address lengths */
flen->dest_addr_len = addr_len(p->fcf.dest_addr_mode & 3);
flen->src_addr_len = addr_len(p->fcf.src_addr_mode & 3);
#if LLSEC802154_SECURITY_LEVEL
/* Aux security header */
if(p->fcf.security_enabled & 1) {
flen->aux_sec_len = 5
#if LLSEC802154_USES_EXPLICIT_KEYS
+ get_key_id_len(p->aux_hdr.security_control.key_id_mode);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
;
}
#endif /* LLSEC802154_SECURITY_LEVEL */
}
/*----------------------------------------------------------------------------*/
/**
* \brief Calculates the length of the frame header. This function is
* meant to be called by a higher level function, that interfaces to a MAC.
*
* \param p Pointer to frame802154_t_t struct, which specifies the
* frame to send.
*
* \return The length of the frame header.
*/
int
frame802154_hdrlen(frame802154_t *p)
{
field_length_t flen;
field_len(p, &flen);
return 3 + flen.dest_pid_len + flen.dest_addr_len +
flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len;
}
/*----------------------------------------------------------------------------*/
/**
* \brief Creates a frame for transmission over the air. This function is
* meant to be called by a higher level function, that interfaces to a MAC.
*
* \param p Pointer to frame802154_t struct, which specifies the
* frame to send.
*
* \param buf Pointer to the buffer to use for the frame.
*
* \param buf_len The length of the buffer to use for the frame.
*
* \return The length of the frame header or 0 if there was
* insufficient space in the buffer for the frame headers.
*/
int
frame802154_create(frame802154_t *p, uint8_t *buf, int buf_len)
{
int c;
field_length_t flen;
uint8_t pos;
#if LLSEC802154_USES_EXPLICIT_KEYS
uint8_t key_id_mode;
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
field_len(p, &flen);
if(3 + flen.dest_pid_len + flen.dest_addr_len +
flen.src_pid_len + flen.src_addr_len + flen.aux_sec_len > buf_len) {
/* Too little space for headers. */
return 0;
}
/* OK, now we have field lengths. Time to actually construct */
/* the outgoing frame, and store it in buf */
buf[0] = (p->fcf.frame_type & 7) |
((p->fcf.security_enabled & 1) << 3) |
((p->fcf.frame_pending & 1) << 4) |
((p->fcf.ack_required & 1) << 5) |
((p->fcf.panid_compression & 1) << 6);
buf[1] = ((p->fcf.dest_addr_mode & 3) << 2) |
((p->fcf.frame_version & 3) << 4) |
((p->fcf.src_addr_mode & 3) << 6);
/* sequence number */
buf[2] = p->seq;
pos = 3;
/* Destination PAN ID */
if(flen.dest_pid_len == 2) {
buf[pos++] = p->dest_pid & 0xff;
buf[pos++] = (p->dest_pid >> 8) & 0xff;
}
/* Destination address */
for(c = flen.dest_addr_len; c > 0; c--) {
buf[pos++] = p->dest_addr[c - 1];
}
/* Source PAN ID */
if(flen.src_pid_len == 2) {
buf[pos++] = p->src_pid & 0xff;
buf[pos++] = (p->src_pid >> 8) & 0xff;
}
/* Source address */
for(c = flen.src_addr_len; c > 0; c--) {
buf[pos++] = p->src_addr[c - 1];
}
#if LLSEC802154_SECURITY_LEVEL
/* Aux header */
if(flen.aux_sec_len) {
buf[pos++] = p->aux_hdr.security_control.security_level
#if LLSEC802154_USES_EXPLICIT_KEYS
| (p->aux_hdr.security_control.key_id_mode << 3)
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
;
memcpy(buf + pos, p->aux_hdr.frame_counter.u8, 4);
pos += 4;
#if LLSEC802154_USES_EXPLICIT_KEYS
key_id_mode = p->aux_hdr.security_control.key_id_mode;
if(key_id_mode) {
c = (key_id_mode - 1) * 4;
memcpy(buf + pos, p->aux_hdr.key_source.u8, c);
pos += c;
buf[pos++] = p->aux_hdr.key_index;
}
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
}
#endif /* LLSEC802154_SECURITY_LEVEL */
return (int)pos;
}
/*----------------------------------------------------------------------------*/
/**
* \brief Parses an input frame. Scans the input frame to find each
* section, and stores the information of each section in a
* frame802154_t structure.
*
* \param data The input data from the radio chip.
* \param len The size of the input data
* \param pf The frame802154_t struct to store the parsed frame information.
*/
int
frame802154_parse(uint8_t *data, int len, frame802154_t *pf)
{
uint8_t *p;
frame802154_fcf_t fcf;
int c;
#if LLSEC802154_USES_EXPLICIT_KEYS
uint8_t key_id_mode;
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
if(len < 3) {
return 0;
}
p = data;
/* decode the FCF */
fcf.frame_type = p[0] & 7;
fcf.security_enabled = (p[0] >> 3) & 1;
fcf.frame_pending = (p[0] >> 4) & 1;
fcf.ack_required = (p[0] >> 5) & 1;
fcf.panid_compression = (p[0] >> 6) & 1;
fcf.dest_addr_mode = (p[1] >> 2) & 3;
fcf.frame_version = (p[1] >> 4) & 3;
fcf.src_addr_mode = (p[1] >> 6) & 3;
/* copy fcf and seqNum */
memcpy(&pf->fcf, &fcf, sizeof(frame802154_fcf_t));
pf->seq = p[2];
p += 3; /* Skip first three bytes */
/* Destination address, if any */
if(fcf.dest_addr_mode) {
/* Destination PAN */
pf->dest_pid = p[0] + (p[1] << 8);
p += 2;
/* Destination address */
/* l = addr_len(fcf.dest_addr_mode); */
/* for(c = 0; c < l; c++) { */
/* pf->dest_addr.u8[c] = p[l - c - 1]; */
/* } */
/* p += l; */
if(fcf.dest_addr_mode == FRAME802154_SHORTADDRMODE) {
linkaddr_copy((linkaddr_t *)&(pf->dest_addr), &linkaddr_null);
pf->dest_addr[0] = p[1];
pf->dest_addr[1] = p[0];
p += 2;
} else if(fcf.dest_addr_mode == FRAME802154_LONGADDRMODE) {
for(c = 0; c < 8; c++) {
pf->dest_addr[c] = p[7 - c];
}
p += 8;
}
} else {
linkaddr_copy((linkaddr_t *)&(pf->dest_addr), &linkaddr_null);
pf->dest_pid = 0;
}
/* Source address, if any */
if(fcf.src_addr_mode) {
/* Source PAN */
if(!fcf.panid_compression) {
pf->src_pid = p[0] + (p[1] << 8);
p += 2;
} else {
pf->src_pid = pf->dest_pid;
}
/* Source address */
/* l = addr_len(fcf.src_addr_mode); */
/* for(c = 0; c < l; c++) { */
/* pf->src_addr.u8[c] = p[l - c - 1]; */
/* } */
/* p += l; */
if(fcf.src_addr_mode == FRAME802154_SHORTADDRMODE) {
linkaddr_copy((linkaddr_t *)&(pf->src_addr), &linkaddr_null);
pf->src_addr[0] = p[1];
pf->src_addr[1] = p[0];
p += 2;
} else if(fcf.src_addr_mode == FRAME802154_LONGADDRMODE) {
for(c = 0; c < 8; c++) {
pf->src_addr[c] = p[7 - c];
}
p += 8;
}
} else {
linkaddr_copy((linkaddr_t *)&(pf->src_addr), &linkaddr_null);
pf->src_pid = 0;
}
#if LLSEC802154_SECURITY_LEVEL
if(fcf.security_enabled) {
pf->aux_hdr.security_control.security_level = p[0] & 7;
#if LLSEC802154_USES_EXPLICIT_KEYS
pf->aux_hdr.security_control.key_id_mode = (p[0] >> 3) & 3;
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
p += 1;
memcpy(pf->aux_hdr.frame_counter.u8, p, 4);
p += 4;
#if LLSEC802154_USES_EXPLICIT_KEYS
key_id_mode = pf->aux_hdr.security_control.key_id_mode;
if(key_id_mode) {
c = (key_id_mode - 1) * 4;
memcpy(pf->aux_hdr.key_source.u8, p, c);
p += c;
pf->aux_hdr.key_index = p[0];
p += 1;
}
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
}
#endif /* LLSEC802154_SECURITY_LEVEL */
/* header length */
c = p - data;
/* payload length */
pf->payload_len = (len - c);
/* payload */
pf->payload = p;
/* return header length if successful */
return c > len ? 0 : c;
}
/** \} */

View file

@ -1,199 +0,0 @@
/*
* Copyright (c) 2008, Swedish Institute of Computer Science
* All rights reserved.
*
* Additional fixes for AVR contributed 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
*
* Additional fixes for MSP430 contributed by:
* Joakim Eriksson
* Niclas Finne
* Nicolas Tsiftes
*
* 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.
*/
/**
* \addtogroup net
* @{
*/
/**
* \defgroup frame802154 802.15.4 frame creation and parsing
* @{
*/
/**
* \file
* \brief 802.15.4 frame creation and parsing functions
*
* This file converts to and from a structure to a packed 802.15.4
* frame.
*
*/
/* Includes */
#ifndef FRAME_802154_H
#define FRAME_802154_H
#include "contiki-conf.h"
#ifdef IEEE802154_CONF_PANID
#define IEEE802154_PANID IEEE802154_CONF_PANID
#else /* IEEE802154_CONF_PANID */
#define IEEE802154_PANID 0xABCD
#endif /* IEEE802154_CONF_PANID */
/* Macros & Defines */
/** \brief These are some definitions of values used in the FCF. See the 802.15.4 spec for details.
* \name FCF element values definitions
* @{
*/
#define FRAME802154_BEACONFRAME (0x00)
#define FRAME802154_DATAFRAME (0x01)
#define FRAME802154_ACKFRAME (0x02)
#define FRAME802154_CMDFRAME (0x03)
#define FRAME802154_BEACONREQ (0x07)
#define FRAME802154_IEEERESERVED (0x00)
#define FRAME802154_NOADDR (0x00) /**< Only valid for ACK or Beacon frames. */
#define FRAME802154_SHORTADDRMODE (0x02)
#define FRAME802154_LONGADDRMODE (0x03)
#define FRAME802154_NOBEACONS (0x0F)
#define FRAME802154_BROADCASTADDR (0xFFFF)
#define FRAME802154_BROADCASTPANDID (0xFFFF)
#define FRAME802154_IEEE802154_2003 (0x00)
#define FRAME802154_IEEE802154_2006 (0x01)
#define FRAME802154_SECURITY_LEVEL_NONE (0)
#define FRAME802154_SECURITY_LEVEL_MIC_32 (1)
#define FRAME802154_SECURITY_LEVEL_MIC_64 (2)
#define FRAME802154_SECURITY_LEVEL_MIC_128 (3)
#define FRAME802154_SECURITY_LEVEL_ENC (4)
#define FRAME802154_SECURITY_LEVEL_ENC_MIC_32 (5)
#define FRAME802154_SECURITY_LEVEL_ENC_MIC_64 (6)
#define FRAME802154_SECURITY_LEVEL_ENC_MIC_128 (7)
#define FRAME802154_IMPLICIT_KEY (0)
#define FRAME802154_1_BYTE_KEY_ID_MODE (1)
#define FRAME802154_5_BYTE_KEY_ID_MODE (2)
#define FRAME802154_9_BYTE_KEY_ID_MODE (3)
/**
* @brief The IEEE 802.15.4 frame has a number of constant/fixed fields that
* can be counted to make frame construction and max payload
* calculations easier.
*
* These include:
* 1. FCF - 2 bytes - Fixed
* 2. Sequence number - 1 byte - Fixed
* 3. Addressing fields - 4 - 20 bytes - Variable
* 4. Aux security header - 0 - 14 bytes - Variable
* 5. CRC - 2 bytes - Fixed
*/
/**
* \brief Defines the bitfields of the frame control field (FCF).
*/
typedef struct {
uint8_t frame_type; /**< 3 bit. Frame type field, see 802.15.4 */
uint8_t security_enabled; /**< 1 bit. True if security is used in this frame */
uint8_t frame_pending; /**< 1 bit. True if sender has more data to send */
uint8_t ack_required; /**< 1 bit. Is an ack frame required? */
uint8_t panid_compression; /**< 1 bit. Is this a compressed header? */
/* uint8_t reserved; */ /**< 3 bit. Unused bits */
uint8_t dest_addr_mode; /**< 2 bit. Destination address mode, see 802.15.4 */
uint8_t frame_version; /**< 2 bit. 802.15.4 frame version */
uint8_t src_addr_mode; /**< 2 bit. Source address mode, see 802.15.4 */
} frame802154_fcf_t;
/** \brief 802.15.4 security control bitfield. See section 7.6.2.2.1 in 802.15.4 specification */
typedef struct {
uint8_t security_level; /**< 3 bit. security level */
uint8_t key_id_mode; /**< 2 bit. Key identifier mode */
uint8_t reserved; /**< 3 bit. Reserved bits */
} frame802154_scf_t;
typedef union {
uint32_t u32;
uint16_t u16[2];
uint8_t u8[4];
} frame802154_frame_counter_t;
typedef union {
uint16_t u16[4];
uint8_t u8[8];
} frame802154_key_source_t;
/** \brief 802.15.4 Aux security header */
typedef struct {
frame802154_scf_t security_control; /**< Security control bitfield */
frame802154_frame_counter_t frame_counter; /**< Frame counter, used for security */
frame802154_key_source_t key_source; /**< Key Source subfield */
uint8_t key_index; /**< Key Index subfield */
} frame802154_aux_hdr_t;
/** \brief Parameters used by the frame802154_create() function. These
* parameters are used in the 802.15.4 frame header. See the 802.15.4
* specification for details.
*/
typedef struct {
/* The fields dest_addr and src_addr must come first to ensure they are aligned to the
* CPU word size. Needed as they are accessed directly as linkaddr_t*. Note we cannot use
* the type linkaddr_t directly here, as we always need 8 bytes, not LINKADDR_SIZE bytes. */
uint8_t dest_addr[8]; /**< Destination address */
uint8_t src_addr[8]; /**< Source address */
frame802154_fcf_t fcf; /**< Frame control field */
uint8_t seq; /**< Sequence number */
uint16_t dest_pid; /**< Destination PAN ID */
uint16_t src_pid; /**< Source PAN ID */
frame802154_aux_hdr_t aux_hdr; /**< Aux security header */
uint8_t *payload; /**< Pointer to 802.15.4 payload */
int payload_len; /**< Length of payload field */
} frame802154_t;
/* Prototypes */
int frame802154_hdrlen(frame802154_t *p);
int frame802154_create(frame802154_t *p, uint8_t *buf, int buf_len);
int frame802154_parse(uint8_t *data, int length, frame802154_t *pf);
/** @} */
#endif /* FRAME_802154_H */
/** @} */
/** @} */

View file

@ -1,300 +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
* MAC framer for IEEE 802.15.4
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include <net/l2_buf.h>
#include "contiki/mac/framer-802154.h"
#include "contiki/mac/frame802154.h"
#include "contiki/llsec/llsec802154.h"
#include "contiki/packetbuf.h"
#include "lib/random.h"
#include <string.h>
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_15_4_FRAMING
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
/** \brief The 16-bit identifier of the PAN on which the device is
* sending to. If this value is 0xffff, the device is not
* associated.
*/
static uint16_t mac_dst_pan_id = IEEE802154_PANID;
/** \brief The 16-bit identifier of the PAN on which the device is
* operating. If this value is 0xffff, the device is not
* associated.
*/
static uint16_t mac_src_pan_id = IEEE802154_PANID;
#ifdef FRAMER_802154_HANDLER
int FRAMER_802154_HANDLER(frame802154_t *frame);
#endif
/** \brief The sequence number (0x00 - 0xff) added to the transmitted
* data or MAC command frame. The default is a random value within
* the range.
*/
uint8_t
framer_802154_next_seqno(void)
{
static uint8_t mac_dsn;
static uint8_t initialized = 0;
if(!initialized) {
initialized = 1;
mac_dsn = random_rand() & 0xff;
}
/* Ensure that the sequence number 0 is not used as it would bypass the PACKETBUF_PARAM_MAC_SEQNO check. */
if(mac_dsn == 0) {
mac_dsn++;
}
return mac_dsn++;
}
/*---------------------------------------------------------------------------*/
uint16_t
framer_802154_get_pan_id(void)
{
return mac_src_pan_id;
}
/*---------------------------------------------------------------------------*/
void
framer_802154_set_pan_id(uint16_t pan)
{
mac_dst_pan_id = pan;
mac_src_pan_id = pan;
}
/*---------------------------------------------------------------------------*/
static int
is_broadcast_addr(uint8_t mode, uint8_t *addr)
{
int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8;
while(i-- > 0) {
if(addr[i] != 0xff) {
return 0;
}
}
return 1;
}
/*---------------------------------------------------------------------------*/
static int
create_frame(struct net_buf *buf, int do_create)
{
frame802154_t params;
int hdr_len;
/* init to zeros */
memset(&params, 0, sizeof(params));
/* Build the FCF. */
params.fcf.frame_type = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_TYPE);
params.fcf.frame_pending = packetbuf_attr(buf, PACKETBUF_ATTR_PENDING);
if(packetbuf_holds_broadcast(buf)) {
params.fcf.ack_required = 0;
} else {
params.fcf.ack_required = packetbuf_attr(buf, PACKETBUF_ATTR_MAC_ACK);
}
params.fcf.panid_compression = 0;
/* Insert IEEE 802.15.4 (2006) version bits. */
params.fcf.frame_version = FRAME802154_IEEE802154_2006;
#if LLSEC802154_SECURITY_LEVEL
if(packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL)) {
params.fcf.security_enabled = 1;
}
/* Setting security-related attributes */
params.aux_hdr.security_control.security_level = packetbuf_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL);
params.aux_hdr.frame_counter.u16[0] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1);
params.aux_hdr.frame_counter.u16[1] = packetbuf_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3);
#if LLSEC802154_USES_EXPLICIT_KEYS
params.aux_hdr.security_control.key_id_mode = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_ID_MODE);
params.aux_hdr.key_index = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_INDEX);
params.aux_hdr.key_source.u16[0] = packetbuf_attr(buf, PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
#endif /* LLSEC802154_SECURITY_LEVEL */
/* Increment and set the data sequence number. */
if(!do_create) {
/* Only length calculation - no sequence number is needed and
should not be consumed. */
} else if(packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO)) {
params.seq = packetbuf_attr(buf, PACKETBUF_ATTR_MAC_SEQNO);
} else {
params.seq = framer_802154_next_seqno();
packetbuf_set_attr(buf, PACKETBUF_ATTR_MAC_SEQNO, params.seq);
}
/* Complete the addressing fields. */
/**
\todo For phase 1 the addresses are all long. We'll need a mechanism
in the rime attributes to tell the mac to use long or short for phase 2.
*/
if(LINKADDR_SIZE == 2) {
/* Use short address mode if linkaddr size is short. */
params.fcf.src_addr_mode = FRAME802154_SHORTADDRMODE;
} else {
params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
}
params.dest_pid = mac_dst_pan_id;
if(packetbuf_holds_broadcast(buf)) {
/* Broadcast requires short address mode. */
params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
params.dest_addr[0] = 0xFF;
params.dest_addr[1] = 0xFF;
} else {
linkaddr_copy((linkaddr_t *)&params.dest_addr,
packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER));
/* Use short address mode if linkaddr size is small */
if(LINKADDR_SIZE == 2) {
params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
} else {
params.fcf.dest_addr_mode = FRAME802154_LONGADDRMODE;
}
}
/* Set the source PAN ID to the global variable. */
params.src_pid = mac_src_pan_id;
/*
* Set up the source address using only the long address mode for
* phase 1.
*/
linkaddr_copy((linkaddr_t *)&params.src_addr, &linkaddr_node_addr);
params.payload = packetbuf_dataptr(buf);
params.payload_len = packetbuf_datalen(buf);
hdr_len = frame802154_hdrlen(&params);
if(!do_create) {
/* Only calculate header length */
return hdr_len;
} else if(packetbuf_hdralloc(buf, hdr_len)) {
frame802154_create(&params, packetbuf_hdrptr(buf), hdr_len);
PRINTF("15.4-OUT: %2X ", params.fcf.frame_type);
PRINTLLADDR((const uip_lladdr_t *)params.dest_addr);
PRINTF(" %d %u (%u)\n", hdr_len, packetbuf_datalen(buf), packetbuf_totlen(buf));
return hdr_len;
} else {
PRINTF("15.4-OUT: too large header: %u\n", hdr_len);
return FRAMER_FAILED;
}
}
/*---------------------------------------------------------------------------*/
static int
hdr_length(struct net_buf *buf)
{
return create_frame(buf, 0);
}
/*---------------------------------------------------------------------------*/
static int
create(struct net_buf *buf)
{
return create_frame(buf, 1);
}
/*---------------------------------------------------------------------------*/
static int
parse(struct net_buf *buf)
{
frame802154_t frame;
int hdr_len;
hdr_len = frame802154_parse(packetbuf_dataptr(buf), packetbuf_datalen(buf), &frame);
if(hdr_len && packetbuf_hdrreduce(buf, hdr_len)) {
packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_TYPE, frame.fcf.frame_type);
if(frame.fcf.dest_addr_mode) {
if(frame.dest_pid != mac_src_pan_id &&
frame.dest_pid != FRAME802154_BROADCASTPANDID) {
/* Packet to another PAN */
PRINTF("15.4: for another pan %u (0x%x)\n", frame.dest_pid,
frame.dest_pid);
return FRAMER_FAILED;
}
if(!is_broadcast_addr(frame.fcf.dest_addr_mode, frame.dest_addr)) {
packetbuf_set_addr(buf, PACKETBUF_ADDR_RECEIVER, (linkaddr_t *)&frame.dest_addr);
}
}
packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER, (linkaddr_t *)&frame.src_addr);
packetbuf_set_attr(buf, PACKETBUF_ATTR_PENDING, frame.fcf.frame_pending);
/* packetbuf_set_attr(PACKETBUF_ATTR_RELIABLE, frame.fcf.ack_required);*/
packetbuf_set_attr(buf, PACKETBUF_ATTR_PACKET_ID, frame.seq);
#if LLSEC802154_SECURITY_LEVEL
if(frame.fcf.security_enabled) {
packetbuf_set_attr(buf, PACKETBUF_ATTR_SECURITY_LEVEL, frame.aux_hdr.security_control.security_level);
packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, frame.aux_hdr.frame_counter.u16[0]);
packetbuf_set_attr(buf, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, frame.aux_hdr.frame_counter.u16[1]);
#if LLSEC802154_USES_EXPLICIT_KEYS
packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_ID_MODE, frame.aux_hdr.security_control.key_id_mode);
packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_INDEX, frame.aux_hdr.key_index);
packetbuf_set_attr(buf, PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, frame.aux_hdr.key_source.u16[0]);
#endif /* LLSEC802154_USES_EXPLICIT_KEYS */
}
#endif /* LLSEC802154_SECURITY_LEVEL */
PRINTF("15.4-IN: %2X ", frame.fcf.frame_type);
PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_SENDER));
PRINTF(" ");
PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER));
PRINTF(" %d %u (%u)\n", hdr_len, packetbuf_datalen(buf), packetbuf_totlen(buf));
#ifdef FRAMER_802154_HANDLER
if(FRAMER_802154_HANDLER(&frame)) {
return FRAMER_FRAME_HANDLED;
}
#endif
return hdr_len;
}
return FRAMER_FAILED;
}
/*---------------------------------------------------------------------------*/
const struct framer framer_802154 = {
hdr_length,
create,
framer_canonical_create_and_secure,
parse
};
/*---------------------------------------------------------------------------*/

View file

@ -1,50 +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 MAC framer for IEEE 802.15.4
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#ifndef FRAMER_802154_H_
#define FRAMER_802154_H_
#include "contiki/mac/framer.h"
extern const struct framer framer_802154;
uint8_t framer_802154_next_seqno(void);
uint16_t framer_802154_get_pan_id(void);
void framer_802154_set_pan_id(uint16_t panid);
#endif /* FRAMER_802154_H_ */

View file

@ -1,99 +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
* MAC framer for nullmac
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include "contiki/mac/framer-nullmac.h"
#include "contiki/packetbuf.h"
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_15_4_FRAMING
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
struct nullmac_hdr {
linkaddr_t receiver;
linkaddr_t sender;
};
/*---------------------------------------------------------------------------*/
static int
hdr_length(struct net_buf *buf)
{
return sizeof(struct nullmac_hdr);
}
/*---------------------------------------------------------------------------*/
static int
create(struct net_buf *buf)
{
struct nullmac_hdr *hdr;
if(packetbuf_hdralloc(buf, sizeof(struct nullmac_hdr))) {
hdr = packetbuf_hdrptr(buf);
linkaddr_copy(&(hdr->sender), &linkaddr_node_addr);
linkaddr_copy(&(hdr->receiver), packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER));
return sizeof(struct nullmac_hdr);
}
PRINTF("PNULLMAC-UT: too large header: %u\n", sizeof(struct nullmac_hdr));
return FRAMER_FAILED;
}
/*---------------------------------------------------------------------------*/
static int
parse(struct net_buf *buf)
{
struct nullmac_hdr *hdr;
hdr = packetbuf_dataptr(buf);
if(packetbuf_hdrreduce(buf, sizeof(struct nullmac_hdr))) {
packetbuf_set_addr(buf, PACKETBUF_ADDR_SENDER, &(hdr->sender));
packetbuf_set_addr(buf, PACKETBUF_ADDR_RECEIVER, &(hdr->receiver));
PRINTF("PNULLMAC-IN: ");
PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_SENDER));
PRINTF(" ");
PRINTLLADDR((const uip_lladdr_t *)packetbuf_addr(buf, PACKETBUF_ADDR_RECEIVER));
PRINTF(" %u (%u)\n", packetbuf_datalen(buf), sizeof(struct nullmac_hdr));
return sizeof(struct nullmac_hdr);
}
return FRAMER_FAILED;
}
/*---------------------------------------------------------------------------*/
const struct framer framer_nullmac = {
hdr_length,
create,
framer_canonical_create_and_secure,
parse
};

View file

@ -1,46 +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
* MAC framer for nullmac
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#ifndef FRAMER_NULLMAC_H_
#define FRAMER_NULLMAC_H_
#include "contiki/mac/framer.h"
extern const struct framer framer_nullmac;
#endif /* FRAMER_NULLMAC_H_ */

View file

@ -1,50 +0,0 @@
/*
* Copyright (c) 2014, Fraunhofer Heinrich-Hertz-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.
*
*/
#include "contiki/mac/framer.h"
#include "contiki/packetbuf.h"
#include "contiki/netstack.h"
/*---------------------------------------------------------------------------*/
int
framer_canonical_create_and_secure(struct net_buf *buf)
{
int hdr_len;
hdr_len = NETSTACK_FRAMER.create(buf);
if(hdr_len >= 0) {
packetbuf_compact(buf);
if(!NETSTACK_LLSEC.on_frame_created()) {
return FRAMER_FAILED;
}
}
return hdr_len;
}
/*---------------------------------------------------------------------------*/

View file

@ -1,62 +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 MAC framer is responsible for constructing and parsing
* the header in MAC frames. At least the sender and receiver
* are required to be encoded in the MAC frame headers.
* \author
* Niclas Finne <nfi@sics.se>
* Joakim Eriksson <joakime@sics.se>
*/
#include <net/buf.h>
#ifndef FRAMER_H_
#define FRAMER_H_
#define FRAMER_FAILED -1
#define FRAMER_FRAME_HANDLED -2
struct framer {
int (* length)(struct net_buf *buf);
int (* create)(struct net_buf *buf);
/** Creates the frame and calls LLSEC.on_frame_created() */
int (* create_and_secure)(struct net_buf *buf);
int (* parse)(struct net_buf *buf);
};
int framer_canonical_create_and_secure(struct net_buf *buf);
#endif /* FRAMER_H_ */

View file

@ -1,420 +0,0 @@
/*
* Copyright (c) 2013-2015, Yanzi Networks AB.
* 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 MAC handler for IEEE 802.15.4
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#include <net/l2_buf.h>
#include "contiki/mac/framer-802154.h"
#include "contiki/mac/frame802154.h"
#include "contiki/mac/handler-802154.h"
#include "contiki/packetbuf.h"
#include "contiki/netstack.h"
#include "lib/random.h"
#include "sys/ctimer.h"
#include <string.h>
#include <stdio.h>
#ifdef CONFIG_NETWORK_IP_STACK_DEBUG_15_4_MAC
#define DEBUG 1
#endif
#include "contiki/ip/uip-debug.h"
#define CHANNEL_LOW 11
#define CHANNEL_HIGH 26
#if HANDLER_802154_CONF_STATS
handler_802154_stats_t handler_802154_stats;
#endif /* HANDLER_802154_CONF_STATS */
/* ----------------------------------------------------- */
/* variables for beacon req/resp - active scan */
/* ----------------------------------------------------- */
static int current_channel = 0;
static uint8_t chseqno = 0;
static int scan = 0; /* flag if scan is already active */
static struct ctimer scan_timer;
static struct ctimer beacon_send_timer;
static void handle_beacon(frame802154_t *frame);
static void handle_beacon_send_timer(struct net_buf *mbuf, void *p);
static int answer_beacon_requests;
static uint16_t panid;
static scan_callback_t callback;
static uint8_t beacon_payload[BEACON_PAYLOAD_BUFFER_SIZE] = { 0xfe, 0x00 };
static uint8_t beacon_payload_len = 1;
static int others_beacon_reply;
#ifndef DISABLE_NETSELECT_RANDOM_CHANNEL
#define DISABLE_NETSELECT_RANDOM_CHANNEL 0
#endif /* DISABLE_NETSELECT_RANDOM_CHANNEL */
#if (DISABLE_NETSELECT_RANDOM_CHANNEL == 0)
uint8_t channel_list[CHANNEL_HIGH - CHANNEL_LOW + 1];
uint8_t channel_index;
#endif /* (DISABLE_NETSELECT_RANDOM_CHANNEL == 0) */
/*---------------------------------------------------------------------------*/
/* the init function assumes that the framer 802.15.4 is active and
used */
void
handler_802154_join(uint16_t pid, int answer_beacons)
{
panid = pid;
framer_802154_set_pan_id(pid);
answer_beacon_requests = answer_beacons;
}
/*---------------------------------------------------------------------------*/
static void
end_scan(void)
{
scan = 0;
NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE,
RADIO_RX_MODE_ADDRESS_FILTER | RADIO_RX_MODE_AUTOACK);
if(callback) {
/* nothing more will be scanned now */
callback(0, NULL, CALLBACK_ACTION_SCAN_END);
}
}
/*---------------------------------------------------------------------------*/
static void
handle_beacon(frame802154_t *frame)
{
radio_value_t value;
PRINTF("Beacon received on channel: %d PanID: %x\n", current_channel, frame->src_pid);
if(answer_beacon_requests &&
(frame->payload_len == beacon_payload_len) &&
(memcmp(beacon_payload, frame->payload, beacon_payload_len) == 0)) {
others_beacon_reply++;
if(others_beacon_reply >= 3) {
/* Abort scheduled beacon transmit */
ctimer_stop(&beacon_send_timer);
}
}
/* scanned channel is already increased... */
if(callback) {
/* pick the channel from the RADIO if it have been changed since we started
the scan - e.g. if we get a beacon later */
NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, &value);
if(callback(value, frame, CALLBACK_ACTION_RX) == CALLBACK_STATUS_FINISHED) {
/* scan is over - application is satisfied */
end_scan();
}
}
}
/*---------------------------------------------------------------------------*/
static void
handle_beacon_send_timer(struct net_buf *buf, void *p)
{
struct net_buf *mbuf;
frame802154_t params;
uint8_t len;
mbuf = l2_buf_get_reserve(0);
if(!mbuf) {
return;
}
/* init to zeros */
memset(&params, 0, sizeof(params));
/* use packetbuf for sending ?? */
packetbuf_clear(mbuf);
/* Build the FCF. */
params.fcf.frame_type = FRAME802154_BEACONFRAME;
/* Insert IEEE 802.15.4 (2006) version bits. */
params.fcf.frame_version = FRAME802154_IEEE802154_2006;
/* assume long for now */
params.fcf.src_addr_mode = FRAME802154_LONGADDRMODE;
linkaddr_copy((linkaddr_t *)&params.src_addr, &linkaddr_node_addr);
/* Set the source PAN ID to the global variable. */
params.src_pid = panid;
params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
params.dest_addr[0] = 0xFF;
params.dest_addr[1] = 0xFF;
params.dest_pid = 0xffff;
params.seq = framer_802154_next_seqno();
/* Calculate beacon length and copy it to packetbuf */
beacon_payload_len = handler_802154_calculate_beacon_payload_length(beacon_payload, BEACON_PAYLOAD_BUFFER_SIZE);
packetbuf_copyfrom(mbuf, beacon_payload, beacon_payload_len);
/* Set payload and payload length */
params.payload = packetbuf_dataptr(mbuf);
params.payload_len = packetbuf_datalen(mbuf);
len = frame802154_hdrlen(&params);
if(packetbuf_hdralloc(mbuf, len)) {
frame802154_create(&params, packetbuf_hdrptr(mbuf), len);
if(NETSTACK_RADIO.send(mbuf, packetbuf_hdrptr(mbuf),
packetbuf_totlen(mbuf)) != RADIO_TX_OK) {
l2_buf_unref(mbuf);
return;
}
HANDLER_802154_STAT(handler_802154_stats.beacons_sent++);
}
}
/*---------------------------------------------------------------------------*/
/* called to send a beacon request */
void
handler_802154_send_beacon_request(void)
{
struct net_buf *mbuf;
frame802154_t params;
uint8_t len;
mbuf = l2_buf_get_reserve(0);
if(!mbuf) {
return;
}
/* init to zeros */
memset(&params, 0, sizeof(params));
/* use packetbuf for sending ?? */
packetbuf_clear(mbuf);
/* Build the FCF. */
params.fcf.frame_type = FRAME802154_CMDFRAME;
/* Insert IEEE 802.15.4 (2006) version bits. */
params.fcf.frame_version = FRAME802154_IEEE802154_2006;
params.fcf.src_addr_mode = FRAME802154_NOADDR;
params.fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE;
params.dest_addr[0] = 0xFF;
params.dest_addr[1] = 0xFF;
params.dest_pid = 0xffff;
params.seq = chseqno;
packetbuf_set_datalen(mbuf, 1);
params.payload = packetbuf_dataptr(mbuf);
/* set the type in the payload */
params.payload[0] = FRAME802154_BEACONREQ;
params.payload_len = packetbuf_datalen(mbuf);
len = frame802154_hdrlen(&params);
if(packetbuf_hdralloc(mbuf, len)) {
frame802154_create(&params, packetbuf_hdrptr(mbuf), len);
if(NETSTACK_RADIO.send(mbuf, packetbuf_hdrptr(mbuf),
packetbuf_totlen(mbuf)) != RADIO_TX_OK) {
l2_buf_unref(mbuf);
return;
}
HANDLER_802154_STAT(handler_802154_stats.beacons_reqs_sent++);
}
}
/*---------------------------------------------------------------------------*/
static void
handle_scan_timer(struct net_buf *mbuf, void *p)
{
if(!scan) {
return;
}
if(scan > 1) {
int callback_status;
callback_status = callback(current_channel, NULL, CALLBACK_ACTION_CHANNEL_DONE);
if(callback_status == CALLBACK_STATUS_FINISHED) {
end_scan();
return;
} else if(callback_status == CALLBACK_STATUS_NEED_MORE_TIME) {
ctimer_reset(&scan_timer);
return;
}
}
scan++;
#if DISABLE_NETSELECT_RANDOM_CHANNEL
if(current_channel == 26) {
/* Last channel has been scanned. Report that the process is over. */
end_scan();
return;
}
if(current_channel == 0) {
current_channel = 11;
} else {
current_channel++;
}
#else /* DISABLE_NETSELECT_RANDOM_CHANNEL */
if(channel_index > (CHANNEL_HIGH - CHANNEL_LOW)) {
/* Last channel has been scanned. Report that the process is over. */
end_scan();
return;
}
if(current_channel == 0) {
/* new scan, randomize channels */
int i;
int j;
channel_index = 0;
/* Initialize a random list as shown by Durstenfelds' FisherYates shuffle. */
for(i = 0; i <= (CHANNEL_HIGH - CHANNEL_LOW); i++) {
j = random_rand() % (i + 1);
if(j != i) {
channel_list[i] = channel_list[j];
}
channel_list[j] = i + CHANNEL_LOW;
}
#if DEBUG
PRINTF("New netselect search: channel order: ");
for(i = 0; i <= (CHANNEL_HIGH - CHANNEL_LOW); i++) {
PRINTF("%d ", channel_list[i]);
}
PRINTF("\n");
#endif
}
current_channel = channel_list[channel_index++];
#endif /* DISABLE_NETSELECT_RANDOM_CHANNEL */
NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, 0);
NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, current_channel);
handler_802154_send_beacon_request();
ctimer_reset(&scan_timer);
}
/*---------------------------------------------------------------------------*/
/*
* active scan - will scan all 16 channels in the 802.15.4 network
* NOTE: this assumes 16 channels, starting from 11. Needs to be changed
* if running on other than 2.4 GHz
*/
int
handler_802154_active_scan(scan_callback_t cb)
{
/* if no scan is active - start one */
if(!scan) {
callback = cb;
current_channel = 0;
#if (DISABLE_NETSELECT_RANDOM_CHANNEL == 0)
channel_index = 0;
#endif /* (DISABLE_NETSELECT_RANDOM_CHANNEL == 0) */
scan = 1;
chseqno = framer_802154_next_seqno();
NETSTACK_RADIO.set_value(RADIO_PARAM_RX_MODE, 0);
ctimer_set(NULL, &scan_timer, (CLOCK_SECOND * 6) / 10, &handle_scan_timer, callback);
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
int
handler_802154_frame_received(frame802154_t *frame)
{
if(answer_beacon_requests &&
frame->fcf.frame_type == FRAME802154_CMDFRAME &&
frame->payload[0] == FRAME802154_BEACONREQ) {
others_beacon_reply = 0;
ctimer_set(NULL, &beacon_send_timer,
CLOCK_SECOND / 16 +
(CLOCK_SECOND * (random_rand() & 0xff)) / 0x200,
&handle_beacon_send_timer, NULL);
return 1;
}
if(frame->fcf.frame_type == FRAME802154_BEACONFRAME) {
HANDLER_802154_STAT(handler_802154_stats.beacons_received++);
handle_beacon(frame);
return 1;
}
return 0;
}
/*---------------------------------------------------------------------------*/
/*
* Calculate beacon payload length.
* Return length or -1 on error.
*/
int
handler_802154_calculate_beacon_payload_length(uint8_t *beacon, int maxlen)
{
int i;
if(beacon[0] != 0xfe) {
return -1;
}
for(i = 1; beacon[i] != 0; i += beacon[i]) {
if(i >= maxlen) {
return -1;
}
}
i++; /* include the last 0-length indicator */
return i;
}
/*---------------------------------------------------------------------------*/
void
handler_802154_set_answer_beacons(int answer)
{
answer_beacon_requests = answer;
}
/*---------------------------------------------------------------------------*/
void
handler_802154_set_beacon_payload(uint8_t *payload, uint8_t len)
{
if(len <= BEACON_PAYLOAD_BUFFER_SIZE) {
beacon_payload_len = 1;
memset(beacon_payload, 0, BEACON_PAYLOAD_BUFFER_SIZE);
memcpy(beacon_payload, payload, len);
beacon_payload_len = len;
}
}
/*---------------------------------------------------------------------------*/
/*
* Write current beacon payload length to "len", if non-NULL.
*
* Return pointer to beacon payload buffer.
*/
uint8_t *
handler_802154_get_beacon_payload(uint8_t *len)
{
if(len) {
*len = beacon_payload_len;
}
return beacon_payload;
}
/*---------------------------------------------------------------------------*/

View file

@ -1,86 +0,0 @@
/*
* Copyright (c) 2013-2015, Yanzi Networks AB.
* 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 MAC handler for IEEE 802.15.4
* \author
* Joakim Eriksson <joakime@sics.se>
* Niclas Finne <nfi@sics.se>
*/
#ifndef HANDLER_802154_H_
#define HANDLER_802154_H_
#include "contiki/mac/frame802154.h"
#define BEACON_PAYLOAD_BUFFER_SIZE 128
typedef enum {
CALLBACK_ACTION_RX,
CALLBACK_ACTION_CHANNEL_DONE,
CALLBACK_ACTION_SCAN_END,
} callback_action;
#define CALLBACK_STATUS_CONTINUE 0
#define CALLBACK_STATUS_NEED_MORE_TIME 1
#define CALLBACK_STATUS_FINISHED 2
typedef int (* scan_callback_t)(uint8_t channel, frame802154_t *frame, callback_action cba);
void handler_802154_join(uint16_t panid, int answer_beacons);
int handler_802154_active_scan(scan_callback_t callback);
int handler_802154_calculate_beacon_payload_length(uint8_t *beacon, int maxlen);
void handler_802154_set_beacon_payload(uint8_t *payload, uint8_t len);
uint8_t *handler_802154_get_beacon_payload(uint8_t *len);
void handler_802154_send_beacon_request(void);
void handler_802154_set_answer_beacons(int answer);
#ifndef HANDLER_802154_CONF_STATS
#define HANDLER_802154_CONF_STATS 0
#endif
#if HANDLER_802154_CONF_STATS
/* Statistics for fault management. */
typedef struct handler_802154_stats {
uint16_t beacons_reqs_sent;
uint16_t beacons_sent;
uint16_t beacons_received;
} handler_802154_stats_t;
extern handler_802154_stats_t handler_802154_stats;
#define HANDLER_802154_STAT(code) (code)
#else /* HANDLER_802154_CONF_STATS */
#define HANDLER_802154_STAT(code)
#endif /* HANDLER_802154_CONF_STATS */
#endif /* HANDLER_802154_H_ */

Some files were not shown because too many files have changed in this diff Show more