Merge pull request #714 from simonduq/contrib/uip-cleanup
Safer uIP6 buffer handling
This commit is contained in:
commit
2b0c2d5e4a
|
@ -51,7 +51,7 @@ uint16_t
|
|||
uip_ipchksum(void)
|
||||
{
|
||||
/* Assumes proper alignement of uip_buf. */
|
||||
uint16_t *p = (uint16_t *)&uip_buf[UIP_LLH_LEN];
|
||||
uint16_t *p = (uint16_t *)UIP_IP_BUF;
|
||||
register uint16_t sum;
|
||||
|
||||
sum = p[0];
|
||||
|
|
|
@ -263,7 +263,7 @@ output(const linkaddr_t *localdest)
|
|||
{
|
||||
LOG_DBG("SUT: %u\n", uip_len);
|
||||
if(uip_len > 0) {
|
||||
return tun_output(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
return tun_output(uip_buf, uip_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -297,7 +297,7 @@ handle_fd(fd_set *rset, fd_set *wset)
|
|||
LOG_INFO("Tun6-handle FD\n");
|
||||
|
||||
if(FD_ISSET(tunfd, rset)) {
|
||||
size = tun_input(&uip_buf[UIP_LLH_LEN], sizeof(uip_buf));
|
||||
size = tun_input(uip_buf, sizeof(uip_buf));
|
||||
LOG_DBG("TUN data incoming read:%d\n", size);
|
||||
uip_len = size;
|
||||
tcpip_input();
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
static uint8_t
|
||||
uip_driver_send(const linkaddr_t *addr)
|
||||
{
|
||||
packetbuf_copyfrom(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
packetbuf_copyfrom(uip_buf, uip_len);
|
||||
|
||||
/* XXX we should provide a callback function that is called when the
|
||||
packet is sent. For now, we just supply a NULL pointer. */
|
||||
|
@ -64,9 +64,8 @@ init(void)
|
|||
static void
|
||||
input(void)
|
||||
{
|
||||
if(packetbuf_datalen() > 0 &&
|
||||
packetbuf_datalen() <= UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], packetbuf_dataptr(), packetbuf_datalen());
|
||||
if(packetbuf_datalen() > 0 && packetbuf_datalen() <= UIP_BUFSIZE) {
|
||||
memcpy(uip_buf, packetbuf_dataptr(), packetbuf_datalen());
|
||||
uip_len = packetbuf_datalen();
|
||||
tcpip_input();
|
||||
}
|
||||
|
|
|
@ -46,7 +46,6 @@
|
|||
|
||||
#include <MicroInt.h>
|
||||
#include "net/ipv6/uip.h"
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#include "dev/slip.h"
|
||||
|
||||
|
@ -117,7 +116,7 @@ unsigned long slip_received, slip_frames;
|
|||
#ifdef SLIP_CONF_RX_BUFSIZE
|
||||
#define RX_BUFSIZE SLIP_CONF_RX_BUFSIZE
|
||||
|
||||
#if RX_BUFSIZE < (UIP_BUFSIZE - UIP_LLH_LEN + 16)
|
||||
#if RX_BUFSIZE < (UIP_BUFSIZE + 16)
|
||||
#error "SLIP_CONF_RX_BUFSIZE too small for UIP_BUFSIZE"
|
||||
#endif
|
||||
|
||||
|
@ -195,7 +194,7 @@ slip_send(void)
|
|||
|
||||
slip_arch_writeb(SLIP_END);
|
||||
|
||||
ptr = &uip_buf[UIP_LLH_LEN];
|
||||
ptr = uip_buf;
|
||||
for(i = 0; i < uip_len; ++i) {
|
||||
c = *ptr++;
|
||||
slip_write_char(c);
|
||||
|
@ -317,8 +316,7 @@ PROCESS_THREAD(slip_process, ev, data)
|
|||
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
|
||||
|
||||
/* Move packet from rxbuf to buffer provided by uIP. */
|
||||
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
||||
UIP_BUFSIZE - UIP_LLH_LEN);
|
||||
uip_len = slip_poll_handler(uip_buf, UIP_BUFSIZE);
|
||||
|
||||
PRINTF("SLIP: recv bytes %u frames RECV: %u. is_full %u, is_dropping %u.\n",
|
||||
end_counter, uip_len, is_full, is_dropping);
|
||||
|
|
|
@ -10,8 +10,6 @@
|
|||
#define LOG_MODULE "App"
|
||||
#define LOG_LEVEL LOG_LEVEL_INFO
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS(ipv6_hooks_process, "IPv6 Hooks");
|
||||
AUTOSTART_PROCESSES(&ipv6_hooks_process);
|
||||
|
|
|
@ -55,8 +55,6 @@
|
|||
static struct uip_udp_conn *sink_conn;
|
||||
static uint16_t count;
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#if !NETSTACK_CONF_WITH_IPV6 || !UIP_CONF_ROUTER || !UIP_IPV6_MULTICAST || !UIP_CONF_IPV6_RPL
|
||||
#error "This example can not work with the current contiki configuration"
|
||||
#error "Check the values of: NETSTACK_CONF_WITH_IPV6, UIP_CONF_ROUTER, UIP_CONF_IPV6_RPL"
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#define REST_MAX_CHUNK_SIZE 256
|
||||
|
||||
/* Network config */
|
||||
//#define UIP_CONF_BUFFER_SIZE (REST_MAX_CHUNK_SIZE + UIP_LLH_LEN + UIP_IPUDPH_LEN + COAP_MAX_HEADER_SIZE)
|
||||
//#define UIP_CONF_BUFFER_SIZE (REST_MAX_CHUNK_SIZE + UIP_IPUDPH_LEN + COAP_MAX_HEADER_SIZE)
|
||||
//#define UIP_CONF_BUFFER_SIZE (REST_MAX_CHUNK_SIZE + 0 + 48 + 70)
|
||||
#define UIP_CONF_BUFFER_SIZE 1280 /* ipv6 required minimum */
|
||||
|
||||
|
|
|
@ -50,8 +50,6 @@
|
|||
#define DEBUG DEBUG_PRINT
|
||||
#include "net/ipv6/uip-debug.h"
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#define INTERVAL (10)
|
||||
#define BLINK_TIME (CLOCK_SECOND/4)
|
||||
|
||||
|
|
|
@ -97,7 +97,6 @@ PROCESS_THREAD(er_example_server, ev, data)
|
|||
PRINTF("Starting Erbium Example Server\n");
|
||||
|
||||
PRINTF("uIP buffer: %u\n", UIP_BUFSIZE);
|
||||
PRINTF("LL header: %u\n", UIP_LLH_LEN);
|
||||
PRINTF("IP+UDP header: %u\n", UIP_IPUDPH_LEN);
|
||||
PRINTF("REST max chunk: %u\n", COAP_MAX_CHUNK_SIZE);
|
||||
|
||||
|
|
|
@ -226,12 +226,11 @@ slip_radio_cmd_handler(const uint8_t *data, int len)
|
|||
static void
|
||||
slip_input_callback(void)
|
||||
{
|
||||
LOG_DBG("SR-SIN: %u '%c%c'\n", uip_len,
|
||||
uip_buf[UIP_LLH_LEN], uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(!cmd_input(&uip_buf[UIP_LLH_LEN], uip_len)) {
|
||||
LOG_DBG("SR-SIN: %u '%c%c'\n", uip_len, uip_buf[0], uip_buf[1]);
|
||||
if(!cmd_input(uip_buf, uip_len)) {
|
||||
cmd_send((uint8_t *)"EUnknown command", 16);
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
|
|
|
@ -44,10 +44,8 @@
|
|||
#include "net/ipv6/uip-nameserver.h"
|
||||
#include "net/routing/routing.h"
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#include "net/ipv6/uip-icmp6.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
#include "net/ipv6/resolv.h"
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ static uint16_t slip_rubbish, slip_twopackets, slip_overflow, slip_ip_drop;
|
|||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Must be at least one byte larger than UIP_BUFSIZE! */
|
||||
#define RX_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN + 16)
|
||||
#define RX_BUFSIZE (UIP_BUFSIZE + 16)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
enum {
|
||||
STATE_TWOPACKETS = 0, /* We have 2 packets and drop incoming data. */
|
||||
|
@ -87,7 +87,7 @@ slip_set_input_callback(void (*c)(void))
|
|||
void
|
||||
slip_send(void)
|
||||
{
|
||||
slip_write(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
slip_write(uip_buf, uip_len);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -252,8 +252,7 @@ PROCESS_THREAD(slip_process, ev, data)
|
|||
slip_active = 1;
|
||||
|
||||
/* Move packet from rxbuf to buffer provided by uIP. */
|
||||
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
||||
UIP_BUFSIZE - UIP_LLH_LEN);
|
||||
uip_len = slip_poll_handler(uip_buf, UIP_BUFSIZE);
|
||||
|
||||
if(uip_len > 0) {
|
||||
if(input_callback) {
|
||||
|
|
|
@ -70,21 +70,13 @@
|
|||
#endif /* WITH_DTLS */
|
||||
|
||||
/* sanity check for configured values */
|
||||
#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPH_LEN - UIP_UDPH_LEN)
|
||||
#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_IPH_LEN - UIP_UDPH_LEN)
|
||||
#error "UIP_CONF_BUFFER_SIZE too small for COAP_MAX_CHUNK_SIZE"
|
||||
#endif
|
||||
|
||||
#define SERVER_LISTEN_PORT UIP_HTONS(COAP_DEFAULT_PORT)
|
||||
#define SERVER_LISTEN_SECURE_PORT UIP_HTONS(COAP_DEFAULT_SECURE_PORT)
|
||||
|
||||
/* direct access into the buffer */
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#else
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DTLS
|
||||
static dtls_handler_t cb;
|
||||
static dtls_context_t *dtls_context = NULL;
|
||||
|
|
|
@ -103,26 +103,18 @@ static struct uip_udp_conn *c;
|
|||
static uip_ipaddr_t src_ip;
|
||||
static uip_ipaddr_t des_ip;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* uIPv6 Pointers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Local function prototypes */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void icmp_input(void);
|
||||
static void icmp_output(void);
|
||||
static void mcast_fwd(void *p);
|
||||
int remove_ext_hdr(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Internal Data Structures */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
struct multicast_on_behalf{ /* ICMP message of multicast_on_behalf */
|
||||
uint16_t mcast_port;
|
||||
uip_ipaddr_t mcast_ip;
|
||||
uint8_t mcast_payload[UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN];
|
||||
uint8_t mcast_payload[UIP_BUFSIZE - UIP_IPUDPH_LEN];
|
||||
};
|
||||
#define UIP_ICMP_MOB 18 /* Size of multicast_on_behalf ICMP header */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -143,7 +135,7 @@ icmp_output()
|
|||
|
||||
struct multicast_on_behalf *mob;
|
||||
mob = (struct multicast_on_behalf *)UIP_ICMP_PAYLOAD;
|
||||
memcpy(&mob->mcast_payload, &uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], uip_slen);
|
||||
memcpy(&mob->mcast_payload, &uip_buf[UIP_IPUDPH_LEN], uip_slen);
|
||||
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
UIP_IP_BUF->tcflow = 0;
|
||||
|
@ -164,8 +156,7 @@ icmp_output()
|
|||
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
PRINTF("\n");
|
||||
|
||||
UIP_IP_BUF->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8;
|
||||
UIP_IP_BUF->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + payload_len);
|
||||
|
||||
UIP_ICMP_BUF->type = ICMP6_ESMRF;
|
||||
UIP_ICMP_BUF->icode = ESMRF_ICMP_CODE;
|
||||
|
@ -199,7 +190,7 @@ icmp_input()
|
|||
}
|
||||
#endif
|
||||
|
||||
remove_ext_hdr();
|
||||
uip_remove_ext_hdr();
|
||||
|
||||
PRINTF("ESMRF: ICMPv6 In from ");
|
||||
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
|
@ -210,11 +201,11 @@ icmp_input()
|
|||
VERBOSE_PRINTF("ESMRF: ICMPv6 In, parse from %p to %p\n",
|
||||
UIP_ICMP_PAYLOAD,
|
||||
(uint8_t *)UIP_ICMP_PAYLOAD + uip_len -
|
||||
uip_l2_l3_icmp_hdr_len);
|
||||
uip_l3_icmp_hdr_len);
|
||||
|
||||
|
||||
locmobptr = (struct multicast_on_behalf *) UIP_ICMP_PAYLOAD;
|
||||
loclen = uip_len - (uip_l2_l3_icmp_hdr_len + UIP_ICMP_MOB);
|
||||
loclen = uip_len - (uip_l3_icmp_hdr_len + UIP_ICMP_MOB);
|
||||
|
||||
uip_ipaddr_copy(&src_ip, &UIP_IP_BUF->srcipaddr);
|
||||
uip_ipaddr_copy(&des_ip, &UIP_IP_BUF->destipaddr);
|
||||
|
@ -224,13 +215,13 @@ icmp_input()
|
|||
c->rport = locmobptr->mcast_port;
|
||||
uip_slen = loclen;
|
||||
uip_udp_conn=c;
|
||||
memcpy(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], locmobptr->mcast_payload,
|
||||
loclen > UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN?
|
||||
UIP_BUFSIZE - UIP_LLH_LEN - UIP_IPUDPH_LEN: loclen);
|
||||
memcpy(&uip_buf[UIP_IPUDPH_LEN], locmobptr->mcast_payload,
|
||||
loclen > UIP_BUFSIZE - UIP_IPUDPH_LEN?
|
||||
UIP_BUFSIZE - UIP_IPUDPH_LEN: loclen);
|
||||
|
||||
uip_process(UIP_UDP_SEND_CONN);
|
||||
|
||||
memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len);
|
||||
memcpy(&mcast_buf, uip_buf, uip_len);
|
||||
mcast_len = uip_len;
|
||||
/* pass the packet to our uip_process to check if it is allowed to
|
||||
* accept this packet or not */
|
||||
|
@ -240,7 +231,7 @@ icmp_input()
|
|||
|
||||
uip_process(UIP_DATA);
|
||||
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len);
|
||||
memcpy(uip_buf, &mcast_buf, mcast_len);
|
||||
uip_len = mcast_len;
|
||||
/* Return the IP of the original Multicast sender */
|
||||
uip_ipaddr_copy(&UIP_IP_BUF->srcipaddr, &src_ip);
|
||||
|
@ -252,17 +243,17 @@ icmp_input()
|
|||
/* If we enter here, we will definitely forward */
|
||||
tcpip_ipv6_output();
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
mcast_fwd(void *p)
|
||||
{
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len);
|
||||
memcpy(uip_buf, &mcast_buf, mcast_len);
|
||||
uip_len = mcast_len;
|
||||
UIP_IP_BUF->ttl--;
|
||||
tcpip_output(NULL);
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
|
@ -352,7 +343,7 @@ in()
|
|||
fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread));
|
||||
}
|
||||
|
||||
memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len);
|
||||
memcpy(&mcast_buf, uip_buf, uip_len);
|
||||
mcast_len = uip_len;
|
||||
ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL);
|
||||
}
|
||||
|
|
|
@ -276,7 +276,7 @@ struct mcast_packet {
|
|||
uint16_t seq_val; /* host-byte order */
|
||||
struct sliding_window *sw; /* Pointer to the SW this packet belongs to */
|
||||
uint8_t flags; /* Is-Used, Must Send, Is Listed */
|
||||
uint8_t buff[UIP_BUFSIZE - UIP_LLH_LEN];
|
||||
uint8_t buff[UIP_BUFSIZE];
|
||||
};
|
||||
|
||||
/* Flag bits */
|
||||
|
@ -289,7 +289,7 @@ struct mcast_packet {
|
|||
#define MCAST_PACKET_GET_SEED(p) ((seed_id_t *)&((p)->seed_id))
|
||||
#else
|
||||
#define MCAST_PACKET_GET_SEED(p) \
|
||||
((seed_id_t *)&((struct uip_ip_hdr *)&(p)->buff[UIP_LLH_LEN])->srcipaddr)
|
||||
((seed_id_t *)&((struct uip_ip_hdr *)&(p)->buff[0])->srcipaddr)
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@ -456,14 +456,9 @@ static uint16_t last_seq;
|
|||
/*---------------------------------------------------------------------------*/
|
||||
/* uIPv6 Pointers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_DATA_BUF ((uint8_t *)&uip_buf[uip_l2_l3_hdr_len + UIP_UDPH_LEN])
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#define UIP_EXT_BUF_NEXT ((uint8_t *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + HBHO_TOTAL_LEN])
|
||||
#define UIP_EXT_OPT_FIRST ((struct hbho_mcast *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + 2])
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)UIP_IP_PAYLOAD(0))
|
||||
#define UIP_EXT_BUF_NEXT ((uint8_t *)(UIP_IP_PAYLOAD(HBHO_TOTAL_LEN)))
|
||||
#define UIP_EXT_OPT_FIRST ((struct hbho_mcast *)(UIP_IP_PAYLOAD(0) + 2))
|
||||
extern uint16_t uip_slen;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Local function prototypes */
|
||||
|
@ -864,8 +859,7 @@ icmp_output()
|
|||
roll_tm_create_dest(&UIP_IP_BUF->destipaddr);
|
||||
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
|
||||
|
||||
UIP_IP_BUF->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8;
|
||||
UIP_IP_BUF->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + payload_len);
|
||||
|
||||
UIP_ICMP_BUF->type = ICMP6_ROLL_TM;
|
||||
UIP_ICMP_BUF->icode = ROLL_TM_ICMP_CODE;
|
||||
|
@ -1153,10 +1147,10 @@ icmp_input()
|
|||
VERBOSE_PRINTF("ROLL TM: ICMPv6 In, parse from %p to %p\n",
|
||||
UIP_ICMP_PAYLOAD,
|
||||
(uint8_t *)UIP_ICMP_PAYLOAD + uip_len -
|
||||
uip_l2_l3_icmp_hdr_len);
|
||||
uip_l3_icmp_hdr_len);
|
||||
while(locslhptr <
|
||||
(struct sequence_list_header *)((uint8_t *)UIP_ICMP_PAYLOAD +
|
||||
uip_len - uip_l2_l3_icmp_hdr_len)) {
|
||||
uip_len - uip_l3_icmp_hdr_len)) {
|
||||
VERBOSE_PRINTF("ROLL TM: ICMPv6 In, seq hdr @ %p\n", locslhptr);
|
||||
|
||||
if((locslhptr->flags & SEQUENCE_LIST_RES) != 0) {
|
||||
|
@ -1321,7 +1315,7 @@ static void
|
|||
out()
|
||||
{
|
||||
|
||||
if(uip_len + HBHO_TOTAL_LEN > UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
if(uip_len + HBHO_TOTAL_LEN > UIP_BUFSIZE) {
|
||||
PRINTF("ROLL TM: Multicast Out can not add HBHO. Packet too long\n");
|
||||
goto drop;
|
||||
}
|
||||
|
@ -1355,13 +1349,11 @@ out()
|
|||
HBH_SET_M(lochbhmptr);
|
||||
#endif
|
||||
|
||||
uip_ext_len += HBHO_TOTAL_LEN;
|
||||
uip_len += HBHO_TOTAL_LEN;
|
||||
uipbuf_add_ext_hdr(HBHO_TOTAL_LEN);
|
||||
|
||||
/* Update the proto and length field in the v6 header */
|
||||
UIP_IP_BUF->proto = UIP_PROTO_HBHO;
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
PRINTF("ROLL TM: Multicast Out, HBHO: T=%u, L=%u, M=%u, S=0x%02x%02x\n",
|
||||
lochbhmptr->type, lochbhmptr->len, HBH_GET_M(lochbhmptr),
|
||||
|
@ -1383,7 +1375,7 @@ out()
|
|||
|
||||
drop:
|
||||
uip_slen = 0;
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
|
|
|
@ -77,18 +77,14 @@ static uip_buf_t mcast_buf;
|
|||
static uint8_t fwd_delay;
|
||||
static uint8_t fwd_spread;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* uIPv6 Pointers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
mcast_fwd(void *p)
|
||||
{
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], &mcast_buf, mcast_len);
|
||||
memcpy(uip_buf, &mcast_buf, mcast_len);
|
||||
uip_len = mcast_len;
|
||||
UIP_IP_BUF->ttl--;
|
||||
tcpip_output(NULL);
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t
|
||||
|
@ -178,7 +174,7 @@ in()
|
|||
fwd_delay = fwd_delay * (1 + ((random_rand() >> 11) % fwd_spread));
|
||||
}
|
||||
|
||||
memcpy(&mcast_buf, &uip_buf[UIP_LLH_LEN], uip_len);
|
||||
memcpy(&mcast_buf, uip_buf, uip_len);
|
||||
mcast_len = uip_len;
|
||||
ctimer_set(&mcast_periodic, fwd_delay, mcast_fwd, NULL);
|
||||
}
|
||||
|
|
|
@ -116,8 +116,6 @@ int strcasecmp(const char *s1, const char *s2);
|
|||
int strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
#endif /* __SDCC */
|
||||
|
||||
#define UIP_UDP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
/* If RESOLV_CONF_SUPPORTS_MDNS is set, then queries
|
||||
* for domain names in the local TLD will use mDNS as
|
||||
* described by draft-cheshire-dnsext-multicastdns.
|
||||
|
@ -837,7 +835,7 @@ newdata(void)
|
|||
} else {
|
||||
uip_udp_packet_sendto(resolv_conn, uip_appdata,
|
||||
mdns_prep_host_announce_packet(),
|
||||
&UIP_UDP_BUF->srcipaddr,
|
||||
&UIP_IP_BUF->srcipaddr,
|
||||
UIP_UDP_BUF->srcport);
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -121,12 +121,8 @@
|
|||
#define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN])
|
||||
#define SICSLOWPAN_IPPAYLOAD_BUF(buf) (&buf[UIP_IPH_LEN])
|
||||
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_UDP_BUF(p) ((struct uip_udp_hdr *)&uip_buf[UIP_LLIPH_LEN + p])
|
||||
#define UIP_TCP_BUF ((struct uip_tcp_hdr *)&uip_buf[UIP_LLIPH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLIPH_LEN])
|
||||
#define UIP_IPPAYLOAD_BUF(pos) (&uip_buf[UIP_LLIPH_LEN + pos])
|
||||
#define UIP_IPPAYLOAD_BUF_POS(pos) (&uip_buf[UIP_IPH_LEN + (pos)])
|
||||
#define UIP_UDP_BUF_POS(pos) ((struct uip_udp_hdr *)UIP_IPPAYLOAD_BUF_POS(pos))
|
||||
|
||||
/** @} */
|
||||
|
||||
|
@ -466,9 +462,9 @@ set_packet_attrs(void)
|
|||
|
||||
/* assign values to the channel attribute (port or type + code) */
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_UDP) {
|
||||
c = UIP_UDP_BUF(0)->srcport;
|
||||
if(UIP_UDP_BUF(0)->destport < c) {
|
||||
c = UIP_UDP_BUF(0)->destport;
|
||||
c = UIP_UDP_BUF_POS(0)->srcport;
|
||||
if(UIP_UDP_BUF_POS(0)->destport < c) {
|
||||
c = UIP_UDP_BUF_POS(0)->destport;
|
||||
}
|
||||
} else if(UIP_IP_BUF->proto == UIP_PROTO_TCP) {
|
||||
c = UIP_TCP_BUF->srcport;
|
||||
|
@ -919,7 +915,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
|
|||
/* Handle the header here! */
|
||||
{
|
||||
struct uip_ext_hdr *ext_hdr =
|
||||
(struct uip_ext_hdr *) UIP_IPPAYLOAD_BUF(ext_hdr_len);
|
||||
(struct uip_ext_hdr *) UIP_IPPAYLOAD_BUF_POS(ext_hdr_len);
|
||||
int len;
|
||||
proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_DESTO : proto;
|
||||
/* Len is defined to be in octets from the length byte */
|
||||
|
@ -958,7 +954,7 @@ compress_hdr_iphc(linkaddr_t *link_destaddr)
|
|||
case UIP_PROTO_UDP:
|
||||
/* allocate a byte for the next header posision as UDP has no next */
|
||||
hc06_ptr++;
|
||||
udp_buf = UIP_UDP_BUF(ext_hdr_len);
|
||||
udp_buf = UIP_UDP_BUF_POS(ext_hdr_len);
|
||||
LOG_DBG("compression: inlined UDP ports on send side: %x, %x\n",
|
||||
UIP_HTONS(udp_buf->srcport), UIP_HTONS(udp_buf->destport));
|
||||
/* Mask out the last 4 bits can be used as a mask */
|
||||
|
@ -1936,12 +1932,12 @@ input(void)
|
|||
|
||||
/* Sanity-check size of incoming packet to avoid buffer overflow */
|
||||
{
|
||||
int req_size = UIP_LLH_LEN + uncomp_hdr_len + (uint16_t)(frag_offset << 3)
|
||||
int req_size = uncomp_hdr_len + (uint16_t)(frag_offset << 3)
|
||||
+ packetbuf_payload_len;
|
||||
if(req_size > sizeof(uip_buf)) {
|
||||
LOG_ERR(
|
||||
"input: packet dropped, minimum required IP_BUF size: %d+%d+%d+%d=%d (current size: %u)\n",
|
||||
UIP_LLH_LEN, uncomp_hdr_len, (uint16_t)(frag_offset << 3),
|
||||
"input: packet dropped, minimum required IP_BUF size: %d+%d+%d=%d (current size: %u)\n",
|
||||
uncomp_hdr_len, (uint16_t)(frag_offset << 3),
|
||||
packetbuf_payload_len, req_size, (unsigned)sizeof(uip_buf));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -52,8 +52,6 @@ PROCESS(simple_udp_process, "Simple UDP process");
|
|||
static uint8_t started = 0;
|
||||
static uint8_t databuffer[UIP_BUFSIZE];
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
init_simple_udp(void)
|
||||
|
@ -134,7 +132,7 @@ PROCESS_THREAD(simple_udp_process, ev, data)
|
|||
{
|
||||
struct simple_udp_connection *c;
|
||||
PROCESS_BEGIN();
|
||||
|
||||
|
||||
while(1) {
|
||||
PROCESS_WAIT_EVENT();
|
||||
if(ev == tcpip_event) {
|
||||
|
@ -165,9 +163,9 @@ PROCESS_THREAD(simple_udp_process, ev, data)
|
|||
PROCESS_CONTEXT_BEGIN(c->client_process);
|
||||
c->receive_callback(c,
|
||||
&(UIP_IP_BUF->srcipaddr),
|
||||
UIP_HTONS(UIP_IP_BUF->srcport),
|
||||
UIP_HTONS(UIP_UDP_BUF->srcport),
|
||||
&(UIP_IP_BUF->destipaddr),
|
||||
UIP_HTONS(UIP_IP_BUF->destport),
|
||||
UIP_HTONS(UIP_UDP_BUF->destport),
|
||||
databuffer, uip_datalen());
|
||||
PROCESS_CONTEXT_END();
|
||||
}
|
||||
|
|
|
@ -55,10 +55,6 @@
|
|||
#define LOG_MODULE "TCP/IP"
|
||||
#define LOG_LEVEL LOG_LEVEL_TCPIP
|
||||
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLIPH_LEN + uip_ext_len])
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_TCP_BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#ifdef UIP_FALLBACK_INTERFACE
|
||||
extern struct uip_fallback_interface UIP_FALLBACK_INTERFACE;
|
||||
#endif
|
||||
|
@ -129,7 +125,7 @@ tcpip_output(const uip_lladdr_t *a)
|
|||
return ret;
|
||||
} else {
|
||||
/* Ok, ignore and drop... */
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -452,18 +448,16 @@ tcpip_input(void)
|
|||
NETSTACK_IP_PROCESS) {
|
||||
process_post_synch(&tcpip_process, PACKET_INPUT, NULL);
|
||||
} /* else - do nothing and drop */
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
extern void remove_ext_hdr(void);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
output_fallback(void)
|
||||
{
|
||||
#ifdef UIP_FALLBACK_INTERFACE
|
||||
LOG_INFO("fallback: removing ext hdrs & setting proto %d %d\n",
|
||||
uip_ext_len, *((uint8_t *)UIP_IP_BUF + 40));
|
||||
remove_ext_hdr();
|
||||
uip_remove_ext_hdr();
|
||||
/* Inform the other end that the destination is not reachable. If it's
|
||||
* not informed routes might get lost unexpectedly until there's a need
|
||||
* to send a new packet to the peer */
|
||||
|
@ -658,7 +652,7 @@ tcpip_ipv6_output(void)
|
|||
if(!NETSTACK_ROUTING.ext_header_update()) {
|
||||
/* Packet can not be forwarded */
|
||||
LOG_ERR("output: routing protocol extension header update error\n");
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -746,7 +740,7 @@ send_packet:
|
|||
}
|
||||
|
||||
exit:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -38,9 +38,6 @@ PROCESS(udp_socket_process, "UDP socket process");
|
|||
|
||||
static uint8_t buf[UIP_BUFSIZE];
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_udpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
init(void)
|
||||
|
@ -182,9 +179,9 @@ PROCESS_THREAD(udp_socket_process, ev, data)
|
|||
PROCESS_CONTEXT_BEGIN(c->p);
|
||||
c->input_callback(c, c->ptr,
|
||||
&(UIP_IP_BUF->srcipaddr),
|
||||
UIP_HTONS(UIP_IP_BUF->srcport),
|
||||
UIP_HTONS(UIP_UDP_BUF->srcport),
|
||||
&(UIP_IP_BUF->destipaddr),
|
||||
UIP_HTONS(UIP_IP_BUF->destport),
|
||||
UIP_HTONS(UIP_UDP_BUF->destport),
|
||||
buf, uip_datalen());
|
||||
PROCESS_CONTEXT_END();
|
||||
}
|
||||
|
|
|
@ -53,11 +53,7 @@
|
|||
#define LOG_MODULE "ICMPv6"
|
||||
#define LOG_LEVEL LOG_LEVEL_IPV6
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_FIRST_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[UIP_LLIPH_LEN])
|
||||
#define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)UIP_ICMP_PAYLOAD)
|
||||
|
||||
/** \brief temporary IP address */
|
||||
static uip_ipaddr_t tmp_ipaddr;
|
||||
|
@ -134,22 +130,7 @@ echo_request_input(void)
|
|||
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &tmp_ipaddr);
|
||||
}
|
||||
|
||||
if(uip_ext_len > 0) {
|
||||
/* Remove extension headers if any */
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
uip_len -= uip_ext_len;
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
/* move the echo request payload (starting after the icmp header)
|
||||
* to the new location in the reply.
|
||||
* The shift is equal to the length of the extension headers present
|
||||
* Note: UIP_ICMP_BUF still points to the echo request at this stage
|
||||
*/
|
||||
memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - uip_ext_len,
|
||||
(uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN,
|
||||
(uip_len - UIP_IPH_LEN - UIP_ICMPH_LEN));
|
||||
uip_ext_len = 0;
|
||||
}
|
||||
uip_remove_ext_hdr();
|
||||
|
||||
/* Below is important for the correctness of UIP_ICMP_BUF and the
|
||||
* checksum
|
||||
|
@ -173,47 +154,38 @@ echo_request_input(void)
|
|||
void
|
||||
uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
||||
/* check if originating packet is not an ICMP error */
|
||||
if(uip_ext_len) {
|
||||
if(UIP_EXT_BUF->next == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128) {
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128) {
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
uint16_t shift;
|
||||
if(uip_last_proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128) {
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
/* Remove all extension headers related to the routing protocol in place */
|
||||
/* Remove all extension headers related to the routing protocol in place.
|
||||
* Keep all other extension headers, so as to match original packet. */
|
||||
NETSTACK_ROUTING.ext_header_remove();
|
||||
|
||||
/* remember data of original packet before shifting */
|
||||
uip_ipaddr_copy(&tmp_ipaddr, &UIP_IP_BUF->destipaddr);
|
||||
|
||||
uip_len += UIP_IPICMPH_LEN + UIP_ICMP6_ERROR_LEN;
|
||||
|
||||
if(uip_len > UIP_LINK_MTU) {
|
||||
uip_len = UIP_LINK_MTU;
|
||||
}
|
||||
|
||||
memmove((uint8_t *)UIP_ICMP6_ERROR_BUF + uip_ext_len + UIP_ICMP6_ERROR_LEN,
|
||||
(void *)UIP_IP_BUF, uip_len - UIP_IPICMPH_LEN - uip_ext_len - UIP_ICMP6_ERROR_LEN);
|
||||
/* The ICMPv6 error message contains as much of possible of the invoking packet
|
||||
* (see RFC 4443 section 3). Make space for the additional IPv6 and
|
||||
* ICMPv6 headers here and move payload to the "right". What we move includes
|
||||
* extension headers */
|
||||
shift = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ICMP6_ERROR_LEN;
|
||||
uip_len += shift;
|
||||
uip_len = MIN(uip_len, UIP_LINK_MTU);
|
||||
memmove(uip_buf + shift, (void *)UIP_IP_BUF, uip_len - shift);
|
||||
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
UIP_IP_BUF->tcflow = 0;
|
||||
UIP_IP_BUF->flow = 0;
|
||||
if (uip_ext_len) {
|
||||
UIP_FIRST_EXT_BUF->next = UIP_PROTO_ICMP6;
|
||||
} else {
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
}
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
|
||||
|
||||
/* the source should not be unspecified nor multicast, the check for
|
||||
multicast is done in uip_process */
|
||||
if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)){
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -223,7 +195,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
|||
if(type == ICMP6_PARAM_PROB && code == ICMP6_PARAMPROB_OPTION){
|
||||
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr);
|
||||
} else {
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -234,8 +206,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) {
|
|||
UIP_ICMP_BUF->type = type;
|
||||
UIP_ICMP_BUF->icode = code;
|
||||
UIP_ICMP6_ERROR_BUF->param = uip_htonl(param);
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
UIP_ICMP_BUF->icmpchksum = 0;
|
||||
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
|
||||
|
||||
|
@ -258,8 +229,7 @@ uip_icmp6_send(const uip_ipaddr_t *dest, int type, int code, int payload_len)
|
|||
UIP_IP_BUF->flow = 0;
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
|
||||
UIP_IP_BUF->len[0] = (UIP_ICMPH_LEN + payload_len) >> 8;
|
||||
UIP_IP_BUF->len[1] = (UIP_ICMPH_LEN + payload_len) & 0xff;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + payload_len);
|
||||
|
||||
memcpy(&UIP_IP_BUF->destipaddr, dest, sizeof(*dest));
|
||||
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
|
||||
|
@ -297,22 +267,7 @@ echo_reply_input(void)
|
|||
uip_ipaddr_copy(&sender, &UIP_IP_BUF->srcipaddr);
|
||||
ttl = UIP_IP_BUF->ttl;
|
||||
|
||||
if(uip_ext_len > 0) {
|
||||
/* Remove extension headers if any */
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
uip_len -= uip_ext_len;
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
/* move the echo reply payload (starting after the icmp header)
|
||||
* to the new location in the reply. The shift is equal to the
|
||||
* length of the extension headers present Note: UIP_ICMP_BUF
|
||||
* still points to the echo request at this stage
|
||||
*/
|
||||
memmove((uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN - uip_ext_len,
|
||||
(uint8_t *)UIP_ICMP_BUF + UIP_ICMPH_LEN,
|
||||
(uip_len - UIP_IPH_LEN - UIP_ICMPH_LEN));
|
||||
uip_ext_len = 0;
|
||||
}
|
||||
uip_remove_ext_hdr();
|
||||
|
||||
/* Call all registered applications to let them know an echo reply
|
||||
has been received. */
|
||||
|
@ -329,7 +284,7 @@ echo_reply_input(void)
|
|||
}
|
||||
}
|
||||
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
/**
|
||||
* \file
|
||||
* Header file for ICMPv6 message and error handing (RFC 4443)
|
||||
* \author Julien Abeille <jabeille@cisco.com>
|
||||
* \author Julien Abeille <jabeille@cisco.com>
|
||||
* \author Mathilde Durvy <mdurvy@cisco.com>
|
||||
*/
|
||||
|
||||
|
@ -52,8 +52,8 @@
|
|||
/** @{ */
|
||||
#define ICMP6_DST_UNREACH 1 /**< dest unreachable */
|
||||
#define ICMP6_PACKET_TOO_BIG 2 /**< packet too big */
|
||||
#define ICMP6_TIME_EXCEEDED 3 /**< time exceeded */
|
||||
#define ICMP6_PARAM_PROB 4 /**< ip6 header bad */
|
||||
#define ICMP6_TIME_EXCEEDED 3 /**< time exceeded */
|
||||
#define ICMP6_PARAM_PROB 4 /**< ip6 header bad */
|
||||
#define ICMP6_ECHO_REQUEST 128 /**< Echo request */
|
||||
#define ICMP6_ECHO_REPLY 129 /**< Echo reply */
|
||||
|
||||
|
@ -76,10 +76,10 @@
|
|||
/** \name ICMPv6 Destination Unreachable message codes*/
|
||||
/** @{ */
|
||||
#define ICMP6_DST_UNREACH_NOROUTE 0 /**< no route to destination */
|
||||
#define ICMP6_DST_UNREACH_ADMIN 1 /**< administratively prohibited */
|
||||
#define ICMP6_DST_UNREACH_ADMIN 1 /**< administratively prohibited */
|
||||
#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /**< not a neighbor(obsolete) */
|
||||
#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /**< beyond scope of source address */
|
||||
#define ICMP6_DST_UNREACH_ADDR 3 /**< address unreachable */
|
||||
#define ICMP6_DST_UNREACH_ADDR 3 /**< address unreachable */
|
||||
#define ICMP6_DST_UNREACH_NOPORT 4 /**< port unreachable */
|
||||
/** @} */
|
||||
|
||||
|
@ -116,7 +116,7 @@ typedef struct uip_icmp6_error{
|
|||
* \param param 32 bit parameter of the error message, semantic depends on error
|
||||
*/
|
||||
void
|
||||
uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param);
|
||||
uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param);
|
||||
|
||||
/**
|
||||
* \brief Send an icmpv6 message
|
||||
|
|
|
@ -108,7 +108,7 @@ uip_nameserver_update(const uip_ipaddr_t *nameserver, uint32_t lifetime)
|
|||
* the the eldest ones */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(e == NULL) {
|
||||
if((e = memb_alloc(&dnsmemb)) != NULL) {
|
||||
list_add(dns, e);
|
||||
|
@ -221,11 +221,7 @@ uip_nameserver_count(void)
|
|||
}
|
||||
return list_length(dns);
|
||||
#else /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
if(uip_is_addr_unspecified(&serveraddr)) {
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
if(uip_ipaddr_cmp(&serveraddr, &uip_all_zeroes_addr)) {
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
|
|
|
@ -84,29 +84,20 @@
|
|||
/*------------------------------------------------------------------*/
|
||||
/** @{ */
|
||||
/** \name Pointers to the header structures.
|
||||
* All pointers except UIP_IP_BUF depend on uip_ext_len, which at
|
||||
* packet reception, is the total length of the extension headers.
|
||||
*
|
||||
* The pointer to ND6 options header also depends on nd6_opt_offset,
|
||||
* which we set in each function.
|
||||
*
|
||||
* Care should be taken when manipulating these buffers about the
|
||||
* value of these length variables
|
||||
*/
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN]) /**< Pointer to IP header */
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len]) /**< Pointer to ICMP header*/
|
||||
/**@{ Pointers to messages just after icmp header */
|
||||
#define UIP_ND6_RS_BUF ((uip_nd6_rs *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_ND6_RA_BUF ((uip_nd6_ra *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_ND6_NS_BUF ((uip_nd6_ns *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_ND6_NA_BUF ((uip_nd6_na *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define UIP_ND6_RS_BUF ((uip_nd6_rs *)UIP_ICMP_PAYLOAD)
|
||||
#define UIP_ND6_RA_BUF ((uip_nd6_ra *)UIP_ICMP_PAYLOAD)
|
||||
#define UIP_ND6_NS_BUF ((uip_nd6_ns *)UIP_ICMP_PAYLOAD)
|
||||
#define UIP_ND6_NA_BUF ((uip_nd6_na *)UIP_ICMP_PAYLOAD)
|
||||
/** @} */
|
||||
/** Pointer to ND option */
|
||||
#define UIP_ND6_OPT_HDR_BUF ((uip_nd6_opt_hdr *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||
#define UIP_ND6_OPT_PREFIX_BUF ((uip_nd6_opt_prefix_info *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||
#define UIP_ND6_OPT_MTU_BUF ((uip_nd6_opt_mtu *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||
#define UIP_ND6_OPT_RDNSS_BUF ((uip_nd6_opt_dns *)&uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset])
|
||||
#define ND6_OPT(opt) ((unsigned char *)(UIP_ICMP_PAYLOAD + (opt)))
|
||||
#define ND6_OPT_HDR_BUF(opt) ((uip_nd6_opt_hdr *)ND6_OPT(opt))
|
||||
#define ND6_OPT_PREFIX_BUF(opt) ((uip_nd6_opt_prefix_info *)ND6_OPT(opt))
|
||||
#define ND6_OPT_MTU_BUF(opt) ((uip_nd6_opt_mtu *)ND6_OPT(opt))
|
||||
#define ND6_OPT_RDNSS_BUF(opt) ((uip_nd6_opt_dns *)ND6_OPT(opt))
|
||||
/** @} */
|
||||
|
||||
#if UIP_ND6_SEND_NS || UIP_ND6_SEND_NA || UIP_ND6_SEND_RA || !UIP_CONF_ROUTER
|
||||
|
@ -203,14 +194,14 @@ ns_input(void)
|
|||
nd6_opt_offset = UIP_ND6_NS_LEN;
|
||||
while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
if(UIP_ND6_OPT_HDR_BUF->len == 0) {
|
||||
if(ND6_OPT_HDR_BUF(nd6_opt_offset)->len == 0) {
|
||||
LOG_ERR("NS received is bad\n");
|
||||
goto discard;
|
||||
}
|
||||
#endif /* UIP_CONF_IPV6_CHECKS */
|
||||
switch (UIP_ND6_OPT_HDR_BUF->type) {
|
||||
switch (ND6_OPT_HDR_BUF(nd6_opt_offset)->type) {
|
||||
case UIP_ND6_OPT_SLLAO:
|
||||
nd6_opt_llao = &uip_buf[uip_l2_l3_icmp_hdr_len + nd6_opt_offset];
|
||||
nd6_opt_llao = &uip_buf[uip_l3_icmp_hdr_len + nd6_opt_offset];
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
/* There must be NO option in a DAD NS */
|
||||
if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
|
||||
|
@ -252,7 +243,7 @@ ns_input(void)
|
|||
LOG_WARN("ND option not supported in NS");
|
||||
break;
|
||||
}
|
||||
nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3);
|
||||
nd6_opt_offset += (ND6_OPT_HDR_BUF(nd6_opt_offset)->len << 3);
|
||||
}
|
||||
|
||||
addr = uip_ds6_addr_lookup(&UIP_ND6_NS_BUF->tgtipaddr);
|
||||
|
@ -323,12 +314,11 @@ create_na:
|
|||
#if UIP_CONF_ROUTER
|
||||
flags = flags | UIP_ND6_NA_FLAG_ROUTER;
|
||||
#endif
|
||||
uip_ext_len = 0;
|
||||
uipbuf_clear();
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
UIP_IP_BUF->tcflow = 0;
|
||||
UIP_IP_BUF->flow = 0;
|
||||
UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */
|
||||
UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN);
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
|
||||
UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT;
|
||||
|
||||
|
@ -338,14 +328,13 @@ create_na:
|
|||
UIP_ND6_NA_BUF->flagsreserved = flags;
|
||||
memcpy(&UIP_ND6_NA_BUF->tgtipaddr, &addr->ipaddr, sizeof(uip_ipaddr_t));
|
||||
|
||||
create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NA_LEN],
|
||||
create_llao(&uip_buf[uip_l3_icmp_hdr_len + UIP_ND6_NA_LEN],
|
||||
UIP_ND6_OPT_TLLAO);
|
||||
|
||||
UIP_ICMP_BUF->icmpchksum = 0;
|
||||
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
|
||||
|
||||
uip_len =
|
||||
UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN;
|
||||
uipbuf_set_len(UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_NA_LEN + UIP_ND6_OPT_LLAO_LEN);
|
||||
|
||||
UIP_STAT(++uip_stat.nd6.sent);
|
||||
LOG_INFO("Sending NA to ");
|
||||
|
@ -358,7 +347,7 @@ create_na:
|
|||
return;
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
#endif /* UIP_ND6_SEND_NA */
|
||||
|
@ -369,7 +358,7 @@ discard:
|
|||
void
|
||||
uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt)
|
||||
{
|
||||
uip_ext_len = 0;
|
||||
uipbuf_clear();
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
UIP_IP_BUF->tcflow = 0;
|
||||
UIP_IP_BUF->flow = 0;
|
||||
|
@ -385,7 +374,6 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt)
|
|||
UIP_ICMP_BUF->icode = 0;
|
||||
UIP_ND6_NS_BUF->reserved = 0;
|
||||
uip_ipaddr_copy((uip_ipaddr_t *) &UIP_ND6_NS_BUF->tgtipaddr, tgt);
|
||||
UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */
|
||||
/*
|
||||
* check if we add a SLLAO option: for DAD, MUST NOT, for NUD, MAY
|
||||
* (here yes), for Address resolution , MUST
|
||||
|
@ -398,13 +386,12 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt)
|
|||
}
|
||||
if (uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
|
||||
LOG_ERR("Dropping NS due to no suitable source address\n");
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
UIP_IP_BUF->len[1] =
|
||||
UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + UIP_ND6_NS_LEN + UIP_ND6_OPT_LLAO_LEN);
|
||||
|
||||
create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_NS_LEN],
|
||||
create_llao(&uip_buf[uip_l3_icmp_hdr_len + UIP_ND6_NS_LEN],
|
||||
UIP_ND6_OPT_SLLAO);
|
||||
|
||||
uip_len =
|
||||
|
@ -493,20 +480,20 @@ na_input(void)
|
|||
nd6_opt_llao = NULL;
|
||||
while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
if(UIP_ND6_OPT_HDR_BUF->len == 0) {
|
||||
if(ND6_OPT_HDR_BUF(nd6_opt_offset)->len == 0) {
|
||||
LOG_ERR("NA received is bad\n");
|
||||
goto discard;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS */
|
||||
switch (UIP_ND6_OPT_HDR_BUF->type) {
|
||||
switch (ND6_OPT_HDR_BUF(nd6_opt_offset)->type) {
|
||||
case UIP_ND6_OPT_TLLAO:
|
||||
nd6_opt_llao = (uint8_t *)UIP_ND6_OPT_HDR_BUF;
|
||||
nd6_opt_llao = (uint8_t *)ND6_OPT_HDR_BUF(nd6_opt_offset);
|
||||
break;
|
||||
default:
|
||||
LOG_WARN("ND option not supported in NA\n");
|
||||
break;
|
||||
}
|
||||
nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3);
|
||||
nd6_opt_offset += (ND6_OPT_HDR_BUF(nd6_opt_offset)->len << 3);
|
||||
}
|
||||
addr = uip_ds6_addr_lookup(&UIP_ND6_NA_BUF->tgtipaddr);
|
||||
/* Message processing, including TLLAO if any */
|
||||
|
@ -605,7 +592,7 @@ na_input(void)
|
|||
#endif /*UIP_CONF_IPV6_QUEUE_PKT */
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
#endif /* UIP_ND6_SEND_NS */
|
||||
|
@ -644,20 +631,20 @@ rs_input(void)
|
|||
|
||||
while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
if(UIP_ND6_OPT_HDR_BUF->len == 0) {
|
||||
if(ND6_OPT_HDR_BUF(nd6_opt_offset)->len == 0) {
|
||||
LOG_ERR("RS received is bad\n");
|
||||
goto discard;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS */
|
||||
switch (UIP_ND6_OPT_HDR_BUF->type) {
|
||||
switch (ND6_OPT_HDR_BUF(nd6_opt_offset)->type) {
|
||||
case UIP_ND6_OPT_SLLAO:
|
||||
nd6_opt_llao = (uint8_t *)UIP_ND6_OPT_HDR_BUF;
|
||||
nd6_opt_llao = (uint8_t *)ND6_OPT_HDR_BUF(nd6_opt_offset);
|
||||
break;
|
||||
default:
|
||||
LOG_WARN("ND option not supported in RS\n");
|
||||
break;
|
||||
}
|
||||
nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3);
|
||||
nd6_opt_offset += (ND6_OPT_HDR_BUF(nd6_opt_offset)->len << 3);
|
||||
}
|
||||
/* Options processing: only SLLAO */
|
||||
if(nd6_opt_llao != NULL) {
|
||||
|
@ -701,7 +688,7 @@ rs_input(void)
|
|||
uip_ds6_send_ra_sollicited();
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -746,31 +733,31 @@ uip_nd6_ra_output(uip_ipaddr_t * dest)
|
|||
for(prefix = uip_ds6_prefix_list;
|
||||
prefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; prefix++) {
|
||||
if((prefix->isused) && (prefix->advertise)) {
|
||||
UIP_ND6_OPT_PREFIX_BUF->type = UIP_ND6_OPT_PREFIX_INFO;
|
||||
UIP_ND6_OPT_PREFIX_BUF->len = UIP_ND6_OPT_PREFIX_INFO_LEN / 8;
|
||||
UIP_ND6_OPT_PREFIX_BUF->preflen = prefix->length;
|
||||
UIP_ND6_OPT_PREFIX_BUF->flagsreserved1 = prefix->l_a_reserved;
|
||||
UIP_ND6_OPT_PREFIX_BUF->validlt = uip_htonl(prefix->vlifetime);
|
||||
UIP_ND6_OPT_PREFIX_BUF->preferredlt = uip_htonl(prefix->plifetime);
|
||||
UIP_ND6_OPT_PREFIX_BUF->reserved2 = 0;
|
||||
uip_ipaddr_copy(&(UIP_ND6_OPT_PREFIX_BUF->prefix), &(prefix->ipaddr));
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->type = UIP_ND6_OPT_PREFIX_INFO;
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->len = UIP_ND6_OPT_PREFIX_INFO_LEN / 8;
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->preflen = prefix->length;
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->flagsreserved1 = prefix->l_a_reserved;
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->validlt = uip_htonl(prefix->vlifetime);
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->preferredlt = uip_htonl(prefix->plifetime);
|
||||
ND6_OPT_PREFIX_BUF(nd6_opt_offset)->reserved2 = 0;
|
||||
uip_ipaddr_copy(&(ND6_OPT_PREFIX_BUF(nd6_opt_offset)->prefix), &(prefix->ipaddr));
|
||||
nd6_opt_offset += UIP_ND6_OPT_PREFIX_INFO_LEN;
|
||||
uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Source link-layer option */
|
||||
create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF, UIP_ND6_OPT_SLLAO);
|
||||
create_llao((uint8_t *)ND6_OPT_HDR_BUF(nd6_opt_offset), UIP_ND6_OPT_SLLAO);
|
||||
|
||||
uip_len += UIP_ND6_OPT_LLAO_LEN;
|
||||
nd6_opt_offset += UIP_ND6_OPT_LLAO_LEN;
|
||||
|
||||
/* MTU */
|
||||
UIP_ND6_OPT_MTU_BUF->type = UIP_ND6_OPT_MTU;
|
||||
UIP_ND6_OPT_MTU_BUF->len = UIP_ND6_OPT_MTU_LEN >> 3;
|
||||
UIP_ND6_OPT_MTU_BUF->reserved = 0;
|
||||
//UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(uip_ds6_if.link_mtu);
|
||||
UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(1500);
|
||||
ND6_OPT_MTU_BUF(nd6_opt_offset)->type = UIP_ND6_OPT_MTU;
|
||||
ND6_OPT_MTU_BUF(nd6_opt_offset)->len = UIP_ND6_OPT_MTU_LEN >> 3;
|
||||
ND6_OPT_MTU_BUF(nd6_opt_offset)->reserved = 0;
|
||||
//ND6_OPT_MTU_BUF(nd6_opt_offset)->mtu = uip_htonl(uip_ds6_if.link_mtu);
|
||||
ND6_OPT_MTU_BUF(nd6_opt_offset)->mtu = uip_htonl(1500);
|
||||
|
||||
uip_len += UIP_ND6_OPT_MTU_LEN;
|
||||
nd6_opt_offset += UIP_ND6_OPT_MTU_LEN;
|
||||
|
@ -778,27 +765,26 @@ uip_nd6_ra_output(uip_ipaddr_t * dest)
|
|||
#if UIP_ND6_RA_RDNSS
|
||||
if(uip_nameserver_count() > 0) {
|
||||
uint8_t i = 0;
|
||||
uip_ipaddr_t *ip = &UIP_ND6_OPT_RDNSS_BUF->ip;
|
||||
uip_ipaddr_t *ip = &ND6_OPT_RDNSS_BUF(nd6_opt_offset)->ip;
|
||||
uip_ipaddr_t *dns = NULL;
|
||||
UIP_ND6_OPT_RDNSS_BUF->type = UIP_ND6_OPT_RDNSS;
|
||||
UIP_ND6_OPT_RDNSS_BUF->reserved = 0;
|
||||
UIP_ND6_OPT_RDNSS_BUF->lifetime = uip_nameserver_next_expiration();
|
||||
if(UIP_ND6_OPT_RDNSS_BUF->lifetime != UIP_NAMESERVER_INFINITE_LIFETIME) {
|
||||
UIP_ND6_OPT_RDNSS_BUF->lifetime -= clock_seconds();
|
||||
ND6_OPT_RDNSS_BUF(nd6_opt_offset)->type = UIP_ND6_OPT_RDNSS;
|
||||
ND6_OPT_RDNSS_BUF(nd6_opt_offset)->reserved = 0;
|
||||
ND6_OPT_RDNSS_BUF(nd6_opt_offset)->lifetime = uip_nameserver_next_expiration();
|
||||
if(ND6_OPT_RDNSS_BUF(nd6_opt_offset)->lifetime != UIP_NAMESERVER_INFINITE_LIFETIME) {
|
||||
ND6_OPT_RDNSS_BUF(nd6_opt_offset)->lifetime -= clock_seconds();
|
||||
}
|
||||
while((dns = uip_nameserver_get(i)) != NULL) {
|
||||
uip_ipaddr_copy(ip++, dns);
|
||||
i++;
|
||||
}
|
||||
UIP_ND6_OPT_RDNSS_BUF->len = UIP_ND6_OPT_RDNSS_LEN + (i << 1);
|
||||
ND6_OPT_RDNSS_BUF(nd6_opt_offset)->len = UIP_ND6_OPT_RDNSS_LEN + (i << 1);
|
||||
LOG_INFO("%d nameservers reported\n", i);
|
||||
uip_len += UIP_ND6_OPT_RDNSS_BUF->len << 3;
|
||||
nd6_opt_offset += UIP_ND6_OPT_RDNSS_BUF->len << 3;
|
||||
uip_len += ND6_OPT_RDNSS_BUF(nd6_opt_offset)->len << 3;
|
||||
nd6_opt_offset += ND6_OPT_RDNSS_BUF(nd6_opt_offset)->len << 3;
|
||||
}
|
||||
#endif /* UIP_ND6_RA_RDNSS */
|
||||
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
/*ICMP checksum */
|
||||
UIP_ICMP_BUF->icmpchksum = 0;
|
||||
|
@ -829,17 +815,15 @@ uip_nd6_rs_output(void)
|
|||
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
|
||||
UIP_ICMP_BUF->type = ICMP6_RS;
|
||||
UIP_ICMP_BUF->icode = 0;
|
||||
UIP_IP_BUF->len[0] = 0; /* length will not be more than 255 */
|
||||
|
||||
if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
|
||||
UIP_IP_BUF->len[1] = UIP_ICMPH_LEN + UIP_ND6_RS_LEN;
|
||||
uip_len = uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN;
|
||||
} else {
|
||||
uip_len = uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN;
|
||||
UIP_IP_BUF->len[1] =
|
||||
UIP_ICMPH_LEN + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN;
|
||||
uipbuf_set_len_field(UIP_IP_BUF, UIP_ICMPH_LEN + UIP_ND6_RS_LEN + UIP_ND6_OPT_LLAO_LEN);
|
||||
|
||||
create_llao(&uip_buf[uip_l2_l3_icmp_hdr_len + UIP_ND6_RS_LEN],
|
||||
create_llao(&uip_buf[uip_l3_icmp_hdr_len + UIP_ND6_RS_LEN],
|
||||
UIP_ND6_OPT_SLLAO);
|
||||
}
|
||||
|
||||
|
@ -904,14 +888,14 @@ ra_input(void)
|
|||
/* Options processing */
|
||||
nd6_opt_offset = UIP_ND6_RA_LEN;
|
||||
while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
|
||||
if(UIP_ND6_OPT_HDR_BUF->len == 0) {
|
||||
if(ND6_OPT_HDR_BUF(nd6_opt_offset)->len == 0) {
|
||||
LOG_ERR("RA received is bad");
|
||||
goto discard;
|
||||
}
|
||||
switch (UIP_ND6_OPT_HDR_BUF->type) {
|
||||
switch (ND6_OPT_HDR_BUF(nd6_opt_offset)->type) {
|
||||
case UIP_ND6_OPT_SLLAO:
|
||||
LOG_DBG("Processing SLLAO option in RA\n");
|
||||
nd6_opt_llao = (uint8_t *) UIP_ND6_OPT_HDR_BUF;
|
||||
nd6_opt_llao = (uint8_t *) ND6_OPT_HDR_BUF(nd6_opt_offset);
|
||||
nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr);
|
||||
if(!extract_lladdr_from_llao_aligned(&lladdr_aligned)) {
|
||||
/* failed to extract llao - discard packet */
|
||||
|
@ -944,11 +928,11 @@ ra_input(void)
|
|||
case UIP_ND6_OPT_MTU:
|
||||
LOG_DBG("Processing MTU option in RA\n");
|
||||
uip_ds6_if.link_mtu =
|
||||
uip_ntohl(((uip_nd6_opt_mtu *) UIP_ND6_OPT_HDR_BUF)->mtu);
|
||||
uip_ntohl(((uip_nd6_opt_mtu *) ND6_OPT_HDR_BUF(nd6_opt_offset))->mtu);
|
||||
break;
|
||||
case UIP_ND6_OPT_PREFIX_INFO:
|
||||
LOG_DBG("Processing PREFIX option in RA\n");
|
||||
nd6_opt_prefix_info = (uip_nd6_opt_prefix_info *) UIP_ND6_OPT_HDR_BUF;
|
||||
nd6_opt_prefix_info = (uip_nd6_opt_prefix_info *) ND6_OPT_HDR_BUF(nd6_opt_offset);
|
||||
if((uip_ntohl(nd6_opt_prefix_info->validlt) >=
|
||||
uip_ntohl(nd6_opt_prefix_info->preferredlt))
|
||||
&& (!uip_is_addr_linklocal(&nd6_opt_prefix_info->prefix))) {
|
||||
|
@ -1035,14 +1019,14 @@ ra_input(void)
|
|||
#if UIP_ND6_RA_RDNSS
|
||||
case UIP_ND6_OPT_RDNSS:
|
||||
LOG_DBG("Processing RDNSS option\n");
|
||||
uint8_t naddr = (UIP_ND6_OPT_RDNSS_BUF->len - 1) / 2;
|
||||
uip_ipaddr_t *ip = (uip_ipaddr_t *)(&UIP_ND6_OPT_RDNSS_BUF->ip);
|
||||
uint8_t naddr = (ND6_OPT_RDNSS_BUF(nd6_opt_offset)->len - 1) / 2;
|
||||
uip_ipaddr_t *ip = (uip_ipaddr_t *)(&ND6_OPT_RDNSS_BUF(nd6_opt_offset)->ip);
|
||||
LOG_DBG("got %d nameservers\n", naddr);
|
||||
while(naddr-- > 0) {
|
||||
LOG_DBG("nameserver: ");
|
||||
LOG_DBG_6ADDR(ip);
|
||||
LOG_DBG_(" lifetime: %"PRIx32"\n", uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime));
|
||||
uip_nameserver_update(ip, uip_ntohl(UIP_ND6_OPT_RDNSS_BUF->lifetime));
|
||||
LOG_DBG_(" lifetime: %"PRIx32"\n", uip_ntohl(ND6_OPT_RDNSS_BUF(nd6_opt_offset)->lifetime));
|
||||
uip_nameserver_update(ip, uip_ntohl(ND6_OPT_RDNSS_BUF(nd6_opt_offset)->lifetime));
|
||||
ip++;
|
||||
}
|
||||
break;
|
||||
|
@ -1051,7 +1035,7 @@ ra_input(void)
|
|||
LOG_ERR("ND option not supported in RA\n");
|
||||
break;
|
||||
}
|
||||
nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3);
|
||||
nd6_opt_offset += (ND6_OPT_HDR_BUF(nd6_opt_offset)->len << 3);
|
||||
}
|
||||
|
||||
defrt = uip_ds6_defrt_lookup(&UIP_IP_BUF->srcipaddr);
|
||||
|
@ -1092,7 +1076,7 @@ ra_input(void)
|
|||
#endif /*UIP_CONF_IPV6_QUEUE_PKT */
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
#endif /* !UIP_CONF_ROUTER */
|
||||
|
|
|
@ -7,7 +7,7 @@ struct uip_packetqueue_handle;
|
|||
|
||||
struct uip_packetqueue_packet {
|
||||
struct uip_ds6_queued_packet *next;
|
||||
uint8_t queue_buf[UIP_BUFSIZE - UIP_LLH_LEN];
|
||||
uint8_t queue_buf[UIP_BUFSIZE];
|
||||
uint16_t queue_buf_len;
|
||||
struct ctimer lifetimer;
|
||||
struct uip_packetqueue_handle *handle;
|
||||
|
|
|
@ -51,10 +51,10 @@ void
|
|||
uip_udp_packet_send(struct uip_udp_conn *c, const void *data, int len)
|
||||
{
|
||||
#if UIP_UDP
|
||||
if(data != NULL && len <= (UIP_BUFSIZE - (UIP_LLH_LEN + UIP_IPUDPH_LEN))) {
|
||||
if(data != NULL && len <= (UIP_BUFSIZE - UIP_IPUDPH_LEN)) {
|
||||
uip_udp_conn = c;
|
||||
uip_slen = len;
|
||||
memmove(&uip_buf[UIP_LLH_LEN + UIP_IPUDPH_LEN], data, len);
|
||||
memmove(&uip_buf[UIP_IPUDPH_LEN], data, len);
|
||||
uip_process(UIP_UDP_SEND_CONN);
|
||||
|
||||
#if UIP_IPV6_MULTICAST
|
||||
|
|
|
@ -62,22 +62,24 @@
|
|||
|
||||
#define UIP_IPUDPH_LEN (UIP_UDPH_LEN + UIP_IPH_LEN) /* Size of IP + UDP header */
|
||||
#define UIP_IPTCPH_LEN (UIP_TCPH_LEN + UIP_IPH_LEN) /* Size of IP + TCP header */
|
||||
#define UIP_TCPIP_HLEN UIP_IPTCPH_LEN
|
||||
#define UIP_IPICMPH_LEN (UIP_IPH_LEN + UIP_ICMPH_LEN) /* Size of ICMP + IP header */
|
||||
#define UIP_LLIPH_LEN (UIP_LLH_LEN + UIP_IPH_LEN) /* Size of L2 + IP header */
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/**
|
||||
* The sums below are quite used in ND. When used for uip_buf, we
|
||||
* include link layer length when used for uip_len, we do not, hence
|
||||
* we need values with and without LLH_LEN we do not use capital
|
||||
* letters as these values are variable
|
||||
*/
|
||||
#define uip_l2_l3_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len)
|
||||
#define uip_l2_l3_icmp_hdr_len (UIP_LLH_LEN + UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN)
|
||||
#define uip_l3_hdr_len (UIP_IPH_LEN + uip_ext_len)
|
||||
#define uip_l3_icmp_hdr_len (UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN)
|
||||
#endif /*NETSTACK_CONF_WITH_IPV6*/
|
||||
|
||||
#define uip_l3_icmp_hdr_len (UIP_IPH_LEN + uip_ext_len + UIP_ICMPH_LEN)
|
||||
|
||||
/**
|
||||
* Direct access to IPv6 header
|
||||
*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)uip_buf)
|
||||
#define UIP_IP_PAYLOAD(ext) ((unsigned char *)uip_buf + UIP_IPH_LEN + (ext))
|
||||
|
||||
/**
|
||||
* Direct access to ICMP, UDP, and TCP headers and payload, with implicit ext header offset (global uip_ext_len)
|
||||
*/
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)UIP_IP_PAYLOAD(uip_ext_len))
|
||||
#define UIP_ICMP_PAYLOAD ((unsigned char *)UIP_IP_PAYLOAD(uip_ext_len) + UIP_ICMPH_LEN)
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)UIP_IP_PAYLOAD(uip_ext_len))
|
||||
#define UIP_UDP_PAYLOAD ((unsigned char *)UIP_IP_PAYLOAD(uip_ext_len) + UIP_UDPH_LEN)
|
||||
#define UIP_TCP_BUF ((struct uip_tcp_hdr *)UIP_IP_PAYLOAD(uip_ext_len))
|
||||
#define UIP_TCP_PAYLOAD ((unsigned char *)UIP_IP_PAYLOAD(uip_ext_len) + UIP_TCPH_LEN)
|
||||
|
||||
#include "net/ipv6/uipopt.h"
|
||||
#include "net/ipv6/uipbuf.h"
|
||||
|
@ -100,12 +102,7 @@ typedef union uip_ip6addr_t {
|
|||
uint16_t u16[8];
|
||||
} uip_ip6addr_t;
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
typedef uip_ip6addr_t uip_ipaddr_t;
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
typedef uip_ip4addr_t uip_ipaddr_t;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_802154_SHORTADDR_LEN 2
|
||||
|
@ -1048,11 +1045,7 @@ struct uip_udp_conn *uip_udp_new(const uip_ipaddr_t *ripaddr, uint16_t rport);
|
|||
(addr1)->u16[1] == (addr2)->u16[1])
|
||||
#define uip_ip6addr_cmp(addr1, addr2) (memcmp(addr1, addr2, sizeof(uip_ip6addr_t)) == 0)
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#define uip_ipaddr_cmp(addr1, addr2) uip_ip6addr_cmp(addr1, addr2)
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
#define uip_ipaddr_cmp(addr1, addr2) uip_ip4addr_cmp(addr1, addr2)
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/**
|
||||
* Compare two IP addresses with netmasks
|
||||
|
@ -1308,31 +1301,16 @@ extern uint16_t uip_len;
|
|||
* The length of the extension headers
|
||||
*/
|
||||
extern uint8_t uip_ext_len;
|
||||
|
||||
/** The final protocol after IPv6 extension headers:
|
||||
* UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6 */
|
||||
extern uint8_t uip_last_proto;
|
||||
/** @} */
|
||||
|
||||
#if UIP_URGDATA > 0
|
||||
extern uint16_t uip_urglen, uip_surglen;
|
||||
#endif /* UIP_URGDATA > 0 */
|
||||
|
||||
/*
|
||||
* Clear uIP buffer
|
||||
*
|
||||
* This function clears the uIP buffer by reseting the uip_len and
|
||||
* uip_ext_len pointers.
|
||||
*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#define uip_clear_buf() { \
|
||||
uip_len = 0; \
|
||||
uip_ext_len = 0; \
|
||||
uipbuf_clear_attr();\
|
||||
}
|
||||
#else /*NETSTACK_CONF_WITH_IPV6*/
|
||||
#define uip_clear_buf() { \
|
||||
uip_len = 0; \
|
||||
uipbuf_clear_attr();\
|
||||
}
|
||||
#endif /*NETSTACK_CONF_WITH_IPV6*/
|
||||
|
||||
/**
|
||||
* Representation of a uIP TCP connection.
|
||||
*
|
||||
|
@ -1494,13 +1472,11 @@ struct uip_stats {
|
|||
checksum. */
|
||||
} udp; /**< UDP statistics. */
|
||||
#endif /* UIP_UDP */
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
struct {
|
||||
uip_stats_t drop; /**< Number of dropped ND6 packets. */
|
||||
uip_stats_t recv; /**< Number of recived ND6 packets */
|
||||
uip_stats_t sent; /**< Number of sent ND6 packets */
|
||||
} nd6;
|
||||
#endif /*NETSTACK_CONF_WITH_IPV6*/
|
||||
};
|
||||
|
||||
|
||||
|
@ -1619,113 +1595,14 @@ void uip_process(uint8_t flag);
|
|||
|
||||
#define UIP_STOPPED 16
|
||||
|
||||
/* The TCP and IP headers. */
|
||||
struct uip_tcpip_hdr {
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* IPv6 header. */
|
||||
uint8_t vtc,
|
||||
tcflow;
|
||||
uint16_t flow;
|
||||
uint8_t len[2];
|
||||
uint8_t proto, ttl;
|
||||
uip_ip6addr_t srcipaddr, destipaddr;
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* IPv4 header. */
|
||||
uint8_t vhl,
|
||||
tos,
|
||||
len[2],
|
||||
ipid[2],
|
||||
ipoffset[2],
|
||||
ttl,
|
||||
proto;
|
||||
uint16_t ipchksum;
|
||||
uip_ipaddr_t srcipaddr, destipaddr;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* TCP header. */
|
||||
uint16_t srcport,
|
||||
destport;
|
||||
uint8_t seqno[4],
|
||||
ackno[4],
|
||||
tcpoffset,
|
||||
flags,
|
||||
wnd[2];
|
||||
uint16_t tcpchksum;
|
||||
uint8_t urgp[2];
|
||||
uint8_t optdata[4];
|
||||
};
|
||||
|
||||
/* The ICMP and IP headers. */
|
||||
struct uip_icmpip_hdr {
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* IPv6 header. */
|
||||
uint8_t vtc,
|
||||
tcf;
|
||||
uint16_t flow;
|
||||
uint8_t len[2];
|
||||
uint8_t proto, ttl;
|
||||
uip_ip6addr_t srcipaddr, destipaddr;
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* IPv4 header. */
|
||||
uint8_t vhl,
|
||||
tos,
|
||||
len[2],
|
||||
ipid[2],
|
||||
ipoffset[2],
|
||||
ttl,
|
||||
proto;
|
||||
uint16_t ipchksum;
|
||||
uip_ipaddr_t srcipaddr, destipaddr;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* ICMP header. */
|
||||
uint8_t type, icode;
|
||||
uint16_t icmpchksum;
|
||||
#if !NETSTACK_CONF_WITH_IPV6
|
||||
uint16_t id, seqno;
|
||||
uint8_t payload[1];
|
||||
#endif /* !NETSTACK_CONF_WITH_IPV6 */
|
||||
};
|
||||
|
||||
|
||||
/* The UDP and IP headers. */
|
||||
struct uip_udpip_hdr {
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* IPv6 header. */
|
||||
uint8_t vtc,
|
||||
tcf;
|
||||
uint16_t flow;
|
||||
uint8_t len[2];
|
||||
uint8_t proto, ttl;
|
||||
uip_ip6addr_t srcipaddr, destipaddr;
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* IP header. */
|
||||
uint8_t vhl,
|
||||
tos,
|
||||
len[2],
|
||||
ipid[2],
|
||||
ipoffset[2],
|
||||
ttl,
|
||||
proto;
|
||||
uint16_t ipchksum;
|
||||
uip_ipaddr_t srcipaddr, destipaddr;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
/* UDP header. */
|
||||
uint16_t srcport,
|
||||
destport;
|
||||
uint16_t udplen;
|
||||
uint16_t udpchksum;
|
||||
};
|
||||
|
||||
/*
|
||||
* In IPv6 the length of the L3 headers before the transport header is
|
||||
* not fixed, due to the possibility to include extension option headers
|
||||
* after the IP header. hence we split here L3 and L4 headers
|
||||
*/
|
||||
/* The IP header */
|
||||
|
||||
struct uip_ip_hdr {
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/* IPV6 header */
|
||||
uint8_t vtc;
|
||||
uint8_t tcflow;
|
||||
|
@ -1733,18 +1610,6 @@ struct uip_ip_hdr {
|
|||
uint8_t len[2];
|
||||
uint8_t proto, ttl;
|
||||
uip_ip6addr_t srcipaddr, destipaddr;
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/* IPV4 header */
|
||||
uint8_t vhl,
|
||||
tos,
|
||||
len[2],
|
||||
ipid[2],
|
||||
ipoffset[2],
|
||||
ttl,
|
||||
proto;
|
||||
uint16_t ipchksum;
|
||||
uip_ipaddr_t srcipaddr, destipaddr;
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
};
|
||||
|
||||
|
||||
|
@ -1860,9 +1725,6 @@ struct uip_tcp_hdr {
|
|||
struct uip_icmp_hdr {
|
||||
uint8_t type, icode;
|
||||
uint16_t icmpchksum;
|
||||
#if !NETSTACK_CONF_WITH_IPV6
|
||||
uint16_t id, seqno;
|
||||
#endif /* !NETSTACK_CONF_WITH_IPV6 */
|
||||
};
|
||||
|
||||
|
||||
|
@ -1889,8 +1751,7 @@ struct uip_udp_hdr {
|
|||
*
|
||||
* \hideinitializer
|
||||
*/
|
||||
#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
|
||||
#define UIP_APPDATA_PTR (void *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]
|
||||
#define UIP_APPDATA_SIZE (UIP_BUFSIZE - UIP_IPTCPH_LEN)
|
||||
|
||||
#define UIP_PROTO_ICMP 1
|
||||
#define UIP_PROTO_TCP 6
|
||||
|
@ -1898,7 +1759,6 @@ struct uip_udp_hdr {
|
|||
#define UIP_PROTO_ICMP6 58
|
||||
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/** @{ */
|
||||
/** \brief extension headers types */
|
||||
#define UIP_PROTO_HBHO 0
|
||||
|
@ -1908,7 +1768,7 @@ struct uip_udp_hdr {
|
|||
#define UIP_PROTO_NONE 59
|
||||
/** @} */
|
||||
|
||||
#define uip_is_proto_ext_hdr(proto) (proto == UIP_PROTO_HBHO || proto == UIP_PROTO_DESTO || proto == UIP_PROTO_ROUTING || proto == UIP_PROTO_FRAG || proto == UIP_PROTO_NONE)
|
||||
#define uip_is_proto_ext_hdr(proto) ((proto) != UIP_PROTO_TCP && (proto) != UIP_PROTO_UDP && (proto) != UIP_PROTO_ICMP6)
|
||||
|
||||
/** @{ */
|
||||
/** \brief Destination and Hop By Hop extension headers option types */
|
||||
|
@ -1937,9 +1797,6 @@ struct uip_udp_hdr {
|
|||
/** @} */
|
||||
|
||||
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
|
||||
#if UIP_FIXEDADDR
|
||||
extern const uip_ipaddr_t uip_hostaddr, uip_netmask, uip_draddr;
|
||||
#else /* UIP_FIXEDADDR */
|
||||
|
@ -1954,10 +1811,6 @@ extern const uip_lladdr_t uip_lladdr;
|
|||
extern uip_lladdr_t uip_lladdr;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
/** Length of the link local prefix */
|
||||
#define UIP_LLPREF_LEN 10
|
||||
|
||||
|
@ -2174,8 +2027,6 @@ extern uip_lladdr_t uip_lladdr;
|
|||
(((a)->u8[14]) == ((b)->u8[14])) && \
|
||||
(((a)->u8[15]) == ((b)->u8[15])))
|
||||
|
||||
#endif /*NETSTACK_CONF_WITH_IPV6*/
|
||||
|
||||
/**
|
||||
* A non-error message that indicates that a packet should be
|
||||
* processed locally.
|
||||
|
@ -2288,6 +2139,11 @@ uint16_t uip_udpchksum(void);
|
|||
*/
|
||||
uint16_t uip_icmp6chksum(void);
|
||||
|
||||
/**
|
||||
* Removes all IPv6 extension headers from uip_buf, updates length fields
|
||||
* (uip_len and uip_ext_len)
|
||||
*/
|
||||
void uip_remove_ext_hdr(void);
|
||||
|
||||
#endif /* UIP_H_ */
|
||||
|
||||
|
|
|
@ -114,46 +114,26 @@ uip_lladdr_t uip_lladdr = {{0x00,0x06,0x98,0x00,0x02,0x32}};
|
|||
* @{
|
||||
*/
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Type of the next header in IPv6 header or extension headers
|
||||
*
|
||||
* Can be the next header field in the IPv6 header or in an extension header.
|
||||
* When doing fragment reassembly, we must change the value of the next header
|
||||
* field in the header before the fragmentation header, hence we need a pointer
|
||||
* to this field.
|
||||
*/
|
||||
uint8_t *uip_next_hdr;
|
||||
/** \brief bitmap we use to record which IPv6 headers we have already seen */
|
||||
uint8_t uip_ext_bitmap = 0;
|
||||
/**
|
||||
* \brief length of the extension headers read. updated each time we process
|
||||
* a header
|
||||
* \brief Total length of all IPv6 extension headers
|
||||
*/
|
||||
uint8_t uip_ext_len = 0;
|
||||
/** \brief length of the header options read */
|
||||
uint8_t uip_ext_opt_offset = 0;
|
||||
/** \brief The final protocol after IPv6 extension headers:
|
||||
* UIP_PROTO_TCP, UIP_PROTO_UDP or UIP_PROTO_ICMP6 */
|
||||
uint8_t uip_last_proto = 0;
|
||||
/** @} */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Buffers */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \name Buffer defines
|
||||
* \name Reassembly buffer definition
|
||||
* @{
|
||||
*/
|
||||
#define FBUF ((struct uip_tcpip_hdr *)&uip_reassbuf[0])
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#define UIP_TCP_BUF ((struct uip_tcp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ROUTING_BUF ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_FRAG_BUF ((struct uip_frag_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_DESTO_BUF ((struct uip_desto_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_ICMP6_ERROR_BUF ((struct uip_icmp6_error *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
#define FBUF ((struct uip_ip_hdr *)&uip_reassbuf[0])
|
||||
|
||||
/** @} */
|
||||
/**
|
||||
* \name Buffer variables
|
||||
|
@ -341,7 +321,7 @@ uip_ipchksum(void)
|
|||
{
|
||||
uint16_t sum;
|
||||
|
||||
sum = chksum(0, &uip_buf[UIP_LLH_LEN], UIP_IPH_LEN);
|
||||
sum = chksum(0, uip_buf, UIP_IPH_LEN);
|
||||
LOG_DBG("uip_ipchksum: sum 0x%04x\n", sum);
|
||||
return (sum == 0) ? 0xffff : uip_htons(sum);
|
||||
}
|
||||
|
@ -362,10 +342,10 @@ upper_layer_chksum(uint8_t proto)
|
|||
volatile uint16_t upper_layer_len;
|
||||
uint16_t sum;
|
||||
|
||||
upper_layer_len = (((uint16_t)(UIP_IP_BUF->len[0]) << 8) + UIP_IP_BUF->len[1] - uip_ext_len);
|
||||
upper_layer_len = uipbuf_get_len_field(UIP_IP_BUF) - uip_ext_len;
|
||||
|
||||
LOG_DBG("Upper layer checksum len: %d from: %d\n", upper_layer_len,
|
||||
UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len);
|
||||
(int)(UIP_IP_PAYLOAD(uip_ext_len) - uip_buf));
|
||||
|
||||
/* First sum pseudoheader. */
|
||||
/* IP protocol and length fields. This addition cannot carry. */
|
||||
|
@ -373,9 +353,8 @@ upper_layer_chksum(uint8_t proto)
|
|||
/* Sum IP source and destination addresses. */
|
||||
sum = chksum(sum, (uint8_t *)&UIP_IP_BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
|
||||
|
||||
/* Sum TCP header and data. */
|
||||
sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN + uip_ext_len],
|
||||
upper_layer_len);
|
||||
/* Sum upper-layer header and data. */
|
||||
sum = chksum(sum, UIP_IP_PAYLOAD(uip_ext_len), upper_layer_len);
|
||||
|
||||
return (sum == 0) ? 0xffff : uip_htons(sum);
|
||||
}
|
||||
|
@ -510,29 +489,27 @@ uip_connect(const uip_ipaddr_t *ripaddr, uint16_t rport)
|
|||
#endif /* UIP_TCP && UIP_ACTIVE_OPEN */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
remove_ext_hdr(void)
|
||||
uip_remove_ext_hdr(void)
|
||||
{
|
||||
int last_uip_ext_len;
|
||||
/* Remove ext header before TCP/UDP processing. */
|
||||
if(uip_ext_len > 0) {
|
||||
LOG_DBG("Cutting ext-header before processing (extlen: %d, uiplen: %d)\n",
|
||||
LOG_DBG("Removing IPv6 extension headers (extlen: %d, uiplen: %d)\n",
|
||||
uip_ext_len, uip_len);
|
||||
if(uip_len < UIP_IPH_LEN + uip_ext_len) {
|
||||
LOG_ERR("ERROR: uip_len too short compared to ext len\n");
|
||||
uip_clear_buf();
|
||||
LOG_ERR("uip_len too short compared to ext len\n");
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
UIP_IP_BUF->proto = UIP_EXT_BUF->next;
|
||||
memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + last_uip_ext_len,
|
||||
uip_len - UIP_IPH_LEN - last_uip_ext_len);
|
||||
|
||||
uip_len -= last_uip_ext_len;
|
||||
/* Set proto */
|
||||
UIP_IP_BUF->proto = uip_last_proto;
|
||||
/* Move IP payload to the "left"*/
|
||||
memmove(UIP_IP_PAYLOAD(0), UIP_IP_PAYLOAD(uip_ext_len),
|
||||
uip_len - UIP_IPH_LEN - uip_ext_len);
|
||||
|
||||
/* Update the IP length. */
|
||||
UIP_IP_BUF->len[0] = (uip_len - UIP_IPH_LEN) >> 8;
|
||||
UIP_IP_BUF->len[1] = (uip_len - UIP_IPH_LEN) & 0xff;
|
||||
uipbuf_add_ext_hdr(-uip_ext_len);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -610,7 +587,7 @@ uip_listen(uint16_t port)
|
|||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#if UIP_CONF_IPV6_REASSEMBLY
|
||||
#define UIP_REASS_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN)
|
||||
#define UIP_REASS_BUFSIZE (UIP_BUFSIZE)
|
||||
|
||||
static uint8_t uip_reassbuf[UIP_REASS_BUFSIZE];
|
||||
|
||||
|
@ -646,11 +623,12 @@ static uint32_t uip_id; /* For every packet that is to be fragmented, the source
|
|||
#define IP_MF 0x0001
|
||||
|
||||
static uint16_t
|
||||
uip_reass(void)
|
||||
uip_reass(uint8_t *prev_proto_ptr)
|
||||
{
|
||||
uint16_t offset=0;
|
||||
uint16_t len;
|
||||
uint16_t i;
|
||||
struct uip_frag_hdr *frag_buf = (struct uip_frag_hdr *)UIP_IP_PAYLOAD(uip_ext_len);
|
||||
|
||||
/* If ip_reasstmr is zero, no packet is present in the buffer */
|
||||
/* We first write the unfragmentable part of IP header into the reassembly
|
||||
|
@ -662,7 +640,7 @@ uip_reass(void)
|
|||
etimer_set(&uip_reass_timer, UIP_REASS_MAXAGE*CLOCK_SECOND);
|
||||
uip_reass_on = 1;
|
||||
uip_reassflags = 0;
|
||||
uip_id = UIP_FRAG_BUF->id;
|
||||
uip_id = frag_buf->id;
|
||||
/* Clear the bitmap. */
|
||||
memset(uip_reassbitmap, 0, sizeof(uip_reassbitmap));
|
||||
}
|
||||
|
@ -673,9 +651,9 @@ uip_reass(void)
|
|||
*/
|
||||
if(uip_ipaddr_cmp(&FBUF->srcipaddr, &UIP_IP_BUF->srcipaddr) &&
|
||||
uip_ipaddr_cmp(&FBUF->destipaddr, &UIP_IP_BUF->destipaddr) &&
|
||||
UIP_FRAG_BUF->id == uip_id) {
|
||||
frag_buf->id == uip_id) {
|
||||
len = uip_len - uip_ext_len - UIP_IPH_LEN - UIP_FRAGH_LEN;
|
||||
offset = (uip_ntohs(UIP_FRAG_BUF->offsetresmore) & 0xfff8);
|
||||
offset = (uip_ntohs(frag_buf->offsetresmore) & 0xfff8);
|
||||
/* in byte, originaly in multiple of 8 bytes*/
|
||||
LOG_INFO("len %d\n", len);
|
||||
LOG_INFO("offset %d\n", offset);
|
||||
|
@ -686,7 +664,7 @@ uip_reass(void)
|
|||
* Part is obtained from the Next Header field of the first
|
||||
* fragment's Fragment header.
|
||||
*/
|
||||
*uip_next_hdr = UIP_FRAG_BUF->next;
|
||||
*prev_proto_ptr = frag_buf->next;
|
||||
memcpy(FBUF, UIP_IP_BUF, uip_ext_len + UIP_IPH_LEN);
|
||||
LOG_INFO("src ");
|
||||
LOG_INFO_6ADDR(&FBUF->srcipaddr);
|
||||
|
@ -707,7 +685,7 @@ uip_reass(void)
|
|||
|
||||
/* If this fragment has the More Fragments flag set to zero, it is the
|
||||
last fragment*/
|
||||
if((uip_ntohs(UIP_FRAG_BUF->offsetresmore) & IP_MF) == 0) {
|
||||
if((uip_ntohs(frag_buf->offsetresmore) & IP_MF) == 0) {
|
||||
uip_reassflags |= UIP_REASS_FLAG_LASTFRAG;
|
||||
/*calculate the size of the entire packet*/
|
||||
uip_reasslen = offset + len;
|
||||
|
@ -731,7 +709,7 @@ uip_reass(void)
|
|||
/* Copy the fragment into the reassembly buffer, at the right
|
||||
offset. */
|
||||
memcpy((uint8_t *)FBUF + UIP_IPH_LEN + uip_ext_len + offset,
|
||||
(uint8_t *)UIP_FRAG_BUF + UIP_FRAGH_LEN, len);
|
||||
(uint8_t *)frag_buf + UIP_FRAGH_LEN, len);
|
||||
|
||||
/* Update the bitmap. */
|
||||
if(offset >> 6 == (offset + len) >> 6) {
|
||||
|
@ -777,10 +755,8 @@ uip_reass(void)
|
|||
|
||||
uip_reasslen += UIP_IPH_LEN + uip_ext_len;
|
||||
memcpy(UIP_IP_BUF, FBUF, uip_reasslen);
|
||||
UIP_IP_BUF->len[0] = ((uip_reasslen - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_reasslen - UIP_IPH_LEN) & 0xff);
|
||||
LOG_INFO("reassembled packet %d (%d)\n", uip_reasslen,
|
||||
(UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_reasslen - UIP_IPH_LEN);
|
||||
LOG_INFO("reassembled packet %d (%d)\n", uip_reasslen, uipbuf_get_len_field(UIP_IP_BUF));
|
||||
|
||||
return uip_reasslen;
|
||||
|
||||
|
@ -810,7 +786,7 @@ uip_reass_over(void)
|
|||
* any RFC, we decided not to include it as it reduces the size of
|
||||
* the packet.
|
||||
*/
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
memcpy(UIP_IP_BUF, FBUF, UIP_IPH_LEN); /* copy the header for src
|
||||
and dest address*/
|
||||
uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY, 0);
|
||||
|
@ -840,16 +816,29 @@ uip_add_rcv_nxt(uint16_t n)
|
|||
* \brief Process the options in Destination and Hop By Hop extension headers
|
||||
*/
|
||||
static uint8_t
|
||||
ext_hdr_options_process(void)
|
||||
ext_hdr_options_process(uint8_t *ext_buf)
|
||||
{
|
||||
/*
|
||||
* Length field in the extension header: length of the header in units of
|
||||
* 8 bytes, excluding the first 8 bytes
|
||||
* length field in an option : the length of data in the option
|
||||
*/
|
||||
uip_ext_opt_offset = 2;
|
||||
while(uip_ext_opt_offset < ((UIP_EXT_BUF->len << 3) + 8)) {
|
||||
switch(UIP_EXT_HDR_OPT_BUF->type) {
|
||||
uint8_t opt_offset = 2; /* 2 first bytes in ext header */
|
||||
struct uip_hbho_hdr *ext_hdr = (struct uip_hbho_hdr *)ext_buf;
|
||||
uint8_t ext_hdr_len = (ext_hdr->len << 3) + 8;
|
||||
|
||||
while(opt_offset + 2 <= ext_hdr_len) { /* + 2 for opt header */
|
||||
struct uip_ext_hdr_opt *opt_hdr = (struct uip_ext_hdr_opt *)(ext_buf + opt_offset);
|
||||
uint8_t opt_len = opt_hdr->len + 2;
|
||||
|
||||
if(opt_offset + opt_len > ext_hdr_len) {
|
||||
LOG_ERR("RPL Option too long: Dropping Packet\n");
|
||||
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION,
|
||||
(ext_buf + opt_offset) - uip_buf);
|
||||
return 2;
|
||||
}
|
||||
|
||||
switch(opt_hdr->type) {
|
||||
/*
|
||||
* for now we do not support any options except padding ones
|
||||
* PAD1 does not make sense as the header must be 8bytes aligned,
|
||||
|
@ -857,11 +846,11 @@ ext_hdr_options_process(void)
|
|||
*/
|
||||
case UIP_EXT_HDR_OPT_PAD1:
|
||||
LOG_DBG("Processing PAD1 option\n");
|
||||
uip_ext_opt_offset += 1;
|
||||
opt_offset += 1;
|
||||
break;
|
||||
case UIP_EXT_HDR_OPT_PADN:
|
||||
LOG_DBG("Processing PADN option\n");
|
||||
uip_ext_opt_offset += UIP_EXT_HDR_OPT_PADN_BUF->opt_len + 2;
|
||||
opt_offset += opt_len;
|
||||
break;
|
||||
case UIP_EXT_HDR_OPT_RPL:
|
||||
/* Fixes situation when a node that is not using RPL
|
||||
|
@ -872,12 +861,13 @@ ext_hdr_options_process(void)
|
|||
* Using this fix, the header is ignored, and the next header (if
|
||||
* present) is processed.
|
||||
*/
|
||||
if(!NETSTACK_ROUTING.ext_header_hbh_update(uip_ext_opt_offset)) {
|
||||
LOG_DBG("Processing RPL option\n");
|
||||
if(!NETSTACK_ROUTING.ext_header_hbh_update(ext_buf, opt_offset)) {
|
||||
LOG_ERR("RPL Option Error: Dropping Packet\n");
|
||||
return 1;
|
||||
}
|
||||
uip_ext_opt_offset += (UIP_EXT_HDR_OPT_BUF->len) + 2;
|
||||
return 0;
|
||||
opt_offset += opt_len;
|
||||
break;
|
||||
default:
|
||||
/*
|
||||
* check the two highest order bits of the option
|
||||
|
@ -892,8 +882,8 @@ ext_hdr_options_process(void)
|
|||
* Problem, Code 2, message to the packet's Source Address,
|
||||
* pointing to the unrecognized Option Type.
|
||||
*/
|
||||
LOG_DBG("MSB %x\n", UIP_EXT_HDR_OPT_BUF->type);
|
||||
switch(UIP_EXT_HDR_OPT_BUF->type & 0xC0) {
|
||||
LOG_DBG("Unrecognized option, MSB 0x%x\n", opt_hdr->type);
|
||||
switch(opt_hdr->type & 0xC0) {
|
||||
case 0:
|
||||
break;
|
||||
case 0x40:
|
||||
|
@ -904,22 +894,49 @@ ext_hdr_options_process(void)
|
|||
}
|
||||
case 0x80:
|
||||
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_OPTION,
|
||||
(uint32_t)UIP_IPH_LEN + uip_ext_len + uip_ext_opt_offset);
|
||||
(ext_buf + opt_offset) - uip_buf);
|
||||
return 2;
|
||||
}
|
||||
/* in the cases were we did not discard, update ext_opt* */
|
||||
uip_ext_opt_offset += UIP_EXT_HDR_OPT_BUF->len + 2;
|
||||
opt_offset += opt_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static bool
|
||||
uip_check_mtu(void)
|
||||
{
|
||||
if(uip_len > UIP_LINK_MTU) {
|
||||
uip_icmp6_error_output(ICMP6_PACKET_TOO_BIG, 0, UIP_LINK_MTU);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static bool
|
||||
uip_update_ttl(void)
|
||||
{
|
||||
if(UIP_IP_BUF->ttl <= 1) {
|
||||
uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_TRANSIT, 0);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
return false;
|
||||
} else {
|
||||
UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_process(uint8_t flag)
|
||||
{
|
||||
uint8_t *last_header;
|
||||
uint8_t protocol;
|
||||
uint8_t *next_header;
|
||||
struct uip_ext_hdr *ext_ptr;
|
||||
#if UIP_TCP
|
||||
int c;
|
||||
uint16_t tmp16;
|
||||
|
@ -931,7 +948,7 @@ uip_process(uint8_t flag)
|
|||
goto udp_send;
|
||||
}
|
||||
#endif /* UIP_UDP */
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN];
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPTCPH_LEN];
|
||||
|
||||
/* Check if we were invoked because of a poll request for a
|
||||
particular connection. */
|
||||
|
@ -955,7 +972,7 @@ uip_process(uint8_t flag)
|
|||
} else if(flag == UIP_TIMER) {
|
||||
/* Reset the length variables. */
|
||||
#if UIP_TCP
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
uip_slen = 0;
|
||||
|
||||
/* Increase the initial sequence number. */
|
||||
|
@ -1068,7 +1085,7 @@ uip_process(uint8_t flag)
|
|||
if(flag == UIP_UDP_TIMER) {
|
||||
if(uip_udp_conn->lport != 0) {
|
||||
uip_conn = NULL;
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
|
||||
uip_len = uip_slen = 0;
|
||||
uip_flags = UIP_POLL;
|
||||
UIP_UDP_APPCALL();
|
||||
|
@ -1101,8 +1118,8 @@ uip_process(uint8_t flag)
|
|||
* value..
|
||||
*/
|
||||
|
||||
if((UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] <= uip_len) {
|
||||
uip_len = (UIP_IP_BUF->len[0] << 8) + UIP_IP_BUF->len[1] + UIP_IPH_LEN;
|
||||
if(uipbuf_get_len_field(UIP_IP_BUF) <= uip_len) {
|
||||
uip_len = uipbuf_get_len_field(UIP_IP_BUF) + UIP_IPH_LEN;
|
||||
/*
|
||||
* The length reported in the IPv6 header is the
|
||||
* length of the payload that follows the
|
||||
|
@ -1115,10 +1132,21 @@ uip_process(uint8_t flag)
|
|||
* header (40 bytes).
|
||||
*/
|
||||
} else {
|
||||
LOG_ERR("packet shorter than reported in IP header.");
|
||||
LOG_ERR("packet shorter than reported in IP header\n");
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/* Check sanity of extension headers, and compute the total extension header
|
||||
* length (uip_ext_len) as well as the final protocol (uip_last_proto) */
|
||||
uip_last_proto = 0;
|
||||
last_header = uipbuf_get_last_header(uip_buf, uip_len, &uip_last_proto);
|
||||
if(last_header == NULL) {
|
||||
LOG_ERR("invalid extension header chain\n");
|
||||
goto drop;
|
||||
}
|
||||
/* Set uip_ext_len */
|
||||
uip_ext_len = last_header - UIP_IP_PAYLOAD(0);
|
||||
|
||||
LOG_INFO("packet received from ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->srcipaddr);
|
||||
LOG_INFO_(" to ");
|
||||
|
@ -1140,32 +1168,20 @@ uip_process(uint8_t flag)
|
|||
|
||||
#if UIP_CONF_ROUTER
|
||||
/*
|
||||
* Next header field processing. In IPv6, we can have extension headers,
|
||||
* if present, the Hop-by-Hop Option must be processed before forwarding
|
||||
* If present, the Hop-by-Hop Option must be processed before forwarding
|
||||
* the packet.
|
||||
*/
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_bitmap = 0;
|
||||
if(*uip_next_hdr == UIP_PROTO_HBHO) {
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO;
|
||||
#endif /* UIP_CONF_IPV6_CHECKS */
|
||||
switch(ext_hdr_options_process()) {
|
||||
|
||||
next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
|
||||
if(next_header != NULL && protocol == UIP_PROTO_HBHO) {
|
||||
switch(ext_hdr_options_process(next_header)) {
|
||||
case 0:
|
||||
/* continue */
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
break; /* done */
|
||||
case 1:
|
||||
LOG_ERR("Dropping packet after extension header processing\n");
|
||||
/* silently discard */
|
||||
goto drop;
|
||||
goto drop; /* silently discard */
|
||||
case 2:
|
||||
LOG_ERR("Sending error message after extension header processing\n");
|
||||
/* send icmp error message (created in ext_hdr_options_process)
|
||||
* and discard*/
|
||||
goto send;
|
||||
goto send; /* send icmp error message (created in
|
||||
ext_hdr_options_process) and discard */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1201,23 +1217,12 @@ uip_process(uint8_t flag)
|
|||
!uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr) &&
|
||||
!uip_is_addr_loopback(&UIP_IP_BUF->destipaddr)) {
|
||||
|
||||
|
||||
/* Check MTU */
|
||||
if(uip_len > UIP_LINK_MTU) {
|
||||
uip_icmp6_error_output(ICMP6_PACKET_TOO_BIG, 0, UIP_LINK_MTU);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
goto send;
|
||||
}
|
||||
/* Check Hop Limit */
|
||||
if(UIP_IP_BUF->ttl <= 1) {
|
||||
uip_icmp6_error_output(ICMP6_TIME_EXCEEDED,
|
||||
ICMP6_TIME_EXCEED_TRANSIT, 0);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
if(!uip_check_mtu() || !uip_update_ttl()) {
|
||||
/* Send ICMPv6 error, prepared by the function that just returned false */
|
||||
goto send;
|
||||
}
|
||||
|
||||
UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
|
||||
LOG_INFO("Forwarding packet towards ");
|
||||
LOG_INFO("Forwarding packet to next hop ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
UIP_STAT(++uip_stat.ip.forwarded);
|
||||
|
@ -1246,35 +1251,20 @@ uip_process(uint8_t flag)
|
|||
UIP_STAT(++uip_stat.ip.drop);
|
||||
goto drop;
|
||||
}
|
||||
|
||||
/*
|
||||
* Next header field processing. In IPv6, we can have extension headers,
|
||||
* they are processed here
|
||||
*/
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_bitmap = 0;
|
||||
#endif /* UIP_CONF_ROUTER */
|
||||
|
||||
#if UIP_IPV6_MULTICAST && UIP_CONF_ROUTER
|
||||
process:
|
||||
#endif /* UIP_IPV6_MULTICAST && UIP_CONF_ROUTER */
|
||||
|
||||
while(1) {
|
||||
switch(*uip_next_hdr){
|
||||
#if UIP_TCP
|
||||
case UIP_PROTO_TCP:
|
||||
/* TCP, for both IPv4 and IPv6 */
|
||||
goto tcp_input;
|
||||
#endif /* UIP_TCP */
|
||||
#if UIP_UDP
|
||||
case UIP_PROTO_UDP:
|
||||
/* UDP, for both IPv4 and IPv6 */
|
||||
goto udp_input;
|
||||
#endif /* UIP_UDP */
|
||||
case UIP_PROTO_ICMP6:
|
||||
/* ICMPv6 */
|
||||
goto icmp6_input;
|
||||
/* IPv6 extension header processing: loop until reaching upper-layer protocol */
|
||||
uip_ext_bitmap = 0;
|
||||
for(next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
|
||||
next_header != NULL && uip_is_proto_ext_hdr(protocol);
|
||||
next_header = uipbuf_get_next_header(next_header, uip_len - (next_header - uip_buf), &protocol, false)) {
|
||||
|
||||
ext_ptr = (struct uip_ext_hdr *)next_header;
|
||||
switch(protocol) {
|
||||
case UIP_PROTO_HBHO:
|
||||
LOG_DBG("Processing hbh header\n");
|
||||
/* Hop by hop option header */
|
||||
|
@ -1286,145 +1276,140 @@ uip_process(uint8_t flag)
|
|||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_HBHO;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS*/
|
||||
switch(ext_hdr_options_process()) {
|
||||
switch(ext_hdr_options_process(next_header)) {
|
||||
case 0:
|
||||
/*continue*/
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
break; /* done */
|
||||
case 1:
|
||||
/*silently discard*/
|
||||
goto drop;
|
||||
goto drop; /* silently discard */
|
||||
case 2:
|
||||
/* send icmp error message (created in ext_hdr_options_process)
|
||||
* and discard*/
|
||||
goto send;
|
||||
goto send; /* send icmp error message (created in
|
||||
ext_hdr_options_process) and discard */
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_DESTO:
|
||||
case UIP_PROTO_DESTO:
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
/* Destination option header. if we saw two already, drop */
|
||||
LOG_DBG("Processing desto header\n");
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO1) {
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO2) {
|
||||
goto bad_hdr;
|
||||
} else{
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO2;
|
||||
}
|
||||
} else {
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO1;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS*/
|
||||
switch(ext_hdr_options_process()) {
|
||||
case 0:
|
||||
/*continue*/
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
case 1:
|
||||
/*silently discard*/
|
||||
goto drop;
|
||||
case 2:
|
||||
/* send icmp error message (created in ext_hdr_options_process)
|
||||
* and discard*/
|
||||
goto send;
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_ROUTING:
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
/* Routing header. If we saw one already, drop */
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) {
|
||||
goto bad_hdr;
|
||||
} else {
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS*/
|
||||
/*
|
||||
* Routing Header length field is in units of 8 bytes, excluding
|
||||
* As per RFC2460 section 4.4, if routing type is unrecognized:
|
||||
* if segments left = 0, ignore the header
|
||||
* if segments left > 0, discard packet and send icmp error pointing
|
||||
* to the routing type
|
||||
*/
|
||||
|
||||
LOG_DBG("Processing Routing header\n");
|
||||
if(UIP_ROUTING_BUF->seg_left > 0) {
|
||||
if(NETSTACK_ROUTING.ext_header_srh_update()) {
|
||||
|
||||
/* With routing header, the detination address is us and will
|
||||
* be swapped later to the next hop. Because of this, the MTU
|
||||
* and TTL were not checked and updated yet. Do this now. */
|
||||
|
||||
/* Check MTU */
|
||||
if(uip_len > UIP_LINK_MTU) {
|
||||
uip_icmp6_error_output(ICMP6_PACKET_TOO_BIG, 0, UIP_LINK_MTU);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
goto send;
|
||||
}
|
||||
/* Check Hop Limit */
|
||||
if(UIP_IP_BUF->ttl <= 1) {
|
||||
uip_icmp6_error_output(ICMP6_TIME_EXCEEDED,
|
||||
ICMP6_TIME_EXCEED_TRANSIT, 0);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
goto send;
|
||||
}
|
||||
UIP_IP_BUF->ttl = UIP_IP_BUF->ttl - 1;
|
||||
|
||||
LOG_INFO("Forwarding packet to next hop ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
UIP_STAT(++uip_stat.ip.forwarded);
|
||||
|
||||
goto send; /* Proceed to forwarding */
|
||||
}
|
||||
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER, UIP_IPH_LEN + uip_ext_len + 2);
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
LOG_ERR("unrecognized routing type");
|
||||
goto send;
|
||||
}
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
case UIP_PROTO_FRAG:
|
||||
/* Fragmentation header:call the reassembly function, then leave */
|
||||
#if UIP_CONF_IPV6_REASSEMBLY
|
||||
LOG_INFO("Processing fragmentation header\n");
|
||||
uip_len = uip_reass();
|
||||
if(uip_len == 0) {
|
||||
goto drop;
|
||||
}
|
||||
if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG){
|
||||
/* we are not done with reassembly, this is an error message */
|
||||
goto send;
|
||||
}
|
||||
/*packet is reassembled, reset the next hdr to the beginning
|
||||
of the IP header and restart the parsing of the reassembled pkt*/
|
||||
LOG_INFO("Processing reassembled packet\n");
|
||||
uip_ext_len = 0;
|
||||
uip_ext_bitmap = 0;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
break;
|
||||
#else /* UIP_CONF_IPV6_REASSEMBLY */
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
UIP_STAT(++uip_stat.ip.fragerr);
|
||||
LOG_ERR("fragment dropped.");
|
||||
goto drop;
|
||||
#endif /* UIP_CONF_IPV6_REASSEMBLY */
|
||||
case UIP_PROTO_NONE:
|
||||
goto drop;
|
||||
default:
|
||||
/* Destination option header. if we saw two already, drop */
|
||||
LOG_DBG("Processing desto header\n");
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO1) {
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_DESTO2) {
|
||||
goto bad_hdr;
|
||||
} else{
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO2;
|
||||
}
|
||||
} else {
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_DESTO1;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS*/
|
||||
switch(ext_hdr_options_process(next_header)) {
|
||||
case 0:
|
||||
break; /* done */
|
||||
case 1:
|
||||
goto drop; /* silently discard */
|
||||
case 2:
|
||||
goto send; /* send icmp error message (created in
|
||||
ext_hdr_options_process) and discard */
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_ROUTING:
|
||||
#if UIP_CONF_IPV6_CHECKS
|
||||
/* Routing header. If we saw one already, drop */
|
||||
if(uip_ext_bitmap & UIP_EXT_HDR_BITMAP_ROUTING) {
|
||||
goto bad_hdr;
|
||||
} else {
|
||||
uip_ext_bitmap |= UIP_EXT_HDR_BITMAP_ROUTING;
|
||||
}
|
||||
#endif /*UIP_CONF_IPV6_CHECKS*/
|
||||
/*
|
||||
* Routing Header length field is in units of 8 bytes, excluding
|
||||
* As per RFC2460 section 4.4, if routing type is unrecognized:
|
||||
* if segments left = 0, ignore the header
|
||||
* if segments left > 0, discard packet and send icmp error pointing
|
||||
* to the routing type
|
||||
*/
|
||||
|
||||
LOG_DBG("Processing Routing header\n");
|
||||
if(((struct uip_routing_hdr *)ext_ptr)->seg_left > 0) {
|
||||
/* Process source routing header */
|
||||
if(NETSTACK_ROUTING.ext_header_srh_update()) {
|
||||
|
||||
/* The MTU and TTL were not checked and updated yet, because with
|
||||
* a routing header, the IPv6 destination address was set to us
|
||||
* even though we act only as forwarder. Check MTU and TTL now */
|
||||
if(!uip_check_mtu() || !uip_update_ttl()) {
|
||||
/* Send ICMPv6 error, prepared by the function that just returned false */
|
||||
goto send;
|
||||
}
|
||||
|
||||
LOG_INFO("Forwarding packet to next hop ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
UIP_STAT(++uip_stat.ip.forwarded);
|
||||
|
||||
goto send; /* Proceed to forwarding */
|
||||
} else {
|
||||
LOG_ERR("Unrecognized routing type\n");
|
||||
goto bad_hdr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_FRAG:
|
||||
/* Fragmentation header:call the reassembly function, then leave */
|
||||
#if UIP_CONF_IPV6_REASSEMBLY
|
||||
LOG_INFO("Processing fragmentation header\n");
|
||||
uip_len = uip_reass(&ext_ptr->next);
|
||||
if(uip_len == 0) {
|
||||
goto drop;
|
||||
}
|
||||
if(uip_reassflags & UIP_REASS_FLAG_ERROR_MSG) {
|
||||
/* we are not done with reassembly, this is an error message */
|
||||
goto send;
|
||||
}
|
||||
/* packet is reassembled. Restart the parsing of the reassembled pkt */
|
||||
LOG_INFO("Processing reassembled packet\n");
|
||||
uip_ext_bitmap = 0;
|
||||
next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
|
||||
break;
|
||||
#else /* UIP_CONF_IPV6_REASSEMBLY */
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
UIP_STAT(++uip_stat.ip.fragerr);
|
||||
LOG_ERR("fragment dropped.");
|
||||
goto drop;
|
||||
#endif /* UIP_CONF_IPV6_REASSEMBLY */
|
||||
case UIP_PROTO_NONE:
|
||||
goto drop;
|
||||
default:
|
||||
goto bad_hdr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Process upper-layer input */
|
||||
if(next_header != NULL) {
|
||||
switch(protocol) {
|
||||
#if UIP_TCP
|
||||
case UIP_PROTO_TCP:
|
||||
/* TCP, for both IPv4 and IPv6 */
|
||||
goto tcp_input;
|
||||
#endif
|
||||
#if UIP_UDP
|
||||
case UIP_PROTO_UDP:
|
||||
/* UDP, for both IPv4 and IPv6 */
|
||||
goto udp_input;
|
||||
#endif
|
||||
case UIP_PROTO_ICMP6:
|
||||
/* ICMPv6 */
|
||||
goto icmp6_input;
|
||||
}
|
||||
}
|
||||
|
||||
bad_hdr:
|
||||
/*
|
||||
* RFC 2460 send error message parameterr problem, code unrecognized
|
||||
* next header, pointing to the next header field
|
||||
*/
|
||||
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, (uint32_t)(uip_next_hdr - (uint8_t *)UIP_IP_BUF));
|
||||
uip_icmp6_error_output(ICMP6_PARAM_PROB, ICMP6_PARAMPROB_NEXTHEADER, (uint32_t)(next_header - uip_buf));
|
||||
UIP_STAT(++uip_stat.ip.drop);
|
||||
UIP_STAT(++uip_stat.ip.protoerr);
|
||||
LOG_ERR("unrecognized header");
|
||||
LOG_ERR("unrecognized header\n");
|
||||
goto send;
|
||||
/* End of headers processing */
|
||||
|
||||
|
@ -1465,7 +1450,7 @@ uip_process(uint8_t flag)
|
|||
LOG_ERR("Unknown ICMPv6 message type/code %d\n", UIP_ICMP_BUF->type);
|
||||
UIP_STAT(++uip_stat.icmp.drop);
|
||||
UIP_STAT(++uip_stat.icmp.typeerr);
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
|
||||
if(uip_len > 0) {
|
||||
|
@ -1480,7 +1465,7 @@ uip_process(uint8_t flag)
|
|||
/* UDP input processing. */
|
||||
udp_input:
|
||||
|
||||
remove_ext_hdr();
|
||||
uip_remove_ext_hdr();
|
||||
|
||||
LOG_INFO("Receiving UDP packet\n");
|
||||
|
||||
|
@ -1540,10 +1525,10 @@ uip_process(uint8_t flag)
|
|||
UIP_STAT(++uip_stat.udp.recv);
|
||||
|
||||
uip_len = uip_len - UIP_IPUDPH_LEN;
|
||||
uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
|
||||
uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
|
||||
uip_conn = NULL;
|
||||
uip_flags = UIP_NEWDATA;
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN + UIP_LLH_LEN];
|
||||
uip_sappdata = uip_appdata = &uip_buf[UIP_IPUDPH_LEN];
|
||||
uip_slen = 0;
|
||||
UIP_UDP_APPCALL();
|
||||
|
||||
|
@ -1557,8 +1542,7 @@ uip_process(uint8_t flag)
|
|||
|
||||
/* For IPv6, the IP length field does not include the IPv6 IP header
|
||||
length. */
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
UIP_IP_BUF->vtc = 0x60;
|
||||
UIP_IP_BUF->tcflow = 0x00;
|
||||
|
@ -1574,7 +1558,7 @@ uip_process(uint8_t flag)
|
|||
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &uip_udp_conn->ripaddr);
|
||||
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
|
||||
|
||||
uip_appdata = &uip_buf[UIP_LLH_LEN + UIP_IPTCPH_LEN];
|
||||
uip_appdata = &uip_buf[UIP_IPTCPH_LEN];
|
||||
|
||||
#if UIP_UDP_CHECKSUMS
|
||||
/* Calculate UDP checksum. */
|
||||
|
@ -1592,7 +1576,7 @@ uip_process(uint8_t flag)
|
|||
/* TCP input processing. */
|
||||
tcp_input:
|
||||
|
||||
remove_ext_hdr();
|
||||
uip_remove_ext_hdr();
|
||||
|
||||
UIP_STAT(++uip_stat.tcp.recv);
|
||||
LOG_INFO("Receiving TCP packet\n");
|
||||
|
@ -1609,7 +1593,7 @@ uip_process(uint8_t flag)
|
|||
|
||||
/* Make sure that the TCP port number is not zero. */
|
||||
if(UIP_TCP_BUF->destport == 0 || UIP_TCP_BUF->srcport == 0) {
|
||||
LOG_ERR("tcp: zero port.");
|
||||
LOG_ERR("tcp: zero port\n");
|
||||
goto drop;
|
||||
}
|
||||
|
||||
|
@ -1726,7 +1710,7 @@ uip_process(uint8_t flag)
|
|||
the remote end will retransmit the packet at a time when we
|
||||
have more spare connections. */
|
||||
UIP_STAT(++uip_stat.tcp.syndrop);
|
||||
LOG_ERR("tcp: found no unused connections.");
|
||||
LOG_ERR("tcp: found no unused connections\n");
|
||||
goto drop;
|
||||
}
|
||||
uip_conn = uip_connr;
|
||||
|
@ -1757,7 +1741,7 @@ uip_process(uint8_t flag)
|
|||
/* Parse the TCP MSS option, if present. */
|
||||
if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
|
||||
for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
|
||||
opt = uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + c];
|
||||
opt = uip_buf[UIP_IPTCPH_LEN + c];
|
||||
if(opt == TCP_OPT_END) {
|
||||
/* End of options. */
|
||||
break;
|
||||
|
@ -1765,10 +1749,10 @@ uip_process(uint8_t flag)
|
|||
++c;
|
||||
/* NOP option. */
|
||||
} else if(opt == TCP_OPT_MSS &&
|
||||
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
|
||||
uip_buf[UIP_IPTCPH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
|
||||
/* An MSS option with the right option length. */
|
||||
tmp16 = ((uint16_t)uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
|
||||
(uint16_t)uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + 3 + c];
|
||||
tmp16 = ((uint16_t)uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
|
||||
(uint16_t)uip_buf[UIP_IPTCPH_LEN + 3 + c];
|
||||
uip_connr->initialmss = uip_connr->mss =
|
||||
tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
|
||||
|
||||
|
@ -1777,12 +1761,12 @@ uip_process(uint8_t flag)
|
|||
} else {
|
||||
/* All other options have a length field, so that we easily
|
||||
can skip past them. */
|
||||
if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
|
||||
if(uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
|
||||
/* If the length field is zero, the options are malformed
|
||||
and we don't process them further. */
|
||||
break;
|
||||
}
|
||||
c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
|
||||
c += uip_buf[UIP_IPTCPH_LEN + 1 + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1944,7 +1928,7 @@ uip_process(uint8_t flag)
|
|||
/* Parse the TCP MSS option, if present. */
|
||||
if((UIP_TCP_BUF->tcpoffset & 0xf0) > 0x50) {
|
||||
for(c = 0; c < ((UIP_TCP_BUF->tcpoffset >> 4) - 5) << 2 ;) {
|
||||
opt = uip_buf[UIP_IPTCPH_LEN + UIP_LLH_LEN + c];
|
||||
opt = uip_buf[UIP_IPTCPH_LEN + c];
|
||||
if(opt == TCP_OPT_END) {
|
||||
/* End of options. */
|
||||
break;
|
||||
|
@ -1952,10 +1936,10 @@ uip_process(uint8_t flag)
|
|||
++c;
|
||||
/* NOP option. */
|
||||
} else if(opt == TCP_OPT_MSS &&
|
||||
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
|
||||
uip_buf[UIP_IPTCPH_LEN + 1 + c] == TCP_OPT_MSS_LEN) {
|
||||
/* An MSS option with the right option length. */
|
||||
tmp16 = (uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 2 + c] << 8) |
|
||||
uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 3 + c];
|
||||
tmp16 = (uip_buf[UIP_IPTCPH_LEN + 2 + c] << 8) |
|
||||
uip_buf[UIP_IPTCPH_LEN + 3 + c];
|
||||
uip_connr->initialmss =
|
||||
uip_connr->mss = tmp16 > UIP_TCP_MSS? UIP_TCP_MSS: tmp16;
|
||||
|
||||
|
@ -1964,12 +1948,12 @@ uip_process(uint8_t flag)
|
|||
} else {
|
||||
/* All other options have a length field, so that we easily
|
||||
can skip past them. */
|
||||
if(uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c] == 0) {
|
||||
if(uip_buf[UIP_IPTCPH_LEN + 1 + c] == 0) {
|
||||
/* If the length field is zero, the options are malformed
|
||||
and we don't process them further. */
|
||||
break;
|
||||
}
|
||||
c += uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN + 1 + c];
|
||||
c += uip_buf[UIP_IPTCPH_LEN + 1 + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1981,7 +1965,7 @@ uip_process(uint8_t flag)
|
|||
uip_add_rcv_nxt(1);
|
||||
uip_flags = UIP_CONNECTED | UIP_NEWDATA;
|
||||
uip_connr->len = 0;
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
uip_slen = 0;
|
||||
UIP_APPCALL();
|
||||
goto appsend;
|
||||
|
@ -2083,7 +2067,7 @@ uip_process(uint8_t flag)
|
|||
When the application is called, the global variable uip_len
|
||||
contains the length of the incoming data. The application can
|
||||
access the incoming data through the global pointer
|
||||
uip_appdata, which usually points UIP_IPTCPH_LEN + UIP_LLH_LEN
|
||||
uip_appdata, which usually points UIP_IPTCPH_LEN
|
||||
bytes into the uip_buf array.
|
||||
|
||||
If the application wishes to send any data, this data should be
|
||||
|
@ -2152,7 +2136,7 @@ uip_process(uint8_t flag)
|
|||
packet had new data in it, we must send out a packet. */
|
||||
if(uip_slen > 0 && uip_connr->len > 0) {
|
||||
/* Add the length of the IP and TCP headers. */
|
||||
uip_len = uip_connr->len + UIP_TCPIP_HLEN;
|
||||
uip_len = uip_connr->len + UIP_IPTCPH_LEN;
|
||||
/* We always set the ACK flag in response packets. */
|
||||
UIP_TCP_BUF->flags = TCP_ACK | TCP_PSH;
|
||||
/* Send the packet. */
|
||||
|
@ -2161,7 +2145,7 @@ uip_process(uint8_t flag)
|
|||
/* If there is no data to send, just send out a pure ACK if
|
||||
there is newdata. */
|
||||
if(uip_flags & UIP_NEWDATA) {
|
||||
uip_len = UIP_TCPIP_HLEN;
|
||||
uip_len = UIP_IPTCPH_LEN;
|
||||
UIP_TCP_BUF->flags = TCP_ACK;
|
||||
goto tcp_send_noopts;
|
||||
}
|
||||
|
@ -2289,8 +2273,7 @@ uip_process(uint8_t flag)
|
|||
UIP_IP_BUF->proto = UIP_PROTO_TCP;
|
||||
|
||||
UIP_IP_BUF->ttl = uip_ds6_if.cur_hop_limit;
|
||||
UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
|
||||
UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
UIP_TCP_BUF->urgp[0] = UIP_TCP_BUF->urgp[1] = 0;
|
||||
|
||||
|
@ -2305,8 +2288,7 @@ uip_process(uint8_t flag)
|
|||
#endif
|
||||
UIP_IP_BUF->flow = 0x00;
|
||||
send:
|
||||
LOG_INFO("Sending packet with length %d (%d)\n", uip_len,
|
||||
(UIP_IP_BUF->len[0] << 8) | UIP_IP_BUF->len[1]);
|
||||
LOG_INFO("Sending packet with length %d (%d)\n", uip_len, uipbuf_get_len_field(UIP_IP_BUF));
|
||||
|
||||
UIP_STAT(++uip_stat.ip.sent);
|
||||
/* Return and let the caller do the actual transmission. */
|
||||
|
@ -2314,7 +2296,7 @@ uip_process(uint8_t flag)
|
|||
return;
|
||||
|
||||
drop:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
uip_ext_bitmap = 0;
|
||||
uip_flags = 0;
|
||||
return;
|
||||
|
@ -2338,18 +2320,16 @@ uip_send(const void *data, int len)
|
|||
int copylen;
|
||||
|
||||
if(uip_sappdata != NULL) {
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN -
|
||||
(int)((char *)uip_sappdata -
|
||||
(char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN]));
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_IPTCPH_LEN -
|
||||
(int)((char *)uip_sappdata - (char *)UIP_TCP_PAYLOAD));
|
||||
} else {
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN);
|
||||
copylen = MIN(len, UIP_BUFSIZE - UIP_IPTCPH_LEN);
|
||||
}
|
||||
if(copylen > 0) {
|
||||
uip_slen = copylen;
|
||||
if(data != uip_sappdata) {
|
||||
if(uip_sappdata == NULL) {
|
||||
memcpy((char *)&uip_buf[UIP_LLH_LEN + UIP_TCPIP_HLEN],
|
||||
(data), uip_slen);
|
||||
memcpy(UIP_TCP_PAYLOAD, (data), uip_slen);
|
||||
} else {
|
||||
memcpy(uip_sappdata, (data), uip_slen);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
*
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "uip.h"
|
||||
#include "net/ipv6/uip.h"
|
||||
#include "net/ipv6/uipbuf.h"
|
||||
#include <string.h>
|
||||
|
||||
|
@ -38,45 +38,141 @@
|
|||
|
||||
static uint16_t uipbuf_attrs[UIPBUF_ATTR_MAX];
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uipbuf_clear(void)
|
||||
{
|
||||
uip_len = 0;
|
||||
uip_ext_len = 0;
|
||||
uip_last_proto = 0;
|
||||
uipbuf_clear_attr();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
uipbuf_add_ext_hdr(int16_t len)
|
||||
{
|
||||
if(len + uip_len <= UIP_LINK_MTU && len + uip_len >= 0) {
|
||||
uip_ext_len += len;
|
||||
uip_len += len;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
bool
|
||||
uipbuf_set_len(uint16_t len)
|
||||
{
|
||||
if(len <= UIP_LINK_MTU) {
|
||||
uip_len = len;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uipbuf_set_len_field(struct uip_ip_hdr *hdr, uint16_t len)
|
||||
{
|
||||
hdr->len[0] = (len >> 8);
|
||||
hdr->len[1] = (len & 0xff);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint16_t
|
||||
uipbuf_get_len_field(struct uip_ip_hdr *hdr)
|
||||
{
|
||||
return ((uint16_t)(hdr->len[0]) << 8) + hdr->len[1];
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Get the next header given the buffer - start indicates that this is
|
||||
start of the IPv6 header - needs to be set to 0 when in an ext hdr */
|
||||
uint8_t*
|
||||
uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, uint8_t start)
|
||||
uint8_t *
|
||||
uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, bool start)
|
||||
{
|
||||
int ext_len = 0;
|
||||
struct uip_ip_hdr *ipbuf = (struct uip_ip_hdr *) buffer;
|
||||
struct uip_ext_hdr *ext = NULL;
|
||||
int curr_hdr_len = 0;
|
||||
int next_hdr_len = 0;
|
||||
uint8_t *next_header = NULL;
|
||||
struct uip_ip_hdr *ipbuf = NULL;
|
||||
struct uip_ext_hdr *curr_ext = NULL;
|
||||
struct uip_ext_hdr *next_ext = NULL;
|
||||
|
||||
if(start) {
|
||||
/* protocol in the IP buffer */
|
||||
ipbuf = (struct uip_ip_hdr *)buffer;
|
||||
*protocol = ipbuf->proto;
|
||||
return buffer + UIP_IPH_LEN;
|
||||
curr_hdr_len = UIP_IPH_LEN;
|
||||
} else {
|
||||
/* protocol in the Ext hdr */
|
||||
ext = (struct uip_ext_hdr *) buffer;
|
||||
*protocol = ext->next;
|
||||
curr_ext = (struct uip_ext_hdr *)buffer;
|
||||
*protocol = curr_ext->next;
|
||||
/* This is just an ext header */
|
||||
ext_len = (ext->len << 3) + 8;
|
||||
return buffer + ext_len;
|
||||
curr_hdr_len = (curr_ext->len << 3) + 8;
|
||||
}
|
||||
|
||||
/* Check first if enough space for current header */
|
||||
if(curr_hdr_len > size) {
|
||||
return NULL;
|
||||
}
|
||||
next_header = buffer + curr_hdr_len;
|
||||
|
||||
/* Check if the buffer is large enough for the next header */
|
||||
if(uip_is_proto_ext_hdr(*protocol)) {
|
||||
next_ext = (struct uip_ext_hdr *)next_header;
|
||||
next_hdr_len = (next_ext->len << 3) + 8;
|
||||
} else {
|
||||
if(*protocol == UIP_PROTO_TCP) {
|
||||
next_hdr_len = UIP_TCPH_LEN;
|
||||
} else if(*protocol == UIP_PROTO_UDP) {
|
||||
next_hdr_len = UIP_UDPH_LEN;
|
||||
} else if(*protocol == UIP_PROTO_ICMP6) {
|
||||
next_hdr_len = UIP_ICMPH_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
/* Size must be enough to hold both the current and next header */
|
||||
if(next_hdr_len == 0 || curr_hdr_len + next_hdr_len > size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return next_header;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Get the final header given the buffer - that is assumed to be at start
|
||||
of an IPv6 header */
|
||||
uint8_t*
|
||||
uint8_t *
|
||||
uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol)
|
||||
{
|
||||
uint8_t *nbuf;
|
||||
|
||||
nbuf = uipbuf_get_next_header(buffer, size, protocol, 1);
|
||||
while(uip_is_proto_ext_hdr(*protocol)) {
|
||||
/* send in and move beyond the ext hdr */
|
||||
nbuf = uipbuf_get_next_header(nbuf, size - (nbuf - buffer), protocol, 0);
|
||||
nbuf = uipbuf_get_next_header(buffer, size, protocol, true);
|
||||
while(nbuf != NULL && uip_is_proto_ext_hdr(*protocol)) {
|
||||
/* move to the ext hdr */
|
||||
nbuf = uipbuf_get_next_header(nbuf, size - (nbuf - buffer), protocol, false);
|
||||
}
|
||||
|
||||
/* In case the buffer wasn't large enough for all headers, return NULL */
|
||||
return nbuf;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t *
|
||||
uipbuf_search_header(uint8_t *buffer, uint16_t size, uint8_t protocol)
|
||||
{
|
||||
uint8_t *nbuf;
|
||||
uint8_t next_proto;
|
||||
|
||||
nbuf = uipbuf_get_next_header(buffer, size, &next_proto, true);
|
||||
while(nbuf != NULL && next_proto != protocol && uip_is_proto_ext_hdr(next_proto)) {
|
||||
/* move to the ext hdr */
|
||||
nbuf = uipbuf_get_next_header(nbuf, size - (nbuf - buffer), &next_proto, false);
|
||||
}
|
||||
|
||||
if(next_proto == protocol) {
|
||||
return nbuf;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Common functions for uipbuf (attributes, etc).
|
||||
*
|
||||
|
|
|
@ -34,6 +34,40 @@
|
|||
#define UIPBUF_H_
|
||||
|
||||
#include "contiki.h"
|
||||
struct uip_ip_hdr;
|
||||
|
||||
/**
|
||||
* \brief Resets uIP buffer
|
||||
*/
|
||||
void uipbuf_clear(void);
|
||||
|
||||
/**
|
||||
* \brief Update uip buffer length for addition of an extension header
|
||||
* \param len The length of the new extension header
|
||||
* \retval true if the length fields were successfully set, false otherwise
|
||||
*/
|
||||
bool uipbuf_add_ext_hdr(int16_t len);
|
||||
|
||||
/**
|
||||
* \brief Set the length of the uIP buffer
|
||||
* \param len The new length
|
||||
* \retval true if the len was successfully set, false otherwise
|
||||
*/
|
||||
bool uipbuf_set_len(uint16_t len);
|
||||
|
||||
/**
|
||||
* \brief Updates the length field in the uIP buffer
|
||||
* \param buffer The IPv6 header
|
||||
* \param len The new length value
|
||||
*/
|
||||
void uipbuf_set_len_field(struct uip_ip_hdr *hdr, uint16_t len);
|
||||
|
||||
/**
|
||||
* \brief Returns the value of the length field in the uIP buffer
|
||||
* \param buffer The IPv6 header
|
||||
* \retvel The length value
|
||||
*/
|
||||
uint16_t uipbuf_get_len_field(struct uip_ip_hdr *hdr);
|
||||
|
||||
/**
|
||||
* \brief Get the next IPv6 header.
|
||||
|
@ -41,11 +75,11 @@
|
|||
* \param size The size of the data in the buffer
|
||||
* \param protocol A pointer to a variable where the protocol of the header will be stored
|
||||
* \param start A flag that indicates if this is expected to be the IPv6 packet header or a later header (Extension header)
|
||||
* \retval returns address of the starting position of the next header
|
||||
* \retval returns address of the next header, or NULL in case of insufficient buffer space
|
||||
*
|
||||
* This function moves to the next header in a IPv6 packet.
|
||||
*/
|
||||
uint8_t* uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, uint8_t start);
|
||||
uint8_t *uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protocol, bool start);
|
||||
|
||||
|
||||
/**
|
||||
|
@ -53,12 +87,22 @@ uint8_t* uipbuf_get_next_header(uint8_t *buffer, uint16_t size, uint8_t *protoco
|
|||
* \param buffer A pointer to the buffer holding the IPv6 packet
|
||||
* \param size The size of the data in the buffer
|
||||
* \param protocol A pointer to a variable where the protocol of the header will be stored
|
||||
* \retval returns address of the starting position of the next header
|
||||
* \retval returns address of the last header, or NULL in case of insufficient buffer space
|
||||
*
|
||||
* This function moves to the last header of the IPv6 packet.
|
||||
*/
|
||||
uint8_t* uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol);
|
||||
uint8_t *uipbuf_get_last_header(uint8_t *buffer, uint16_t size, uint8_t *protocol);
|
||||
|
||||
/**
|
||||
* \brief Get an IPv6 header with a given protocol field.
|
||||
* \param buffer A pointer to the buffer holding the IPv6 packet
|
||||
* \param size The size of the data in the buffer
|
||||
* \param protocol The protocol we are looking for
|
||||
* \retval returns address of the header if found, else NULL
|
||||
*
|
||||
* This function moves to the last header of the IPv6 packet.
|
||||
*/
|
||||
uint8_t *uipbuf_search_header(uint8_t *buffer, uint16_t size, uint8_t protocol);
|
||||
|
||||
/**
|
||||
* \brief Get the value of the attribute
|
||||
|
|
|
@ -56,7 +56,6 @@
|
|||
#define LOG_LEVEL LOG_LEVEL_NONE
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
int
|
||||
uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr)
|
||||
{
|
||||
|
@ -118,7 +117,6 @@ uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *ipaddr)
|
|||
|
||||
return 1;
|
||||
}
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Parse a IPv4-address from a string. Returns the number of characters read
|
||||
* for the address. */
|
||||
|
|
|
@ -68,11 +68,7 @@
|
|||
* \retval 0 If the IP address could not be parsed.
|
||||
* \retval Non-zero If the IP address was parsed.
|
||||
*/
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
#define uiplib_ipaddrconv uiplib_ip6addrconv
|
||||
#else /* NETSTACK_CONF_WITH_IPV6 */
|
||||
#define uiplib_ipaddrconv uiplib_ip4addrconv
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
|
||||
int uiplib_ip4addrconv(const char *addrstr, uip_ip4addr_t *addr);
|
||||
int uiplib_ip6addrconv(const char *addrstr, uip_ip6addr_t *addr);
|
||||
|
|
|
@ -121,26 +121,6 @@
|
|||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* The link level header length.
|
||||
*
|
||||
* This is the offset into the uip_buf where the IP header can be
|
||||
* found. For Ethernet, this should be set to 14. For SLIP, this
|
||||
* should be set to 0.
|
||||
*
|
||||
* \note we probably won't use this constant for other link layers than
|
||||
* ethernet as they have variable header length (this is due to variable
|
||||
* number and type of address fields and to optional security features)
|
||||
* E.g.: 802.15.4 -> 2 + (1/2*4/8) + 0/5/6/10/14
|
||||
* 802.11 -> 4 + (6*3/4) + 2
|
||||
* \hideinitializer
|
||||
*/
|
||||
#ifdef UIP_CONF_LLH_LEN
|
||||
#define UIP_LLH_LEN (UIP_CONF_LLH_LEN)
|
||||
#else /* UIP_LLH_LEN */
|
||||
#define UIP_LLH_LEN 0
|
||||
#endif /* UIP_CONF_LLH_LEN */
|
||||
|
||||
/**
|
||||
* The size of the uIP packet buffer.
|
||||
*
|
||||
|
@ -151,12 +131,11 @@
|
|||
* \hideinitializer
|
||||
*/
|
||||
#ifndef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_BUFSIZE (UIP_LINK_MTU + UIP_LLH_LEN)
|
||||
#define UIP_BUFSIZE (UIP_LINK_MTU)
|
||||
#else /* UIP_CONF_BUFFER_SIZE */
|
||||
#define UIP_BUFSIZE (UIP_CONF_BUFFER_SIZE)
|
||||
#endif /* UIP_CONF_BUFFER_SIZE */
|
||||
|
||||
|
||||
/**
|
||||
* Determines if statistics support should be compiled in.
|
||||
*
|
||||
|
@ -248,11 +227,6 @@ void uip_log(char *msg);
|
|||
/** The maximum transmission unit at the IP Layer*/
|
||||
#define UIP_LINK_MTU 1280
|
||||
|
||||
#ifndef NETSTACK_CONF_WITH_IPV6
|
||||
/** Do we use IPv6 or not (default: no) */
|
||||
#define NETSTACK_CONF_WITH_IPV6 0
|
||||
#endif
|
||||
|
||||
#ifndef UIP_CONF_IPV6_QUEUE_PKT
|
||||
/** Do we do per %neighbor queuing during address resolution (default: no) */
|
||||
#define UIP_CONF_IPV6_QUEUE_PKT 0
|
||||
|
@ -440,15 +414,15 @@ void uip_log(char *msg);
|
|||
* The TCP maximum segment size.
|
||||
*
|
||||
* This is should not be to set to more than
|
||||
* UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN.
|
||||
* UIP_BUFSIZE - UIP_IPTCPH_LEN.
|
||||
*/
|
||||
#ifdef UIP_CONF_TCP_MSS
|
||||
#if UIP_CONF_TCP_MSS > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
|
||||
#if UIP_CONF_TCP_MSS > (UIP_BUFSIZE - UIP_IPTCPH_LEN)
|
||||
#error UIP_CONF_TCP_MSS is too large for the current UIP_BUFSIZE
|
||||
#endif /* UIP_CONF_TCP_MSS > (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN) */
|
||||
#endif /* UIP_CONF_TCP_MSS > (UIP_BUFSIZE - UIP_IPTCPH_LEN) */
|
||||
#define UIP_TCP_MSS (UIP_CONF_TCP_MSS)
|
||||
#else /* UIP_CONF_TCP_MSS */
|
||||
#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_LLH_LEN - UIP_TCPIP_HLEN)
|
||||
#define UIP_TCP_MSS (UIP_BUFSIZE - UIP_IPTCPH_LEN)
|
||||
#endif /* UIP_CONF_TCP_MSS */
|
||||
|
||||
/**
|
||||
|
|
|
@ -107,7 +107,7 @@ static void
|
|||
ext_header_remove(void)
|
||||
{
|
||||
#if NETSTACK_CONF_WITH_IPV6
|
||||
uip_ext_len = 0;
|
||||
uip_remove_ext_hdr();
|
||||
#endif /* NETSTACK_CONF_WITH_IPV6 */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -118,7 +118,7 @@ ext_header_update(void)
|
|||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
ext_header_hbh_update(int uip_ext_opt_offset)
|
||||
ext_header_hbh_update(uint8_t *ext_buf, int opt_offset)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -131,12 +131,13 @@ struct routing_driver {
|
|||
* Process and update the routing protocol hob-by-hop
|
||||
* extention headers of the current uIP packet.
|
||||
*
|
||||
* \param uip_ext_opt_offset The offset within the uIP packet where
|
||||
* extension headers start
|
||||
* \param ext_buf A pointer to the ext header buffer
|
||||
* \param opt_offset The offset within the extension header where
|
||||
* the option starts
|
||||
* \return 1 in case the packet is valid and to be processed further,
|
||||
* 0 in case the packet must be dropped.
|
||||
*/
|
||||
int (* ext_header_hbh_update)(int uip_ext_opt_offset);
|
||||
int (* ext_header_hbh_update)(uint8_t *ext_buf, int opt_offset);
|
||||
/**
|
||||
* Process and update SRH in-place,
|
||||
* i.e. internal address swapping as per RFC6554
|
||||
|
|
|
@ -60,46 +60,35 @@
|
|||
#include <limits.h>
|
||||
#include <string.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_NEXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_HOP_BY_HOP_LEN])
|
||||
#define UIP_RH_BUF ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_RPL_SRH_BUF ((struct uip_rpl_srh_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_RH_LEN])
|
||||
#define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
||||
rpl_ext_header_hbh_update(uint8_t *ext_buf, int opt_offset)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
int down;
|
||||
uint16_t sender_rank;
|
||||
uint8_t sender_closer;
|
||||
uip_ds6_route_t *route;
|
||||
rpl_parent_t *sender = NULL;
|
||||
rpl_parent_t *sender;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)ext_buf;
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(ext_buf + opt_offset);
|
||||
|
||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_type != UIP_EXT_HDR_OPT_RPL
|
||||
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||
if(hbh_hdr->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| rpl_opt->opt_type != UIP_EXT_HDR_OPT_RPL
|
||||
|| rpl_opt->opt_len != RPL_HDR_OPT_LEN) {
|
||||
|
||||
LOG_ERR("Hop-by-hop extension header has wrong size or type (%u %u %u)\n",
|
||||
UIP_HBHO_BUF->len,
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_type,
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len);
|
||||
hbh_hdr->len, rpl_opt->opt_type, rpl_opt->opt_len);
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||
instance = rpl_get_instance(rpl_opt->instance);
|
||||
if(instance == NULL) {
|
||||
LOG_ERR("Unknown instance: %u\n",
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||
LOG_ERR("Unknown instance: %u\n", rpl_opt->instance);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||
if(rpl_opt->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||
LOG_ERR("Forward error!\n");
|
||||
/* We should try to repair it by removing the neighbor that caused
|
||||
the packet to be forwareded in the first place. We drop any
|
||||
|
@ -123,14 +112,14 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
return 0;
|
||||
}
|
||||
down = 0;
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN) {
|
||||
if(rpl_opt->flags & RPL_HDR_OPT_DOWN) {
|
||||
down = 1;
|
||||
}
|
||||
|
||||
sender_rank = UIP_HTONS(UIP_EXT_HDR_OPT_RPL_BUF->senderrank);
|
||||
sender_rank = UIP_HTONS(rpl_opt->senderrank);
|
||||
sender = nbr_table_get_from_lladdr(rpl_parents, packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
|
||||
if(sender != NULL && (UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR)) {
|
||||
if(sender != NULL && (rpl_opt->flags & RPL_HDR_OPT_RANK_ERR)) {
|
||||
/* A rank error was signalled, attempt to repair it by updating
|
||||
* the sender's rank from ext header */
|
||||
sender->rank = sender_rank;
|
||||
|
@ -160,7 +149,7 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
instance->unicast_dio_target = sender;
|
||||
rpl_schedule_unicast_dio_immediately(instance);
|
||||
}
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) {
|
||||
if(rpl_opt->flags & RPL_HDR_OPT_RANK_ERR) {
|
||||
RPL_STAT(rpl_stats.loop_errors++);
|
||||
LOG_ERR(" Rank error signalled in RPL option!\n");
|
||||
/* Packet must be dropped and dio trickle timer reset, see RFC6550 - 11.2.2.2 */
|
||||
|
@ -169,7 +158,7 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
}
|
||||
LOG_WARN("Single error tolerated\n");
|
||||
RPL_STAT(rpl_stats.loop_warnings++);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||
rpl_opt->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -181,41 +170,19 @@ int
|
|||
rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
#if RPL_WITH_NON_STORING
|
||||
uint8_t *uip_next_hdr;
|
||||
int last_uip_ext_len = uip_ext_len;
|
||||
struct uip_routing_hdr *rh_header;
|
||||
rpl_dag_t *dag;
|
||||
uip_sr_node_t *dest_node;
|
||||
uip_sr_node_t *root_node;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
|
||||
/* Look for routing header */
|
||||
while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, only the Hop-by-Hop Options header and
|
||||
* Destination Options header can appear before the Routing
|
||||
* header.
|
||||
*/
|
||||
/* Move to next header */
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
uip_next_hdr = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Look for routing ext header */
|
||||
rh_header = (struct uip_routing_hdr *)uipbuf_search_header(uip_buf, uip_len, UIP_PROTO_ROUTING);
|
||||
|
||||
dag = rpl_get_dag(&UIP_IP_BUF->destipaddr);
|
||||
root_node = uip_sr_get_node(dag, &dag->dag_id);
|
||||
dest_node = uip_sr_get_node(dag, &UIP_IP_BUF->destipaddr);
|
||||
|
||||
if((uip_next_hdr != NULL && *uip_next_hdr == UIP_PROTO_ROUTING
|
||||
&& UIP_RH_BUF->routing_type == RPL_RH_TYPE_SRH) ||
|
||||
if((rh_header != NULL && rh_header->routing_type == RPL_RH_TYPE_SRH) ||
|
||||
(dest_node != NULL && root_node != NULL &&
|
||||
dest_node->parent == root_node)) {
|
||||
/* Routing header found or the packet destined for a direct child of the root.
|
||||
|
@ -224,11 +191,9 @@ rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
|
|||
* forwarding to next hop */
|
||||
uip_ipaddr_copy(ipaddr, &UIP_IP_BUF->destipaddr);
|
||||
uip_create_linklocal_prefix(ipaddr);
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
#else /* RPL_WITH_NON_STORING */
|
||||
return 0; /* SRH not found */
|
||||
|
@ -239,34 +204,13 @@ int
|
|||
rpl_ext_header_srh_update(void)
|
||||
{
|
||||
#if RPL_WITH_NON_STORING
|
||||
uint8_t *uip_next_hdr;
|
||||
int last_uip_ext_len = uip_ext_len;
|
||||
struct uip_routing_hdr *rh_header;
|
||||
struct uip_rpl_srh_hdr *srh_header;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
/* Look for routing ext header */
|
||||
rh_header = (struct uip_routing_hdr *)uipbuf_search_header(uip_buf, uip_len, UIP_PROTO_ROUTING);
|
||||
|
||||
/* Look for routing header */
|
||||
while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, only the Hop-by-Hop Options header and
|
||||
* Destination Options header can appear before the Routing
|
||||
* header.
|
||||
*/
|
||||
/* Move to next header */
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
uip_next_hdr = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(uip_next_hdr != NULL && *uip_next_hdr == UIP_PROTO_ROUTING
|
||||
&& UIP_RH_BUF->routing_type == RPL_RH_TYPE_SRH) {
|
||||
if(rh_header != NULL && rh_header->routing_type == RPL_RH_TYPE_SRH) {
|
||||
/* SRH found, now look for next hop */
|
||||
uint8_t cmpri, cmpre;
|
||||
uint8_t ext_len;
|
||||
|
@ -275,11 +219,12 @@ rpl_ext_header_srh_update(void)
|
|||
uint8_t segments_left;
|
||||
uip_ipaddr_t current_dest_addr;
|
||||
|
||||
segments_left = UIP_RH_BUF->seg_left;
|
||||
ext_len = (UIP_RH_BUF->len * 8) + 8;
|
||||
cmpri = UIP_RPL_SRH_BUF->cmpr >> 4;
|
||||
cmpre = UIP_RPL_SRH_BUF->cmpr & 0x0f;
|
||||
padding = UIP_RPL_SRH_BUF->pad >> 4;
|
||||
srh_header = (struct uip_rpl_srh_hdr *)(((uint8_t *)rh_header) + RPL_RH_LEN);
|
||||
segments_left = rh_header->seg_left;
|
||||
ext_len = rh_header->len * 8 + 8;
|
||||
cmpri = srh_header->cmpr >> 4;
|
||||
cmpre = srh_header->cmpr & 0x0f;
|
||||
padding = srh_header->pad >> 4;
|
||||
path_len = ((ext_len - padding - RPL_RH_LEN - RPL_SRH_LEN - (16 - cmpre)) / (16 - cmpri)) + 1;
|
||||
(void)path_len;
|
||||
|
||||
|
@ -290,7 +235,7 @@ rpl_ext_header_srh_update(void)
|
|||
/* We are the final destination, do nothing */
|
||||
} else {
|
||||
uint8_t i = path_len - segments_left; /* The index of the next address to be visited */
|
||||
uint8_t *addr_ptr = ((uint8_t *)UIP_RH_BUF) + RPL_RH_LEN + RPL_SRH_LEN + (i * (16 - cmpri));
|
||||
uint8_t *addr_ptr = ((uint8_t *)rh_header) + RPL_RH_LEN + RPL_SRH_LEN + (i * (16 - cmpri));
|
||||
uint8_t cmpr = segments_left == 1 ? cmpre : cmpri;
|
||||
|
||||
/* As per RFC6554: swap the IPv6 destination address and address[i] */
|
||||
|
@ -303,17 +248,15 @@ rpl_ext_header_srh_update(void)
|
|||
memcpy(addr_ptr, ((uint8_t *)¤t_dest_addr) + cmpr, 16 - cmpr);
|
||||
|
||||
/* Update segments left field */
|
||||
UIP_RH_BUF->seg_left--;
|
||||
rh_header->seg_left--;
|
||||
|
||||
LOG_INFO("SRH next hop ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
}
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
#else /* RPL_WITH_NON_STORING */
|
||||
return 0; /* SRH not found */
|
||||
|
@ -336,7 +279,6 @@ static int
|
|||
insert_srh_header(void)
|
||||
{
|
||||
/* Implementation of RFC6554 */
|
||||
uint8_t temp_len;
|
||||
uint8_t path_len;
|
||||
uint8_t ext_len;
|
||||
uint8_t cmpri, cmpre; /* ComprI and ComprE fields of the RPL Source Routing Header */
|
||||
|
@ -348,6 +290,10 @@ insert_srh_header(void)
|
|||
rpl_dag_t *dag;
|
||||
uip_ipaddr_t node_addr;
|
||||
|
||||
/* Always insest SRH as first extension header */
|
||||
struct uip_routing_hdr *rh_hdr = (struct uip_routing_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_rpl_srh_hdr *srh_hdr = (struct uip_rpl_srh_hdr *)(UIP_IP_PAYLOAD(0) + RPL_RH_LEN);
|
||||
|
||||
LOG_INFO("SRH creating source routing header with destination ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
|
@ -418,33 +364,33 @@ insert_srh_header(void)
|
|||
path_len, cmpri, cmpre, ext_len, padding);
|
||||
|
||||
/* Check if there is enough space to store the extension header */
|
||||
if(uip_len + ext_len > UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
if(uip_len + ext_len > UIP_LINK_MTU) {
|
||||
LOG_ERR("Packet too long: impossible to add source routing header (%u bytes)\n", ext_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move existing ext headers and payload uip_ext_len further */
|
||||
memmove(uip_buf + uip_l2_l3_hdr_len + ext_len,
|
||||
uip_buf + uip_l2_l3_hdr_len, uip_len - UIP_IPH_LEN);
|
||||
memset(uip_buf + uip_l2_l3_hdr_len, 0, ext_len);
|
||||
/* Move existing ext headers and payload ext_len further */
|
||||
memmove(uip_buf + UIP_IPH_LEN + uip_ext_len + ext_len,
|
||||
uip_buf + UIP_IPH_LEN + uip_ext_len, uip_len - UIP_IPH_LEN);
|
||||
memset(uip_buf + UIP_IPH_LEN + uip_ext_len, 0, ext_len);
|
||||
|
||||
/* Insert source routing header */
|
||||
UIP_RH_BUF->next = UIP_IP_BUF->proto;
|
||||
/* Insert source routing header (as first ext header) */
|
||||
rh_hdr->next = UIP_IP_BUF->proto;
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ROUTING;
|
||||
|
||||
/* Initialize IPv6 Routing Header */
|
||||
UIP_RH_BUF->len = (ext_len - 8) / 8;
|
||||
UIP_RH_BUF->routing_type = RPL_RH_TYPE_SRH;
|
||||
UIP_RH_BUF->seg_left = path_len;
|
||||
rh_hdr->len = (ext_len - 8) / 8;
|
||||
rh_hdr->routing_type = RPL_RH_TYPE_SRH;
|
||||
rh_hdr->seg_left = path_len;
|
||||
|
||||
/* Initialize RPL Source Routing Header */
|
||||
UIP_RPL_SRH_BUF->cmpr = (cmpri << 4) + cmpre;
|
||||
UIP_RPL_SRH_BUF->pad = padding << 4;
|
||||
srh_hdr->cmpr = (cmpri << 4) + cmpre;
|
||||
srh_hdr->pad = padding << 4;
|
||||
|
||||
/* Initialize addresses field (the actual source route).
|
||||
* From last to first. */
|
||||
node = dest_node;
|
||||
hop_ptr = ((uint8_t *)UIP_RH_BUF) + ext_len - padding; /* Pointer where to write the next hop compressed address */
|
||||
hop_ptr = ((uint8_t *)rh_hdr) + ext_len - padding; /* Pointer where to write the next hop compressed address */
|
||||
|
||||
while(node != NULL && node->parent != root_node) {
|
||||
NETSTACK_ROUTING.get_sr_node_ipaddr(&node_addr, node);
|
||||
|
@ -459,15 +405,9 @@ insert_srh_header(void)
|
|||
NETSTACK_ROUTING.get_sr_node_ipaddr(&node_addr, node);
|
||||
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &node_addr);
|
||||
|
||||
/* In-place update of IPv6 length field */
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
UIP_IP_BUF->len[1] += ext_len;
|
||||
if(UIP_IP_BUF->len[1] < temp_len) {
|
||||
UIP_IP_BUF->len[0]++;
|
||||
}
|
||||
|
||||
uip_ext_len += ext_len;
|
||||
uip_len += ext_len;
|
||||
/* Update the IPv6 length field */
|
||||
uipbuf_add_ext_hdr(ext_len);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -476,44 +416,37 @@ static int
|
|||
update_hbh_header(void)
|
||||
{
|
||||
rpl_instance_t *instance;
|
||||
int uip_ext_opt_offset;
|
||||
int last_uip_ext_len;
|
||||
rpl_parent_t *parent;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(UIP_IP_PAYLOAD(0) + 2);
|
||||
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO && rpl_opt->opt_type == UIP_EXT_HDR_OPT_RPL) {
|
||||
if(hbh_hdr->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| rpl_opt->opt_len != RPL_HDR_OPT_LEN) {
|
||||
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO && UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL) {
|
||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||
|
||||
LOG_ERR("Hop-by-hop extension header has wrong size (%u %u)\n",
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len,
|
||||
uip_ext_len);
|
||||
LOG_ERR("Hop-by-hop extension header has wrong size (%u)\n", rpl_opt->opt_len);
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
instance = rpl_get_instance(UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||
instance = rpl_get_instance(rpl_opt->instance);
|
||||
if(instance == NULL || !instance->used || !instance->current_dag->joined) {
|
||||
LOG_ERR("Unable to add/update hop-by-hop extension header: incorrect instance\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
LOG_INFO("Updating RPL option\n");
|
||||
/* Update sender rank and instance, will update flags next */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = instance->instance_id;
|
||||
rpl_opt->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||
rpl_opt->instance = instance->instance_id;
|
||||
|
||||
if(RPL_IS_STORING(instance)) { /* In non-storing mode, downwards traffic does not have the HBH option */
|
||||
/* Check the direction of the down flag, as per Section 11.2.2.3,
|
||||
which states that if a packet is going down it should in
|
||||
general not go back up again. If this happens, a
|
||||
RPL_HDR_OPT_FWD_ERR should be flagged. */
|
||||
if((UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN)) {
|
||||
if((rpl_opt->flags & RPL_HDR_OPT_DOWN)) {
|
||||
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_FWD_ERR;
|
||||
rpl_opt->flags |= RPL_HDR_OPT_FWD_ERR;
|
||||
LOG_WARN("RPL forwarding error\n");
|
||||
/* We should send back the packet to the originating parent,
|
||||
but it is not feasible yet, so we send a No-Path DAO instead */
|
||||
|
@ -532,63 +465,51 @@ update_hbh_header(void)
|
|||
if(uip_ds6_route_lookup(&UIP_IP_BUF->destipaddr) == NULL) {
|
||||
/* No route was found, so this packet will go towards the RPL
|
||||
root. If so, we should not set the down flag. */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags &= ~RPL_HDR_OPT_DOWN;
|
||||
rpl_opt->flags &= ~RPL_HDR_OPT_DOWN;
|
||||
LOG_DBG("RPL option going up\n");
|
||||
} else {
|
||||
/* A DAO route was found so we set the down flag. */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_DOWN;
|
||||
rpl_opt->flags |= RPL_HDR_OPT_DOWN;
|
||||
LOG_DBG("RPL option going down\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
insert_hbh_header(const rpl_instance_t *instance)
|
||||
{
|
||||
int uip_ext_opt_offset;
|
||||
int last_uip_ext_len;
|
||||
uint8_t temp_len;
|
||||
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(UIP_IP_PAYLOAD(2));
|
||||
|
||||
/* Insert hop-by-hop header */
|
||||
LOG_DBG("Creating hop-by-hop option\n");
|
||||
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_LINK_MTU) {
|
||||
LOG_ERR("Packet too long: impossible to add hop-by-hop option\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move existing ext headers and payload UIP_EXT_BUF further */
|
||||
memmove(UIP_HBHO_NEXT_BUF, UIP_EXT_BUF, uip_len - UIP_IPH_LEN);
|
||||
memset(UIP_HBHO_BUF, 0, RPL_HOP_BY_HOP_LEN);
|
||||
/* Move existing ext headers and payload RPL_HOP_BY_HOP_LEN further */
|
||||
memmove(UIP_IP_PAYLOAD(RPL_HOP_BY_HOP_LEN), UIP_IP_PAYLOAD(0), uip_len - UIP_IPH_LEN);
|
||||
memset(UIP_IP_PAYLOAD(0), 0, RPL_HOP_BY_HOP_LEN);
|
||||
|
||||
/* Update IP and HBH protocol and fields */
|
||||
UIP_HBHO_BUF->next = UIP_IP_BUF->proto;
|
||||
/* Insert HBH header (as first ext header) */
|
||||
hbh_hdr->next = UIP_IP_BUF->proto;
|
||||
UIP_IP_BUF->proto = UIP_PROTO_HBHO;
|
||||
|
||||
/* Initialize HBH option */
|
||||
UIP_HBHO_BUF->len = (RPL_HOP_BY_HOP_LEN - 8) / 8;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags = 0;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = instance->instance_id;
|
||||
uip_len += RPL_HOP_BY_HOP_LEN;
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
UIP_IP_BUF->len[1] += RPL_HOP_BY_HOP_LEN;
|
||||
if(UIP_IP_BUF->len[1] < temp_len) {
|
||||
UIP_IP_BUF->len[0]++;
|
||||
}
|
||||
hbh_hdr->len = (RPL_HOP_BY_HOP_LEN - 8) / 8;
|
||||
rpl_opt->opt_type = UIP_EXT_HDR_OPT_RPL;
|
||||
rpl_opt->opt_len = RPL_HDR_OPT_LEN;
|
||||
rpl_opt->flags = 0;
|
||||
rpl_opt->senderrank = UIP_HTONS(instance->current_dag->rank);
|
||||
rpl_opt->instance = instance->instance_id;
|
||||
|
||||
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
||||
uipbuf_add_ext_hdr(RPL_HOP_BY_HOP_LEN);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
/* Update header before returning */
|
||||
return update_hbh_header();
|
||||
|
@ -597,52 +518,33 @@ insert_hbh_header(const rpl_instance_t *instance)
|
|||
void
|
||||
rpl_ext_header_remove(void)
|
||||
{
|
||||
uint8_t temp_len;
|
||||
uint8_t rpl_ext_hdr_len;
|
||||
int uip_ext_opt_offset;
|
||||
uint8_t *uip_next_hdr;
|
||||
uint8_t *prev_proto_ptr;
|
||||
uint8_t protocol;
|
||||
uint8_t ext_len;
|
||||
uint8_t *next_header;
|
||||
struct uip_ext_hdr *ext_ptr;
|
||||
struct uip_ext_hdr_opt *opt_ptr;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
|
||||
/* Look for hop-by-hop and routing headers */
|
||||
while(uip_next_hdr != NULL) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_ROUTING:
|
||||
if((*uip_next_hdr != UIP_PROTO_HBHO || UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL)) {
|
||||
/* Remove hop-by-hop and routing headers */
|
||||
*uip_next_hdr = UIP_EXT_BUF->next;
|
||||
rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8;
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
uip_len -= rpl_ext_hdr_len;
|
||||
UIP_IP_BUF->len[1] -= rpl_ext_hdr_len;
|
||||
if(UIP_IP_BUF->len[1] > temp_len) {
|
||||
UIP_IP_BUF->len[0]--;
|
||||
}
|
||||
LOG_DBG("Removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len);
|
||||
memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN);
|
||||
} else {
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, any header other than the Destination
|
||||
* Options header does not appear between the Hop-by-Hop
|
||||
* Options header and the Routing header.
|
||||
*
|
||||
* We're moving to the next header only if uip_next_hdr has
|
||||
* UIP_PROTO_DESTO. Otherwise, we'll return.
|
||||
*/
|
||||
/* Move to next header */
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
|
||||
ext_ptr = (struct uip_ext_hdr *)next_header;
|
||||
prev_proto_ptr = &UIP_IP_BUF->proto;
|
||||
while(next_header != NULL && uip_is_proto_ext_hdr(protocol)) {
|
||||
opt_ptr = (struct uip_ext_hdr_opt *)(next_header + 2);
|
||||
if(protocol == UIP_PROTO_ROUTING || (protocol == UIP_PROTO_HBHO && opt_ptr->type == UIP_EXT_HDR_OPT_RPL)) {
|
||||
/* Remove ext header */
|
||||
*prev_proto_ptr = ext_ptr->next;
|
||||
ext_len = ext_ptr->len * 8 + 8;
|
||||
uipbuf_add_ext_hdr(-ext_len);
|
||||
/* Update length field and rest of packer to the "left" */
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
memmove(next_header, next_header + ext_len, uip_len - (next_header - uip_buf));
|
||||
/* Update loop variables */
|
||||
protocol = *prev_proto_ptr;
|
||||
} else {
|
||||
/* move to the ext hdr */
|
||||
next_header = uipbuf_get_next_header(next_header, uip_len - (next_header - uip_buf), &protocol, false);
|
||||
ext_ptr = (struct uip_ext_hdr *)next_header;
|
||||
prev_proto_ptr = &ext_ptr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,9 +70,6 @@
|
|||
#define RPL_DIO_MOP_MASK 0x38
|
||||
#define RPL_DIO_PREFERENCE_MASK 0x07
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void dis_input(void);
|
||||
static void dio_input(void);
|
||||
|
@ -251,7 +248,7 @@ dis_input(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -471,7 +468,7 @@ dio_input(void)
|
|||
rpl_process_dio(&from, &dio);
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -810,7 +807,7 @@ dao_input_storing(void)
|
|||
/* independent if we remove or not - ACK the request */
|
||||
if(flags & RPL_DAO_K_FLAG) {
|
||||
/* indicate that we accepted the no-path DAO */
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
dao_ack_output(instance, &dao_sender_addr, sequence,
|
||||
RPL_DAO_ACK_UNCONDITIONAL_ACCEPT);
|
||||
}
|
||||
|
@ -900,7 +897,7 @@ fwd_dao:
|
|||
}
|
||||
if(should_ack) {
|
||||
LOG_DBG("Sending DAO ACK\n");
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
dao_ack_output(instance, &dao_sender_addr, sequence,
|
||||
RPL_DAO_ACK_UNCONDITIONAL_ACCEPT);
|
||||
}
|
||||
|
@ -1014,7 +1011,7 @@ dao_input_nonstoring(void)
|
|||
|
||||
if(flags & RPL_DAO_K_FLAG) {
|
||||
LOG_DBG("Sending DAO ACK\n");
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
dao_ack_output(instance, &dao_sender_addr, sequence,
|
||||
RPL_DAO_ACK_UNCONDITIONAL_ACCEPT);
|
||||
}
|
||||
|
@ -1047,7 +1044,7 @@ dao_input(void)
|
|||
}
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if RPL_WITH_DAO_ACK
|
||||
|
@ -1286,7 +1283,7 @@ dao_ack_input(void)
|
|||
|
||||
instance = rpl_get_instance(instance_id);
|
||||
if(instance == NULL) {
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1294,7 +1291,7 @@ dao_ack_input(void)
|
|||
parent = rpl_find_parent(instance->current_dag, &UIP_IP_BUF->srcipaddr);
|
||||
if(parent == NULL) {
|
||||
/* not a known instance - drop the packet and ignore */
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
|
@ -1303,7 +1300,7 @@ dao_ack_input(void)
|
|||
|
||||
if(instance->current_dag->rank == ROOT_RANK(instance)) {
|
||||
LOG_DBG("DODAG root received a DAO ACK, ignoring it\n");
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1363,7 +1360,7 @@ dao_ack_input(void)
|
|||
}
|
||||
}
|
||||
#endif /* RPL_WITH_DAO_ACK */
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
@ -65,7 +65,6 @@
|
|||
* neighbors and are not only MAC neighbors.
|
||||
*/
|
||||
#define MAX_CHILDREN (NBR_TABLE_MAX_NEIGHBORS - 2)
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
static int num_parents; /* any node that are possible parents */
|
||||
static int num_children; /* all children that we have as nexthop */
|
||||
|
|
|
@ -275,7 +275,7 @@ rpl_dag_t *rpl_get_dag(const uip_ipaddr_t *addr);
|
|||
rpl_dag_t *rpl_get_any_dag(void);
|
||||
rpl_instance_t *rpl_get_instance(uint8_t instance_id);
|
||||
int rpl_ext_header_update(void);
|
||||
int rpl_ext_header_hbh_update(int);
|
||||
int rpl_ext_header_hbh_update(uint8_t *, int);
|
||||
void rpl_insert_header(void);
|
||||
void rpl_ext_header_remove(void);
|
||||
const struct link_stats *rpl_get_parent_link_stats(rpl_parent_t *p);
|
||||
|
|
|
@ -53,46 +53,16 @@
|
|||
#define LOG_MODULE "RPL"
|
||||
#define LOG_LEVEL LOG_LEVEL_RPL
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_EXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_BUF ((struct uip_hbho_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_HBHO_NEXT_BUF ((struct uip_ext_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_HOP_BY_HOP_LEN])
|
||||
#define UIP_RH_BUF ((struct uip_routing_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_RPL_SRH_BUF ((struct uip_rpl_srh_hdr *)&uip_buf[uip_l2_l3_hdr_len + RPL_RH_LEN])
|
||||
#define UIP_EXT_HDR_OPT_BUF ((struct uip_ext_hdr_opt *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_PADN_BUF ((struct uip_ext_hdr_opt_padn *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
#define UIP_EXT_HDR_OPT_RPL_BUF ((struct uip_ext_hdr_opt_rpl *)&uip_buf[uip_l2_l3_hdr_len + uip_ext_opt_offset])
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
|
||||
{
|
||||
uint8_t *uip_next_hdr;
|
||||
int last_uip_ext_len = uip_ext_len;
|
||||
struct uip_routing_hdr *rh_header;
|
||||
uip_sr_node_t *dest_node;
|
||||
uip_sr_node_t *root_node;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
|
||||
/* Look for routing header */
|
||||
while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, only the Hop-by-Hop Options header and
|
||||
* Destination Options header can appear before the Routing header.
|
||||
*/
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
uip_next_hdr = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Look for routing ext header */
|
||||
rh_header = (struct uip_routing_hdr *)uipbuf_search_header(uip_buf, uip_len, UIP_PROTO_ROUTING);
|
||||
|
||||
if(!rpl_is_addr_in_our_dag(&UIP_IP_BUF->destipaddr)) {
|
||||
return 0;
|
||||
|
@ -101,8 +71,7 @@ rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
|
|||
root_node = uip_sr_get_node(NULL, &curr_instance.dag.dag_id);
|
||||
dest_node = uip_sr_get_node(NULL, &UIP_IP_BUF->destipaddr);
|
||||
|
||||
if((uip_next_hdr != NULL && *uip_next_hdr == UIP_PROTO_ROUTING
|
||||
&& UIP_RH_BUF->routing_type == RPL_RH_TYPE_SRH) ||
|
||||
if((rh_header != NULL && rh_header->routing_type == RPL_RH_TYPE_SRH) ||
|
||||
(dest_node != NULL && root_node != NULL &&
|
||||
dest_node->parent == root_node)) {
|
||||
/* Routing header found or the packet destined for a direct child of the root.
|
||||
|
@ -111,20 +80,18 @@ rpl_ext_header_srh_get_next_hop(uip_ipaddr_t *ipaddr)
|
|||
* forwarding to next hop */
|
||||
uip_ipaddr_copy(ipaddr, &UIP_IP_BUF->destipaddr);
|
||||
uip_create_linklocal_prefix(ipaddr);
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
LOG_DBG("no SRH found\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_ext_header_srh_update(void)
|
||||
{
|
||||
uint8_t *uip_next_hdr;
|
||||
int last_uip_ext_len = uip_ext_len;
|
||||
struct uip_routing_hdr *rh_header;
|
||||
struct uip_rpl_srh_hdr *srh_header;
|
||||
uint8_t cmpri, cmpre;
|
||||
uint8_t ext_len;
|
||||
uint8_t padding;
|
||||
|
@ -132,40 +99,21 @@ rpl_ext_header_srh_update(void)
|
|||
uint8_t segments_left;
|
||||
uip_ipaddr_t current_dest_addr;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
/* Look for routing ext header */
|
||||
rh_header = (struct uip_routing_hdr *)uipbuf_search_header(uip_buf, uip_len, UIP_PROTO_ROUTING);
|
||||
|
||||
/* Look for routing header */
|
||||
while(uip_next_hdr != NULL && *uip_next_hdr != UIP_PROTO_ROUTING) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, only the Hop-by-Hop Options header and
|
||||
* Destination Options header can appear before the Routing header.
|
||||
*/
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
uip_next_hdr = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(uip_next_hdr == NULL || *uip_next_hdr != UIP_PROTO_ROUTING
|
||||
|| UIP_RH_BUF->routing_type != RPL_RH_TYPE_SRH) {
|
||||
if(rh_header == NULL || rh_header->routing_type != RPL_RH_TYPE_SRH) {
|
||||
LOG_INFO("SRH not found\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse SRH */
|
||||
segments_left = UIP_RH_BUF->seg_left;
|
||||
ext_len = (UIP_RH_BUF->len * 8) + 8;
|
||||
cmpri = UIP_RPL_SRH_BUF->cmpr >> 4;
|
||||
cmpre = UIP_RPL_SRH_BUF->cmpr & 0x0f;
|
||||
padding = UIP_RPL_SRH_BUF->pad >> 4;
|
||||
srh_header = (struct uip_rpl_srh_hdr *)(((uint8_t *)rh_header) + RPL_RH_LEN);
|
||||
segments_left = rh_header->seg_left;
|
||||
ext_len = rh_header->len * 8 + 8;
|
||||
cmpri = srh_header->cmpr >> 4;
|
||||
cmpre = srh_header->cmpr & 0x0f;
|
||||
padding = srh_header->pad >> 4;
|
||||
path_len = ((ext_len - padding - RPL_RH_LEN - RPL_SRH_LEN - (16 - cmpre)) / (16 - cmpri)) + 1;
|
||||
(void)path_len;
|
||||
|
||||
|
@ -177,7 +125,7 @@ rpl_ext_header_srh_update(void)
|
|||
/* We are the final destination, do nothing */
|
||||
} else {
|
||||
uint8_t i = path_len - segments_left; /* The index of the next address to be visited */
|
||||
uint8_t *addr_ptr = ((uint8_t *)UIP_RH_BUF) + RPL_RH_LEN + RPL_SRH_LEN + (i * (16 - cmpri));
|
||||
uint8_t *addr_ptr = ((uint8_t *)rh_header) + RPL_RH_LEN + RPL_SRH_LEN + (i * (16 - cmpri));
|
||||
uint8_t cmpr = segments_left == 1 ? cmpre : cmpri;
|
||||
|
||||
/* As per RFC6554: swap the IPv6 destination address with address[i] */
|
||||
|
@ -190,14 +138,13 @@ rpl_ext_header_srh_update(void)
|
|||
memcpy(addr_ptr, ((uint8_t *)¤t_dest_addr) + cmpr, 16 - cmpr);
|
||||
|
||||
/* Update segments left field */
|
||||
UIP_RH_BUF->seg_left--;
|
||||
rh_header->seg_left--;
|
||||
|
||||
LOG_INFO("SRH next hop ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_("\n");
|
||||
}
|
||||
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -223,7 +170,6 @@ static int
|
|||
insert_srh_header(void)
|
||||
{
|
||||
/* Implementation of RFC6554 */
|
||||
uint8_t temp_len;
|
||||
uint8_t path_len;
|
||||
uint8_t ext_len;
|
||||
uint8_t cmpri, cmpre; /* ComprI and ComprE fields of the RPL Source Routing Header */
|
||||
|
@ -234,6 +180,10 @@ insert_srh_header(void)
|
|||
uip_sr_node_t *node;
|
||||
uip_ipaddr_t node_addr;
|
||||
|
||||
/* Always insest SRH as first extension header */
|
||||
struct uip_routing_hdr *rh_hdr = (struct uip_routing_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_rpl_srh_hdr *srh_hdr = (struct uip_rpl_srh_hdr *)(UIP_IP_PAYLOAD(0) + RPL_RH_LEN);
|
||||
|
||||
LOG_INFO("SRH creating source routing header with destination ");
|
||||
LOG_INFO_6ADDR(&UIP_IP_BUF->destipaddr);
|
||||
LOG_INFO_(" \n");
|
||||
|
@ -304,33 +254,33 @@ insert_srh_header(void)
|
|||
path_len, cmpri, cmpre, ext_len, padding);
|
||||
|
||||
/* Check if there is enough space to store the extension header */
|
||||
if(uip_len + ext_len > UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
if(uip_len + ext_len > UIP_LINK_MTU) {
|
||||
LOG_ERR("packet too long: impossible to add source routing header (%u bytes)\n", ext_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move existing ext headers and payload uip_ext_len further */
|
||||
memmove(uip_buf + uip_l2_l3_hdr_len + ext_len,
|
||||
uip_buf + uip_l2_l3_hdr_len, uip_len - UIP_IPH_LEN);
|
||||
memset(uip_buf + uip_l2_l3_hdr_len, 0, ext_len);
|
||||
/* Move existing ext headers and payload ext_len further */
|
||||
memmove(uip_buf + UIP_IPH_LEN + uip_ext_len + ext_len,
|
||||
uip_buf + UIP_IPH_LEN + uip_ext_len, uip_len - UIP_IPH_LEN);
|
||||
memset(uip_buf + UIP_IPH_LEN + uip_ext_len, 0, ext_len);
|
||||
|
||||
/* Insert source routing header */
|
||||
UIP_RH_BUF->next = UIP_IP_BUF->proto;
|
||||
/* Insert source routing header (as first ext header) */
|
||||
rh_hdr->next = UIP_IP_BUF->proto;
|
||||
UIP_IP_BUF->proto = UIP_PROTO_ROUTING;
|
||||
|
||||
/* Initialize IPv6 Routing Header */
|
||||
UIP_RH_BUF->len = (ext_len - 8) / 8;
|
||||
UIP_RH_BUF->routing_type = RPL_RH_TYPE_SRH;
|
||||
UIP_RH_BUF->seg_left = path_len;
|
||||
rh_hdr->len = (ext_len - 8) / 8;
|
||||
rh_hdr->routing_type = RPL_RH_TYPE_SRH;
|
||||
rh_hdr->seg_left = path_len;
|
||||
|
||||
/* Initialize RPL Source Routing Header */
|
||||
UIP_RPL_SRH_BUF->cmpr = (cmpri << 4) + cmpre;
|
||||
UIP_RPL_SRH_BUF->pad = padding << 4;
|
||||
srh_hdr->cmpr = (cmpri << 4) + cmpre;
|
||||
srh_hdr->pad = padding << 4;
|
||||
|
||||
/* Initialize addresses field (the actual source route).
|
||||
* From last to first. */
|
||||
node = dest_node;
|
||||
hop_ptr = ((uint8_t *)UIP_RH_BUF) + ext_len - padding; /* Pointer where to write the next hop compressed address */
|
||||
hop_ptr = ((uint8_t *)rh_hdr) + ext_len - padding; /* Pointer where to write the next hop compressed address */
|
||||
|
||||
while(node != NULL && node->parent != root_node) {
|
||||
NETSTACK_ROUTING.get_sr_node_ipaddr(&node_addr, node);
|
||||
|
@ -345,21 +295,15 @@ insert_srh_header(void)
|
|||
NETSTACK_ROUTING.get_sr_node_ipaddr(&node_addr, node);
|
||||
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, &node_addr);
|
||||
|
||||
/* In-place update of IPv6 length field */
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
UIP_IP_BUF->len[1] += ext_len;
|
||||
if(UIP_IP_BUF->len[1] < temp_len) {
|
||||
UIP_IP_BUF->len[0]++;
|
||||
}
|
||||
|
||||
uip_ext_len += ext_len;
|
||||
uip_len += ext_len;
|
||||
/* Update the IPv6 length field */
|
||||
uipbuf_add_ext_hdr(ext_len);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
||||
rpl_ext_header_hbh_update(uint8_t *ext_buf, int opt_offset)
|
||||
{
|
||||
int down;
|
||||
int rank_error_signaled;
|
||||
|
@ -367,32 +311,31 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
uint16_t sender_rank;
|
||||
uint8_t sender_closer;
|
||||
rpl_nbr_t *sender;
|
||||
uint8_t opt_type = UIP_EXT_HDR_OPT_RPL_BUF->opt_type;
|
||||
uint8_t opt_len = UIP_EXT_HDR_OPT_RPL_BUF->opt_len;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)ext_buf;
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(ext_buf + opt_offset);
|
||||
|
||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| opt_type != UIP_EXT_HDR_OPT_RPL
|
||||
|| opt_len != RPL_HDR_OPT_LEN) {
|
||||
if(hbh_hdr->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| rpl_opt->opt_type != UIP_EXT_HDR_OPT_RPL
|
||||
|| rpl_opt->opt_len != RPL_HDR_OPT_LEN) {
|
||||
LOG_ERR("hop-by-hop extension header has wrong size or type (%u %u %u)\n",
|
||||
UIP_HBHO_BUF->len, opt_type, opt_len);
|
||||
hbh_hdr->len, rpl_opt->opt_type, rpl_opt->opt_len);
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
if(!curr_instance.used || curr_instance.instance_id != UIP_EXT_HDR_OPT_RPL_BUF->instance) {
|
||||
LOG_ERR("unknown instance: %u\n",
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance);
|
||||
if(!curr_instance.used || curr_instance.instance_id != rpl_opt->instance) {
|
||||
LOG_ERR("unknown instance: %u\n", rpl_opt->instance);
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
if(UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||
if(rpl_opt->flags & RPL_HDR_OPT_FWD_ERR) {
|
||||
LOG_ERR("forward error!\n");
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
down = (UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_DOWN) ? 1 : 0;
|
||||
sender_rank = UIP_HTONS(UIP_EXT_HDR_OPT_RPL_BUF->senderrank);
|
||||
down = (rpl_opt->flags & RPL_HDR_OPT_DOWN) ? 1 : 0;
|
||||
sender_rank = UIP_HTONS(rpl_opt->senderrank);
|
||||
sender = nbr_table_get_from_lladdr(rpl_neighbors, packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
rank_error_signaled = (UIP_EXT_HDR_OPT_RPL_BUF->flags & RPL_HDR_OPT_RANK_ERR) ? 1 : 0;
|
||||
rank_error_signaled = (rpl_opt->flags & RPL_HDR_OPT_RANK_ERR) ? 1 : 0;
|
||||
sender_closer = sender_rank < curr_instance.dag.rank;
|
||||
loop_detected = (down && !sender_closer) || (!down && sender_closer);
|
||||
|
||||
|
@ -406,7 +349,7 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
|
||||
if(loop_detected) {
|
||||
/* Set forward error flag */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||
rpl_opt->flags |= RPL_HDR_OPT_RANK_ERR;
|
||||
}
|
||||
|
||||
return rpl_process_hbh(sender, sender_rank, loop_detected, rank_error_signaled);
|
||||
|
@ -418,34 +361,27 @@ rpl_ext_header_hbh_update(int uip_ext_opt_offset)
|
|||
static int
|
||||
update_hbh_header(void)
|
||||
{
|
||||
int uip_ext_opt_offset;
|
||||
int last_uip_ext_len;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(UIP_IP_PAYLOAD(2));
|
||||
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO && rpl_opt->opt_type == UIP_EXT_HDR_OPT_RPL) {
|
||||
if(hbh_hdr->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| rpl_opt->opt_len != RPL_HDR_OPT_LEN) {
|
||||
|
||||
if(UIP_IP_BUF->proto == UIP_PROTO_HBHO && UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL) {
|
||||
if(UIP_HBHO_BUF->len != ((RPL_HOP_BY_HOP_LEN - 8) / 8)
|
||||
|| UIP_EXT_HDR_OPT_RPL_BUF->opt_len != RPL_HDR_OPT_LEN) {
|
||||
|
||||
LOG_ERR("hop-by-hop extension header has wrong size (%u %u)\n",
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len, uip_ext_len);
|
||||
LOG_ERR("hop-by-hop extension header has wrong size (%u)\n", rpl_opt->opt_len);
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
if(!curr_instance.used || curr_instance.instance_id != UIP_EXT_HDR_OPT_RPL_BUF->instance) {
|
||||
if(!curr_instance.used || curr_instance.instance_id != rpl_opt->instance) {
|
||||
LOG_ERR("unable to add/update hop-by-hop extension header: incorrect instance\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0; /* Drop */
|
||||
}
|
||||
|
||||
/* Update sender rank and instance, will update flags next */
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(curr_instance.dag.rank);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = curr_instance.instance_id;
|
||||
rpl_opt->senderrank = UIP_HTONS(curr_instance.dag.rank);
|
||||
rpl_opt->instance = curr_instance.instance_id;
|
||||
}
|
||||
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -456,45 +392,34 @@ update_hbh_header(void)
|
|||
static int
|
||||
insert_hbh_header(void)
|
||||
{
|
||||
int uip_ext_opt_offset;
|
||||
int last_uip_ext_len;
|
||||
uint8_t temp_len;
|
||||
|
||||
last_uip_ext_len = uip_ext_len;
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
struct uip_hbho_hdr *hbh_hdr = (struct uip_hbho_hdr *)UIP_IP_PAYLOAD(0);
|
||||
struct uip_ext_hdr_opt_rpl *rpl_opt = (struct uip_ext_hdr_opt_rpl *)(UIP_IP_PAYLOAD(2));
|
||||
|
||||
/* Insert hop-by-hop header */
|
||||
LOG_INFO("creating hop-by-hop option\n");
|
||||
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_BUFSIZE - UIP_LLH_LEN) {
|
||||
if(uip_len + RPL_HOP_BY_HOP_LEN > UIP_LINK_MTU) {
|
||||
LOG_ERR("packet too long: impossible to add hop-by-hop option\n");
|
||||
uip_ext_len = last_uip_ext_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move existing ext headers and payload UIP_EXT_BUF further */
|
||||
memmove(UIP_HBHO_NEXT_BUF, UIP_EXT_BUF, uip_len - UIP_IPH_LEN);
|
||||
memset(UIP_HBHO_BUF, 0, RPL_HOP_BY_HOP_LEN);
|
||||
/* Move existing ext headers and payload RPL_HOP_BY_HOP_LEN further */
|
||||
memmove(UIP_IP_PAYLOAD(RPL_HOP_BY_HOP_LEN), UIP_IP_PAYLOAD(0), uip_len - UIP_IPH_LEN);
|
||||
memset(UIP_IP_PAYLOAD(0), 0, RPL_HOP_BY_HOP_LEN);
|
||||
|
||||
/* Update IP and HBH protocol and fields */
|
||||
UIP_HBHO_BUF->next = UIP_IP_BUF->proto;
|
||||
/* Insert HBH header (as first ext header) */
|
||||
hbh_hdr->next = UIP_IP_BUF->proto;
|
||||
UIP_IP_BUF->proto = UIP_PROTO_HBHO;
|
||||
|
||||
/* Initialize HBH option */
|
||||
UIP_HBHO_BUF->len = (RPL_HOP_BY_HOP_LEN - 8) / 8;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_type = UIP_EXT_HDR_OPT_RPL;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->opt_len = RPL_HDR_OPT_LEN;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->flags = 0;
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->senderrank = UIP_HTONS(curr_instance.dag.rank);
|
||||
UIP_EXT_HDR_OPT_RPL_BUF->instance = curr_instance.instance_id;
|
||||
uip_len += RPL_HOP_BY_HOP_LEN;
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
UIP_IP_BUF->len[1] += RPL_HOP_BY_HOP_LEN;
|
||||
if(UIP_IP_BUF->len[1] < temp_len) {
|
||||
UIP_IP_BUF->len[0]++;
|
||||
}
|
||||
hbh_hdr->len = (RPL_HOP_BY_HOP_LEN - 8) / 8;
|
||||
rpl_opt->opt_type = UIP_EXT_HDR_OPT_RPL;
|
||||
rpl_opt->opt_len = RPL_HDR_OPT_LEN;
|
||||
rpl_opt->flags = 0;
|
||||
rpl_opt->senderrank = UIP_HTONS(curr_instance.dag.rank);
|
||||
rpl_opt->instance = curr_instance.instance_id;
|
||||
|
||||
uip_ext_len = last_uip_ext_len + RPL_HOP_BY_HOP_LEN;
|
||||
uipbuf_add_ext_hdr(RPL_HOP_BY_HOP_LEN);
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
|
||||
/* Update header before returning */
|
||||
return update_hbh_header();
|
||||
|
@ -531,54 +456,34 @@ rpl_ext_header_update(void)
|
|||
void
|
||||
rpl_ext_header_remove(void)
|
||||
{
|
||||
uint8_t temp_len;
|
||||
uint8_t rpl_ext_hdr_len;
|
||||
int uip_ext_opt_offset;
|
||||
uint8_t *uip_next_hdr;
|
||||
uint8_t *prev_proto_ptr;
|
||||
uint8_t protocol;
|
||||
uint8_t ext_len;
|
||||
uint8_t *next_header;
|
||||
struct uip_ext_hdr *ext_ptr;
|
||||
struct uip_ext_hdr_opt *opt_ptr;
|
||||
|
||||
uip_ext_len = 0;
|
||||
uip_ext_opt_offset = 2;
|
||||
uip_next_hdr = &UIP_IP_BUF->proto;
|
||||
|
||||
/* Look for hop-by-hop and routing headers */
|
||||
while(uip_next_hdr != NULL) {
|
||||
switch(*uip_next_hdr) {
|
||||
case UIP_PROTO_HBHO:
|
||||
case UIP_PROTO_ROUTING:
|
||||
if((*uip_next_hdr != UIP_PROTO_HBHO || UIP_EXT_HDR_OPT_RPL_BUF->opt_type == UIP_EXT_HDR_OPT_RPL)) {
|
||||
/* Remove hop-by-hop and routing headers */
|
||||
*uip_next_hdr = UIP_EXT_BUF->next;
|
||||
rpl_ext_hdr_len = (UIP_EXT_BUF->len * 8) + 8;
|
||||
temp_len = UIP_IP_BUF->len[1];
|
||||
uip_len -= rpl_ext_hdr_len;
|
||||
UIP_IP_BUF->len[1] -= rpl_ext_hdr_len;
|
||||
if(UIP_IP_BUF->len[1] > temp_len) {
|
||||
UIP_IP_BUF->len[0]--;
|
||||
}
|
||||
LOG_INFO("removing RPL extension header (type %u, len %u)\n", *uip_next_hdr, rpl_ext_hdr_len);
|
||||
memmove(UIP_EXT_BUF, ((uint8_t *)UIP_EXT_BUF) + rpl_ext_hdr_len, uip_len - UIP_IPH_LEN);
|
||||
} else {
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
}
|
||||
break;
|
||||
case UIP_PROTO_DESTO:
|
||||
/*
|
||||
* As per RFC 2460, any header other than the Destination
|
||||
* Options header does not appear between the Hop-by-Hop
|
||||
* Options header and the Routing header.
|
||||
*
|
||||
* We're moving to the next header only if uip_next_hdr has
|
||||
* UIP_PROTO_DESTO. Otherwise, we'll return.
|
||||
*/
|
||||
/* Move to next header */
|
||||
uip_next_hdr = &UIP_EXT_BUF->next;
|
||||
uip_ext_len += (UIP_EXT_BUF->len << 3) + 8;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
next_header = uipbuf_get_next_header(uip_buf, uip_len, &protocol, true);
|
||||
ext_ptr = (struct uip_ext_hdr *)next_header;
|
||||
prev_proto_ptr = &UIP_IP_BUF->proto;
|
||||
while(next_header != NULL && uip_is_proto_ext_hdr(protocol)) {
|
||||
opt_ptr = (struct uip_ext_hdr_opt *)(next_header + 2);
|
||||
if(protocol == UIP_PROTO_ROUTING || (protocol == UIP_PROTO_HBHO && opt_ptr->type == UIP_EXT_HDR_OPT_RPL)) {
|
||||
/* Remove ext header */
|
||||
*prev_proto_ptr = ext_ptr->next;
|
||||
ext_len = ext_ptr->len * 8 + 8;
|
||||
uipbuf_add_ext_hdr(-ext_len);
|
||||
/* Update length field and move rest of packet to the "left" */
|
||||
uipbuf_set_len_field(UIP_IP_BUF, uip_len - UIP_IPH_LEN);
|
||||
memmove(next_header, next_header + ext_len, uip_len - (next_header - uip_buf));
|
||||
/* Update loop variables */
|
||||
protocol = *prev_proto_ptr;
|
||||
} else {
|
||||
/* move to the ext hdr */
|
||||
next_header = uipbuf_get_next_header(next_header, uip_len - (next_header - uip_buf), &protocol, false);
|
||||
ext_ptr = (struct uip_ext_hdr *)next_header;
|
||||
prev_proto_ptr = &ext_ptr->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @}*/
|
||||
|
|
|
@ -63,12 +63,13 @@ int rpl_ext_header_srh_update(void);
|
|||
* Process and update the RPL hop-by-hop extension headers of
|
||||
* the current uIP packet.
|
||||
*
|
||||
* \param uip_ext_opt_offset The offset within the uIP packet where
|
||||
* extension headers start
|
||||
* \param ext_buf A pointer to the ext header buffer
|
||||
* \param opt_offset The offset within the extension header where
|
||||
* the option starts
|
||||
* \return 1 in case the packet is valid and to be processed further,
|
||||
* 0 in case the packet must be dropped.
|
||||
*/
|
||||
int rpl_ext_header_hbh_update(int uip_ext_opt_offset);
|
||||
int rpl_ext_header_hbh_update(uint8_t *ext_buf, int opt_offset);
|
||||
|
||||
/**
|
||||
* Adds/updates all RPL extension headers to current uIP packet.
|
||||
|
|
|
@ -62,10 +62,6 @@
|
|||
#define RPL_DIO_MOP_MASK 0x38
|
||||
#define RPL_DIO_PREFERENCE_MASK 0x07
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#define UIP_ICMP_PAYLOAD ((unsigned char *)&uip_buf[uip_l2_l3_icmp_hdr_len])
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void dis_input(void);
|
||||
static void dio_input(void);
|
||||
|
@ -147,7 +143,7 @@ dis_input(void)
|
|||
rpl_process_dis(&UIP_IP_BUF->srcipaddr, uip_is_addr_mcast(&UIP_IP_BUF->destipaddr));
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -329,7 +325,7 @@ dio_input(void)
|
|||
rpl_process_dio(&from, &dio);
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -540,7 +536,7 @@ dao_input(void)
|
|||
rpl_process_dao(&from, &dao);
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
@ -651,7 +647,7 @@ dao_ack_input(void)
|
|||
rpl_process_dao_ack(sequence, status);
|
||||
|
||||
discard:
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
|
|
|
@ -59,7 +59,6 @@
|
|||
* NOTE: this policy assumes that all neighbors end up being IPv6
|
||||
* neighbors and are not only MAC neighbors.
|
||||
*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
static int num_parents; /* all nodes that are possible parents */
|
||||
static int num_free;
|
||||
|
|
|
@ -139,7 +139,7 @@ ip64_arp_timer(void)
|
|||
{
|
||||
struct arp_entry *tabptr;
|
||||
int i;
|
||||
|
||||
|
||||
++arptime;
|
||||
for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
|
||||
tabptr = &arp_table[i];
|
||||
|
@ -157,7 +157,7 @@ arp_update(uip_ip4addr_t *ipaddr, struct uip_eth_addr *ethaddr)
|
|||
{
|
||||
register struct arp_entry *tabptr = arp_table;
|
||||
int i, c;
|
||||
|
||||
|
||||
/* Walk through the ARP mapping table and try to find an entry to
|
||||
update. If none is found, the IP -> MAC address mapping is
|
||||
inserted in the ARP table. */
|
||||
|
@ -170,7 +170,7 @@ arp_update(uip_ip4addr_t *ipaddr, struct uip_eth_addr *ethaddr)
|
|||
/* Check if the source IP address of the incoming packet matches
|
||||
the IP address in this ARP table entry. */
|
||||
if(uip_ip4addr_cmp(ipaddr, &tabptr->ipaddr)) {
|
||||
|
||||
|
||||
/* An old entry found, update this and return. */
|
||||
memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
|
||||
tabptr->time = arptime;
|
||||
|
@ -239,7 +239,7 @@ ip64_arp_arp_input(const uint8_t *packet, uint16_t packet_len)
|
|||
table, since it is likely that we will do more communication
|
||||
with this host in the future. */
|
||||
arp_update(&arphdr->sipaddr, &arphdr->shwaddr);
|
||||
|
||||
|
||||
arphdr->opcode = UIP_HTONS(ARP_REPLY);
|
||||
|
||||
memcpy(arphdr->dhwaddr.addr, arphdr->shwaddr.addr, 6);
|
||||
|
@ -275,7 +275,7 @@ ip64_arp_check_cache(const uint8_t *nlhdr)
|
|||
|
||||
printf("check cache %d.%d.%d.%d\n",
|
||||
uip_ipaddr_to_quad(&ipv4_hdr->destipaddr));
|
||||
|
||||
|
||||
/* First check if destination is a local broadcast. */
|
||||
uip_ipaddr(&broadcast_addr, 255,255,255,255);
|
||||
if(uip_ip4addr_cmp(&ipv4_hdr->destipaddr, &broadcast_addr)) {
|
||||
|
@ -321,7 +321,7 @@ ip64_arp_create_ethhdr(uint8_t *llhdr, const uint8_t *nlhdr)
|
|||
struct ipv4_hdr *ipv4_hdr = (struct ipv4_hdr *)nlhdr;
|
||||
struct ip64_eth_hdr *ethhdr = (struct ip64_eth_hdr *)llhdr;
|
||||
uip_ip4addr_t broadcast_addr;
|
||||
|
||||
|
||||
/* Find the destination IP address in the ARP table and construct
|
||||
the Ethernet header. If the destination IP addres isn't on the
|
||||
local network, we use the default router's IP address instead.
|
||||
|
@ -371,7 +371,7 @@ ip64_arp_create_ethhdr(uint8_t *llhdr, const uint8_t *nlhdr)
|
|||
|
||||
}
|
||||
memcpy(ethhdr->src.addr, ip64_eth_addr.addr, 6);
|
||||
|
||||
|
||||
ethhdr->type = UIP_HTONS(IP64_ETH_TYPE_IP);
|
||||
return sizeof(struct ip64_eth_hdr);
|
||||
}
|
||||
|
@ -382,7 +382,7 @@ ip64_arp_create_arp_request(uint8_t *llhdr, const uint8_t *nlhdr)
|
|||
struct ipv4_hdr *ipv4_hdr = (struct ipv4_hdr *)nlhdr;
|
||||
struct arp_hdr *arp_hdr = (struct arp_hdr *)llhdr;
|
||||
uip_ip4addr_t ipaddr;
|
||||
|
||||
|
||||
if(!uip_ipaddr_maskcmp(&ipv4_hdr->destipaddr,
|
||||
ip64_get_hostaddr(),
|
||||
ip64_get_netmask())) {
|
||||
|
@ -394,7 +394,7 @@ ip64_arp_create_arp_request(uint8_t *llhdr, const uint8_t *nlhdr)
|
|||
/* Else, we use the destination IP address. */
|
||||
uip_ip4addr_copy(&ipaddr, &ipv4_hdr->destipaddr);
|
||||
}
|
||||
|
||||
|
||||
memset(arp_hdr->ethhdr.dest.addr, 0xff, 6);
|
||||
memset(arp_hdr->dhwaddr.addr, 0x00, 6);
|
||||
memcpy(arp_hdr->ethhdr.src.addr, ip64_eth_addr.addr, 6);
|
||||
|
@ -408,8 +408,8 @@ ip64_arp_create_arp_request(uint8_t *llhdr, const uint8_t *nlhdr)
|
|||
arp_hdr->hwlen = 6;
|
||||
arp_hdr->protolen = 4;
|
||||
arp_hdr->ethhdr.type = UIP_HTONS(IP64_ETH_TYPE_ARP);
|
||||
|
||||
uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
|
||||
|
||||
uip_appdata = &uip_buf[UIP_IPTCPH_LEN];
|
||||
|
||||
return sizeof(struct arp_hdr);
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ struct dhcp_msg {
|
|||
uint8_t options[312];
|
||||
};
|
||||
|
||||
#if (UIP_BUFSIZE - UIP_LLH_LEN - UIP_UDPIP_HLEN) < 548
|
||||
#if (UIP_BUFSIZE - UIP_UDPIP_HLEN) < 548
|
||||
#error UIP_CONF_BUFFER_SIZE may be too small to accomodate DHCPv4 packets
|
||||
#error Increase UIP_CONF_BUFFER_SIZE in your project-conf.h, or contiki-conf.h
|
||||
#error A good size is 600 bytes
|
||||
|
@ -191,12 +191,12 @@ send_request(void)
|
|||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
|
||||
create_msg(m);
|
||||
|
||||
|
||||
end = add_msg_type(&m->options[4], DHCPREQUEST);
|
||||
end = add_server_id(end);
|
||||
end = add_req_ipaddr(end);
|
||||
end = add_end(end);
|
||||
|
||||
|
||||
uip_send(uip_appdata, (int)(end - (uint8_t *)uip_appdata));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -239,7 +239,7 @@ static uint8_t
|
|||
parse_msg(void)
|
||||
{
|
||||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
|
||||
|
||||
if(m->op == DHCP_REPLY &&
|
||||
memcmp(m->xid, &xid, sizeof(xid)) == 0 &&
|
||||
memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
|
||||
|
@ -258,7 +258,7 @@ msg_for_me(void)
|
|||
struct dhcp_msg *m = (struct dhcp_msg *)uip_appdata;
|
||||
uint8_t *optptr = &m->options[4];
|
||||
uint8_t *end = (uint8_t*)uip_appdata + uip_datalen();
|
||||
|
||||
|
||||
if(m->op == DHCP_REPLY &&
|
||||
memcmp(m->xid, &xid, sizeof(xid)) == 0 &&
|
||||
memcmp(m->chaddr, s.mac_addr, s.mac_len) == 0) {
|
||||
|
@ -280,7 +280,7 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
clock_time_t ticks;
|
||||
|
||||
PT_BEGIN(&s.pt);
|
||||
|
||||
|
||||
init:
|
||||
xid++;
|
||||
s.state = STATE_SENDING;
|
||||
|
@ -305,7 +305,7 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
s.ticks *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
selecting:
|
||||
s.ticks = CLOCK_SECOND;
|
||||
do {
|
||||
|
@ -330,7 +330,7 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
goto init;
|
||||
}
|
||||
} while(s.state != STATE_CONFIG_RECEIVED);
|
||||
|
||||
|
||||
bound:
|
||||
#if 0
|
||||
printf("Got IP address %d.%d.%d.%d\n", uip_ipaddr_to_quad(&s.ipaddr));
|
||||
|
@ -343,7 +343,7 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
|||
#endif
|
||||
|
||||
ip64_dhcpc_configured(&s);
|
||||
|
||||
|
||||
#define MAX_TICKS (~((clock_time_t)0) / 2)
|
||||
#define MAX_TICKS32 (~((uint32_t)0))
|
||||
#define IMIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
@ -407,12 +407,12 @@ ip64_dhcpc_init(const void *mac_addr, int mac_len)
|
|||
uip_ip6addr_t v6addr;
|
||||
uip_ip4addr_t v4addr;
|
||||
struct uip_udp_conn *conn2;
|
||||
|
||||
|
||||
s.mac_addr = mac_addr;
|
||||
s.mac_len = mac_len;
|
||||
|
||||
s.state = STATE_INITIAL;
|
||||
uip_ipaddr(&v4addr, 255,255,255,255);
|
||||
uip_ipaddr(&v4addr, 255,255,255,255);
|
||||
ip64_addr_4to6(&v4addr, &v6addr);
|
||||
s.conn = udp_new(&v6addr, UIP_HTONS(IP64_DHCPC_SERVER_PORT), NULL);
|
||||
conn2 = udp_new(NULL, UIP_HTONS(IP64_DHCPC_SERVER_PORT), NULL);
|
||||
|
@ -437,7 +437,7 @@ void
|
|||
ip64_dhcpc_request(void)
|
||||
{
|
||||
uip_ipaddr_t ipaddr;
|
||||
|
||||
|
||||
if(s.state == STATE_INITIAL) {
|
||||
uip_ipaddr(&ipaddr, 0,0,0,0);
|
||||
uip_sethostaddr(&ipaddr);
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/ipv6/uip-debug.h"
|
||||
#define printf(...)
|
||||
|
@ -62,7 +60,7 @@ ip64_eth_interface_input(uint8_t *packet, uint16_t len)
|
|||
printf("-------------->\n");
|
||||
uip_len = ip64_4to6(&packet[sizeof(struct ip64_eth_hdr)],
|
||||
len - sizeof(struct ip64_eth_hdr),
|
||||
&uip_buf[UIP_LLH_LEN]);
|
||||
uip_buf);
|
||||
if(uip_len > 0) {
|
||||
printf("ip64_interface_process: converted %d bytes\n", uip_len);
|
||||
|
||||
|
@ -96,7 +94,7 @@ output(void)
|
|||
PRINTF("\n");
|
||||
|
||||
printf("<--------------\n");
|
||||
len = ip64_6to4(&uip_buf[UIP_LLH_LEN], uip_len,
|
||||
len = ip64_6to4(uip_buf, uip_len,
|
||||
&ip64_packet_buffer[sizeof(struct ip64_eth_hdr)]);
|
||||
|
||||
printf("ip64-interface: output len %d\n", len);
|
||||
|
|
|
@ -38,8 +38,6 @@
|
|||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#define DEBUG DEBUG_NONE
|
||||
#include "net/ipv6/uip-debug.h"
|
||||
|
||||
|
@ -57,24 +55,24 @@ static void
|
|||
input_callback(void)
|
||||
{
|
||||
/*PRINTF("SIN: %u\n", uip_len);*/
|
||||
if(uip_buf[UIP_LLH_LEN] == '!') {
|
||||
PRINTF("Got configuration message of type %c\n", uip_buf[UIP_LLH_LEN + 1]);
|
||||
uip_clear_buf();
|
||||
if(uip_buf[0] == '!') {
|
||||
PRINTF("Got configuration message of type %c\n", uip_buf[1]);
|
||||
uipbuf_clear();
|
||||
#if 0
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'P') {
|
||||
if(uip_buf[1] == 'P') {
|
||||
uip_ipaddr_t prefix;
|
||||
/* Here we set a prefix !!! */
|
||||
memset(&prefix, 0, 16);
|
||||
memcpy(&prefix, &uip_buf[UIP_LLH_LEN + 2], 8);
|
||||
memcpy(&prefix, &uip_buf[2], 8);
|
||||
PRINTF("Setting prefix ");
|
||||
PRINT6ADDR(&prefix);
|
||||
PRINTF("\n");
|
||||
set_prefix_64(&prefix);
|
||||
}
|
||||
#endif
|
||||
} else if(uip_buf[UIP_LLH_LEN] == '?') {
|
||||
PRINTF("Got request message of type %c\n", uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'M') {
|
||||
} else if(uip_buf[0] == '?') {
|
||||
PRINTF("Got request message of type %c\n", uip_buf[1]);
|
||||
if(uip_buf[1] == 'M') {
|
||||
const char *hexchar = "0123456789abcdef";
|
||||
int j;
|
||||
/* this is just a test so far... just to see if it works */
|
||||
|
@ -86,21 +84,21 @@ input_callback(void)
|
|||
uip_len = 18;
|
||||
slip_write(uip_buf, uip_len);
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
} else {
|
||||
|
||||
|
||||
/* Save the last sender received over SLIP to avoid bouncing the
|
||||
packet back if no route is found */
|
||||
uip_ipaddr_copy(&last_sender, &UIP_IP_BUF->srcipaddr);
|
||||
|
||||
uint16_t len = ip64_4to6(&uip_buf[UIP_LLH_LEN], uip_len,
|
||||
|
||||
uint16_t len = ip64_4to6(uip_buf, uip_len,
|
||||
ip64_packet_buffer);
|
||||
if(len > 0) {
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], ip64_packet_buffer, len);
|
||||
memcpy(uip_buf, ip64_packet_buffer, len);
|
||||
uip_len = len;
|
||||
/* PRINTF("send len %d\n", len); */
|
||||
} else {
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -129,11 +127,11 @@ output(void)
|
|||
if(uip_ipaddr_cmp(&last_sender, &UIP_IP_BUF->srcipaddr)) {
|
||||
PRINTF("ip64-interface: output, not sending bounced message\n");
|
||||
} else {
|
||||
len = ip64_6to4(&uip_buf[UIP_LLH_LEN], uip_len,
|
||||
len = ip64_6to4(uip_buf, uip_len,
|
||||
ip64_packet_buffer);
|
||||
PRINTF("ip64-interface: output len %d\n", len);
|
||||
if(len > 0) {
|
||||
memcpy(&uip_buf[UIP_LLH_LEN], ip64_packet_buffer, len);
|
||||
memcpy(uip_buf, ip64_packet_buffer, len);
|
||||
uip_len = len;
|
||||
slip_send();
|
||||
return len;
|
||||
|
|
|
@ -43,8 +43,6 @@
|
|||
#include "dev/slip.h"
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Log configuration */
|
||||
#include "sys/log.h"
|
||||
#define LOG_MODULE "SLIP"
|
||||
|
@ -63,34 +61,34 @@ request_prefix(void)
|
|||
uip_buf[1] = 'P';
|
||||
uip_len = 2;
|
||||
slip_write(uip_buf, uip_len);
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
slip_input_callback(void)
|
||||
{
|
||||
LOG_DBG("SIN: %u\n", uip_len);
|
||||
if(uip_buf[UIP_LLH_LEN] == '!') {
|
||||
if(uip_buf[0] == '!') {
|
||||
LOG_INFO("Got configuration message of type %c\n",
|
||||
uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'P') {
|
||||
uip_buf[1]);
|
||||
if(uip_buf[1] == 'P') {
|
||||
uip_ipaddr_t prefix;
|
||||
/* Here we set a prefix !!! */
|
||||
memset(&prefix, 0, 16);
|
||||
memcpy(&prefix, &uip_buf[UIP_LLH_LEN + 2], 8);
|
||||
memcpy(&prefix, &uip_buf[2], 8);
|
||||
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
|
||||
LOG_INFO("Setting prefix ");
|
||||
LOG_INFO_6ADDR(&prefix);
|
||||
LOG_INFO_("\n");
|
||||
set_prefix_64(&prefix);
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
|
||||
} else if(uip_buf[UIP_LLH_LEN] == '?') {
|
||||
LOG_INFO("Got request message of type %c\n", uip_buf[UIP_LLH_LEN + 1]);
|
||||
if(uip_buf[UIP_LLH_LEN + 1] == 'M') {
|
||||
} else if(uip_buf[0] == '?') {
|
||||
LOG_INFO("Got request message of type %c\n", uip_buf[1]);
|
||||
if(uip_buf[1] == 'M') {
|
||||
char *hexchar = "0123456789abcdef";
|
||||
int j;
|
||||
/* this is just a test so far... just to see if it works */
|
||||
|
@ -102,7 +100,7 @@ slip_input_callback(void)
|
|||
uip_len = 18;
|
||||
slip_write(uip_buf, uip_len);
|
||||
}
|
||||
uip_clear_buf();
|
||||
uipbuf_clear();
|
||||
} else {
|
||||
/* Save the last sender received over SLIP to avoid bouncing the
|
||||
packet back if no route is found */
|
||||
|
|
|
@ -256,7 +256,7 @@ output(void)
|
|||
{
|
||||
LOG_DBG("SUT: %u\n", uip_len);
|
||||
if(uip_len > 0) {
|
||||
return tun_output(&uip_buf[UIP_LLH_LEN], uip_len);
|
||||
return tun_output(uip_buf, uip_len);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -298,7 +298,7 @@ handle_fd(fd_set *rset, fd_set *wset)
|
|||
int size;
|
||||
|
||||
if(FD_ISSET(tunfd, rset)) {
|
||||
size = tun_input(&uip_buf[UIP_LLH_LEN], sizeof(uip_buf));
|
||||
size = tun_input(uip_buf, sizeof(uip_buf));
|
||||
/* printf("TUN data incoming read:%d\n", size); */
|
||||
uip_len = size;
|
||||
tcpip_input();
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
ifdef CONTIKI_HOME
|
||||
CONTIKI = $(CONTIKI_HOME)
|
||||
else
|
||||
ifndef CONTIKI
|
||||
CONTIKI=../../..
|
||||
endif
|
||||
endif
|
||||
|
||||
DEFINES=WITH_SLIP=1
|
||||
|
||||
ifndef TARGET
|
||||
TARGET=sky
|
||||
endif
|
||||
|
||||
MODULES_REL += dev
|
||||
PROJECT_SOURCEFILES = fakeuip.c sicslow_ethernet.c
|
||||
|
||||
all: uip6-bridge-tap.sky
|
||||
|
||||
upload: uip6-bridge-tap.ihex
|
||||
cp $< $(IHEXFILE)
|
||||
$(MAKE) sky-u.$(subst /,-,$(word $(MOTE), $(MOTES)))
|
||||
|
||||
include $(CONTIKI)/Makefile.include
|
||||
|
||||
../../tapslip6: ../../tapslip6.c
|
||||
(cd ../../; $(MAKE) tapslip6)
|
||||
|
||||
ifndef MOTE
|
||||
MOTE=1
|
||||
endif
|
||||
|
||||
connect: ../../tapslip6
|
||||
sudo ../../tapslip6 -t tap0 -s $(USBDEVPREFIX)$(word $(MOTE), $(CMOTES)) 127.0.0.1 255.0.0.0
|
||||
|
||||
bridge:
|
||||
@sudo service radvd restart || echo radvd could not be restarted
|
||||
sudo route add -6 fd00::/64 tap0
|
||||
sudo ip -6 address add fd00::1/64 dev tap0
|
|
@ -1,323 +0,0 @@
|
|||
/* -*- C -*- */
|
||||
/*
|
||||
* Copyright (c) 2005, Swedish Institute of Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "dev/ds2411/ds2411.h"
|
||||
#include "contiki.h"
|
||||
|
||||
#include "net/ipv6/uip.h"
|
||||
#define BUF ((struct uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
#include "dev/slip.h"
|
||||
|
||||
#define SLIP_END 0300
|
||||
#define SLIP_ESC 0333
|
||||
#define SLIP_ESC_END 0334
|
||||
#define SLIP_ESC_ESC 0335
|
||||
|
||||
PROCESS(slip_process, "SLIP driver");
|
||||
|
||||
uint8_t slip_active;
|
||||
|
||||
#if 1
|
||||
#define SLIP_STATISTICS(statement)
|
||||
#else
|
||||
uint16_t slip_rubbish, slip_twopackets, slip_overflow, slip_ip_drop;
|
||||
#define SLIP_STATISTICS(statement) statement
|
||||
#endif
|
||||
|
||||
/* Must be at least one byte larger than UIP_BUFSIZE! */
|
||||
#define RX_BUFSIZE (UIP_BUFSIZE - UIP_LLH_LEN + 16)
|
||||
|
||||
enum {
|
||||
STATE_TWOPACKETS = 0, /* We have 2 packets and drop incoming data. */
|
||||
STATE_OK = 1,
|
||||
STATE_ESC = 2,
|
||||
STATE_RUBBISH = 3,
|
||||
};
|
||||
|
||||
/*
|
||||
* Variables begin and end manage the buffer space in a cyclic
|
||||
* fashion. The first used byte is at begin and end is one byte past
|
||||
* the last. I.e. [begin, end) is the actively used space.
|
||||
*
|
||||
* If begin != pkt_end we have a packet at [begin, pkt_end),
|
||||
* furthermore, if state == STATE_TWOPACKETS we have one more packet at
|
||||
* [pkt_end, end). If more bytes arrive in state STATE_TWOPACKETS
|
||||
* they are discarded.
|
||||
*/
|
||||
|
||||
static uint8_t state = STATE_TWOPACKETS;
|
||||
static uint16_t begin, end;
|
||||
static uint8_t rxbuf[RX_BUFSIZE];
|
||||
static uint16_t pkt_end; /* SLIP_END tracker. */
|
||||
|
||||
static void (* input_callback)(void) = NULL;
|
||||
static void (* tcpip_input_callback)(void) = NULL;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
slip_set_input_callback(void (*c)(void))
|
||||
{
|
||||
input_callback = c;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
slip_set_tcpip_input_callback(void (*c)(void))
|
||||
{
|
||||
tcpip_input_callback = c;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
slip_write(const void *_ptr, int len)
|
||||
{
|
||||
const uint8_t *ptr = _ptr;
|
||||
uint16_t i;
|
||||
uint8_t c;
|
||||
|
||||
slip_arch_writeb(SLIP_END);
|
||||
|
||||
for(i = 0; i < len; ++i) {
|
||||
c = *ptr++;
|
||||
if(c == SLIP_END) {
|
||||
slip_arch_writeb(SLIP_ESC);
|
||||
c = SLIP_ESC_END;
|
||||
} else if(c == SLIP_ESC) {
|
||||
slip_arch_writeb(SLIP_ESC);
|
||||
c = SLIP_ESC_ESC;
|
||||
}
|
||||
slip_arch_writeb(c);
|
||||
}
|
||||
slip_arch_writeb(SLIP_END);
|
||||
|
||||
return len;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
rxbuf_init(void)
|
||||
{
|
||||
begin = end = pkt_end = 0;
|
||||
state = STATE_OK;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Upper half does the polling. */
|
||||
static uint16_t
|
||||
slip_poll_handler(uint8_t *outbuf, uint16_t blen)
|
||||
{
|
||||
/* This is a hack and won't work across buffer edge! */
|
||||
if(rxbuf[begin] == 'C') {
|
||||
int i;
|
||||
if(begin < end && (end - begin) >= 6
|
||||
&& memcmp(&rxbuf[begin], "CLIENT", 6) == 0) {
|
||||
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
|
||||
memset(&rxbuf[begin], 0x0, 6);
|
||||
|
||||
rxbuf_init();
|
||||
|
||||
for(i = 0; i < 13; i++) {
|
||||
slip_arch_writeb("CLIENTSERVER\300"[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
} else if(rxbuf[begin] == '?') {
|
||||
int i, j;
|
||||
char* hexchar = "0123456789abcdef";
|
||||
if(begin < end && (end - begin) >= 2
|
||||
&& rxbuf[begin + 1] == 'M') {
|
||||
state = STATE_TWOPACKETS; /* Interrupts do nothing. */
|
||||
rxbuf[begin] = 0;
|
||||
rxbuf[begin + 1] = 0;
|
||||
|
||||
rxbuf_init();
|
||||
|
||||
/* this is just a test so far... just to see if it works */
|
||||
slip_arch_writeb('!');
|
||||
slip_arch_writeb('M');
|
||||
for(j = 0; j < 8; j++) {
|
||||
slip_arch_writeb(hexchar[ds2411_id[j] >> 4]);
|
||||
slip_arch_writeb(hexchar[ds2411_id[j] & 15]);
|
||||
}
|
||||
slip_arch_writeb(SLIP_END);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Interrupt can not change begin but may change pkt_end.
|
||||
* If pkt_end != begin it will not change again.
|
||||
*/
|
||||
if(begin != pkt_end) {
|
||||
uint16_t len;
|
||||
|
||||
if(begin < pkt_end) {
|
||||
len = pkt_end - begin;
|
||||
if(len > blen) {
|
||||
len = 0;
|
||||
} else {
|
||||
memcpy(outbuf, &rxbuf[begin], len);
|
||||
}
|
||||
} else {
|
||||
len = (RX_BUFSIZE - begin) + (pkt_end - 0);
|
||||
if(len > blen) {
|
||||
len = 0;
|
||||
} else {
|
||||
unsigned i;
|
||||
for(i = begin; i < RX_BUFSIZE; i++) {
|
||||
*outbuf++ = rxbuf[i];
|
||||
}
|
||||
for(i = 0; i < pkt_end; i++) {
|
||||
*outbuf++ = rxbuf[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove data from buffer together with the copied packet. */
|
||||
begin = pkt_end;
|
||||
if(state == STATE_TWOPACKETS) {
|
||||
pkt_end = end;
|
||||
state = STATE_OK; /* Assume no bytes where lost! */
|
||||
|
||||
/* One more packet is buffered, need to be polled again! */
|
||||
process_poll(&slip_process);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(slip_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
rxbuf_init();
|
||||
|
||||
while(1) {
|
||||
PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL);
|
||||
|
||||
slip_active = 1;
|
||||
|
||||
/* Move packet from rxbuf to buffer provided by uIP. */
|
||||
uip_len = slip_poll_handler(&uip_buf[UIP_LLH_LEN],
|
||||
UIP_BUFSIZE - UIP_LLH_LEN);
|
||||
if(uip_len > 0) {
|
||||
if(tcpip_input_callback) {
|
||||
tcpip_input_callback();
|
||||
} else {
|
||||
tcpip_input();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
slip_input_byte(unsigned char c)
|
||||
{
|
||||
switch(state) {
|
||||
case STATE_RUBBISH:
|
||||
if(c == SLIP_END) {
|
||||
state = STATE_OK;
|
||||
}
|
||||
return 0;
|
||||
|
||||
case STATE_TWOPACKETS: /* Two packets are already buffered! */
|
||||
return 0;
|
||||
|
||||
case STATE_ESC:
|
||||
if(c == SLIP_ESC_END) {
|
||||
c = SLIP_END;
|
||||
} else if(c == SLIP_ESC_ESC) {
|
||||
c = SLIP_ESC;
|
||||
} else {
|
||||
state = STATE_RUBBISH;
|
||||
SLIP_STATISTICS(slip_rubbish++);
|
||||
end = pkt_end; /* remove rubbish */
|
||||
return 0;
|
||||
}
|
||||
state = STATE_OK;
|
||||
break;
|
||||
|
||||
case STATE_OK:
|
||||
if(c == SLIP_ESC) {
|
||||
state = STATE_ESC;
|
||||
return 0;
|
||||
} else if(c == SLIP_END) {
|
||||
/*
|
||||
* We have a new packet, possibly of zero length.
|
||||
*
|
||||
* There may already be one packet buffered.
|
||||
*/
|
||||
if(end != pkt_end) { /* Non zero length. */
|
||||
if(begin == pkt_end) { /* None buffered. */
|
||||
pkt_end = end;
|
||||
} else {
|
||||
state = STATE_TWOPACKETS;
|
||||
SLIP_STATISTICS(slip_twopackets++);
|
||||
}
|
||||
process_poll(&slip_process);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* add_char: */
|
||||
{
|
||||
unsigned next;
|
||||
next = end + 1;
|
||||
if(next == RX_BUFSIZE) {
|
||||
next = 0;
|
||||
}
|
||||
if(next == begin) { /* rxbuf is full */
|
||||
state = STATE_RUBBISH;
|
||||
SLIP_STATISTICS(slip_overflow++);
|
||||
end = pkt_end; /* remove rubbish */
|
||||
return 0;
|
||||
}
|
||||
rxbuf[end] = c;
|
||||
end = next;
|
||||
}
|
||||
|
||||
/* There could be a separate poll routine for this. */
|
||||
if(c == 'T' && rxbuf[begin] == 'C') {
|
||||
process_poll(&slip_process);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -1,92 +0,0 @@
|
|||
/* -*- C -*- */
|
||||
/*
|
||||
* Copyright (c) 2005, Swedish Institute of Computer Science
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SLIP_H_
|
||||
#define SLIP_H_
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
PROCESS_NAME(slip_process);
|
||||
|
||||
/**
|
||||
* Send an IP packet from the uIP buffer with SLIP.
|
||||
*/
|
||||
uint8_t slip_send(void);
|
||||
|
||||
/**
|
||||
* Input a SLIP byte.
|
||||
*
|
||||
* This function is called by the RS232/SIO device driver to pass
|
||||
* incoming bytes to the SLIP driver. The function can be called from
|
||||
* an interrupt context.
|
||||
*
|
||||
* For systems using low-power CPU modes, the return value of the
|
||||
* function can be used to determine if the CPU should be woken up or
|
||||
* not. If the function returns non-zero, the CPU should be powered
|
||||
* up. If the function returns zero, the CPU can continue to be
|
||||
* powered down.
|
||||
*
|
||||
* \param c The data that is to be passed to the SLIP driver
|
||||
*
|
||||
* \return Non-zero if the CPU should be powered up, zero otherwise.
|
||||
*/
|
||||
int slip_input_byte(unsigned char c);
|
||||
|
||||
uint8_t slip_write(const void *ptr, int len);
|
||||
|
||||
/* Did we receive any bytes lately? */
|
||||
extern uint8_t slip_active;
|
||||
|
||||
/* Statistics. */
|
||||
extern uint16_t slip_rubbish, slip_twopackets, slip_overflow, slip_ip_drop;
|
||||
|
||||
/**
|
||||
* Set a function to be called when there is activity on the SLIP
|
||||
* interface; used for detecting if a node is a gateway node.
|
||||
*/
|
||||
void slip_set_input_callback(void (*callback)(void));
|
||||
|
||||
/**
|
||||
* Set a function to be called when a packet has been received.
|
||||
* Default is tcpip_input().
|
||||
*/
|
||||
void slip_set_tcpip_input_callback(void (*callback)(void));
|
||||
|
||||
/*
|
||||
* These machine dependent functions and an interrupt service routine
|
||||
* must be provided externally (slip_arch.c).
|
||||
*/
|
||||
void slip_arch_init(void);
|
||||
void slip_arch_writeb(unsigned char c);
|
||||
|
||||
#endif /* SLIP_H_ */
|
|
@ -1,136 +0,0 @@
|
|||
|
||||
/* Various stub functions and uIP variables other code might need to
|
||||
* compile. Allows you to save needing to compile all of uIP in just
|
||||
* to get a few things */
|
||||
|
||||
|
||||
#include "net/ipv6/uip.h"
|
||||
#include "net/ipv6/uip-ds6.h"
|
||||
#include <string.h>
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
uip_buf_t uip_aligned_buf;
|
||||
|
||||
uint16_t uip_len;
|
||||
|
||||
struct uip_stats uip_stat;
|
||||
|
||||
uip_lladdr_t uip_lladdr;
|
||||
|
||||
uint16_t uip_htons(uint16_t val) { return UIP_HTONS(val);}
|
||||
|
||||
uip_ds6_netif_t uip_ds6_if;
|
||||
|
||||
/********** UIP_DS6.c **********/
|
||||
|
||||
void
|
||||
uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, uip_lladdr_t *lladdr)
|
||||
{
|
||||
/* We consider only links with IEEE EUI-64 identifier or
|
||||
IEEE 48-bit MAC addresses */
|
||||
#if (UIP_LLADDR_LEN == 8)
|
||||
memcpy(ipaddr->u8 + 8, lladdr, UIP_LLADDR_LEN);
|
||||
ipaddr->u8[8] ^= 0x02;
|
||||
#elif (UIP_LLADDR_LEN == 6)
|
||||
memcpy(ipaddr->u8 + 8, lladdr, 3);
|
||||
ipaddr->u8[11] = 0xff;
|
||||
ipaddr->u8[12] = 0xfe;
|
||||
memcpy(ipaddr->u8 + 13, lladdr + 3, 3);
|
||||
ipaddr->u8[8] ^= 0x02;
|
||||
#else
|
||||
#error fakeuip.c cannot build interface address when UIP_LLADDR_LEN is not 6 or 8
|
||||
#endif
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* get a link local address -
|
||||
* state = -1 => any address is ok. Otherwise state = desired state of addr.
|
||||
* (TENTATIVE, PREFERRED, DEPRECATED)
|
||||
*/
|
||||
uip_ds6_addr_t *
|
||||
uip_ds6_get_link_local(int8_t state) {
|
||||
uip_ds6_addr_t *locaddr;
|
||||
for(locaddr = uip_ds6_if.addr_list;
|
||||
locaddr < uip_ds6_if.addr_list + UIP_DS6_ADDR_NB; locaddr++) {
|
||||
if((locaddr->isused) && (state == - 1 || locaddr->state == state)
|
||||
&& (uip_is_addr_linklocal(&locaddr->ipaddr))) {
|
||||
return locaddr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uip_ds6_addr_t *
|
||||
uip_ds6_addr_add(uip_ipaddr_t *ipaddr, unsigned long vlifetime, uint8_t type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
/********** UIP.c ****************/
|
||||
|
||||
static uint16_t
|
||||
chksum(uint16_t sum, const uint8_t *data, uint16_t len)
|
||||
{
|
||||
uint16_t t;
|
||||
const uint8_t *dataptr;
|
||||
const uint8_t *last_byte;
|
||||
|
||||
dataptr = data;
|
||||
last_byte = data + len - 1;
|
||||
|
||||
while(dataptr < last_byte) { /* At least two more bytes */
|
||||
t = (dataptr[0] << 8) + dataptr[1];
|
||||
sum += t;
|
||||
if(sum < t) {
|
||||
sum++; /* carry */
|
||||
}
|
||||
dataptr += 2;
|
||||
}
|
||||
|
||||
if(dataptr == last_byte) {
|
||||
t = (dataptr[0] << 8) + 0;
|
||||
sum += t;
|
||||
if(sum < t) {
|
||||
sum++; /* carry */
|
||||
}
|
||||
}
|
||||
|
||||
/* Return sum in host byte order. */
|
||||
return sum;
|
||||
}
|
||||
|
||||
static uint16_t
|
||||
upper_layer_chksum(uint8_t proto)
|
||||
{
|
||||
uint16_t upper_layer_len;
|
||||
uint16_t sum;
|
||||
|
||||
upper_layer_len = (((uint16_t)(UIP_IP_BUF->len[0]) << 8) + UIP_IP_BUF->len[1]) ;
|
||||
|
||||
/* First sum pseudoheader. */
|
||||
/* IP protocol and length fields. This addition cannot carry. */
|
||||
sum = upper_layer_len + proto;
|
||||
/* Sum IP source and destination addresses. */
|
||||
sum = chksum(sum, (uint8_t *)&UIP_IP_BUF->srcipaddr, 2 * sizeof(uip_ipaddr_t));
|
||||
|
||||
/* Sum TCP header and data. */
|
||||
sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN],
|
||||
upper_layer_len);
|
||||
|
||||
return (sum == 0) ? 0xffff : uip_htons(sum);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint16_t
|
||||
uip_icmp6chksum(void)
|
||||
{
|
||||
return upper_layer_chksum(UIP_PROTO_ICMP6);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uip_ds6_link_callback(int status, int numtx)
|
||||
{
|
||||
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A brief description of what this file is
|
||||
* \author
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
*/
|
||||
|
||||
#ifndef BRIDGE_CONF_H_
|
||||
#define BRIDGE_CONF_H_
|
||||
|
||||
#undef UIP_CONF_ROUTER
|
||||
|
||||
#undef UIP_CONF_LLH_LEN
|
||||
#define UIP_CONF_LLH_LEN 14
|
||||
|
||||
#undef UIP_CONF_BUFFER_SIZE
|
||||
#define UIP_CONF_BUFFER_SIZE 256
|
||||
#endif /* BRIDGE_CONF_H_ */
|
|
@ -1,16 +0,0 @@
|
|||
interface tap0 {
|
||||
AdvSendAdvert on;
|
||||
AdvLinkMTU 1280;
|
||||
AdvCurHopLimit 128;
|
||||
AdvReachableTime 360000;
|
||||
MinRtrAdvInterval 100;
|
||||
MaxRtrAdvInterval 150;
|
||||
AdvDefaultLifetime 200;
|
||||
prefix AAAA::/64
|
||||
{
|
||||
AdvOnLink on;
|
||||
AdvAutonomous on;
|
||||
AdvPreferredLifetime 4294967295;
|
||||
AdvValidLifetime 4294967295;
|
||||
};
|
||||
};
|
|
@ -1,882 +0,0 @@
|
|||
/**
|
||||
* \file sicslow_ethernet.c
|
||||
* Routines to interface between Ethernet and 6LowPan
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2008 by:
|
||||
* Colin O'Flynn coflynn@newae.com
|
||||
* Eric Gnoske egnoske@gmail.com
|
||||
* Blake Leverett bleverett@gmail.com
|
||||
* Mike Vidales mavida404@gmail.com
|
||||
* Kevin Brown kbrown3@uccs.edu
|
||||
* Nate Bohlmann nate@elfwerks.com
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name of the copyright holders nor the names of
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
\ingroup usbstick
|
||||
\defgroup sicslowinterop 6LowPan Ethernet Interop
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
\par Ethernet to 6LowPan Address Translation
|
||||
|
||||
It should be obvious that since 802.15.4 addresses are 8
|
||||
bytes, and 802.3 addresses are 6 bytes, some form of
|
||||
address translation is needed. These routines provide this
|
||||
|
||||
\par 802.3 Address Formats
|
||||
|
||||
802.3 MAC addresses used here have this form:
|
||||
|
||||
\verbatim
|
||||
+----+----+----+----+----+----+----+----+
|
||||
+ + + + + + TR + GL + MU +
|
||||
+----+----+----+----+----+----+----+----+
|
||||
\endverbatim
|
||||
|
||||
|
||||
It can be seen this is like a normal ethernet MAC address,
|
||||
with GL being the Global/Local bit, and MU being the
|
||||
Multicast/Unicast bit.
|
||||
|
||||
The addition is the 'TR' bit, which if set indicates that
|
||||
the address must be translated when going between 802.15.4
|
||||
and 802.3.
|
||||
|
||||
\par Address Translation
|
||||
|
||||
If the TRANSLATE (TR) bit is CLEAR, this means the 5th and
|
||||
4th LSBytes of the 802.15.4 address are fffe, aka the address
|
||||
has the hexidecial form:
|
||||
|
||||
xxxxxxfffexxxxxx
|
||||
|
||||
\note
|
||||
You should always aim to set the 802.15.4 addresses
|
||||
of the devices on your network to ones that will
|
||||
satisfy this requirement. Some examples are:
|
||||
\note
|
||||
0x02 23 42 ff fe 73 92 28
|
||||
\note
|
||||
0x82 00 82 ff fe cd ee 22
|
||||
|
||||
\note
|
||||
So the most significant octets MUST
|
||||
have bit 0 CLEAR, bit 1 SET, and bit 2 CLEAR. The remaining
|
||||
bits in this octet can be anything.
|
||||
|
||||
If the TRANSLATE bit is SET, this means the address on the
|
||||
802.3 side does not directly convert to an 802.15.4 address.
|
||||
To translate it, the remainder of the octet is used as an
|
||||
index in a look-up table. This look-up table simply stores
|
||||
the 4th, 5th, and 8th octet of the 802.15.4 address, and attaches
|
||||
them to the remaining 5 bytes of the 802.3 address.
|
||||
|
||||
In this way there can be 32 different 802.15.4 'prefixes',
|
||||
requiring only 96 bytes of RAM in a storage table on the
|
||||
802.3 to 802.15.4 bridge.
|
||||
|
||||
Mulitcast addresses on 802.3 are mapped to broadcast addresses on
|
||||
802.15.4 and vis-versa. Since IPv6 does not use 802.3 broadcast,
|
||||
this code will drop all 802.3 broadcast packets. They are most
|
||||
likely something unwanted, such as IPv4 packets that snuck in.
|
||||
|
||||
\par Notes on how addresses are stored
|
||||
|
||||
An 802.15.4 address will be reported for example as:
|
||||
|
||||
0x8877665544332211
|
||||
|
||||
Stored in the array as passed to these functions, it will be:
|
||||
\verbatim
|
||||
array[0] = 0x88;
|
||||
array[1] = 0x77;
|
||||
array[2] = 0x66;
|
||||
etc.
|
||||
\endverbatim
|
||||
|
||||
An 802.3 address will be reported for example as:
|
||||
02:43:53:35:45:45
|
||||
|
||||
Stored in the array as passed to these functions, it will be:
|
||||
\verbatim
|
||||
array[0] = 0x02;
|
||||
array[1] = 0x43;
|
||||
array[2] = 0x53;
|
||||
array[3] = 0x35
|
||||
etc.
|
||||
\endverbatim
|
||||
*/
|
||||
|
||||
#include "uip.h"
|
||||
#include "uip_arp.h" /* For ethernet header structure */
|
||||
#include "net/ipv6/sicslowpan.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
//#define PRINTF printf
|
||||
#define PRINTF(...)
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#define ETHBUF(x) ((struct uip_eth_hdr *)x)
|
||||
|
||||
//For little endian, such as our friend mr. AVR
|
||||
#ifndef LSB
|
||||
#define LSB(u16) (((uint8_t *)&(u16))[0]) //!< Least significant byte of \a u16.
|
||||
#define MSB(u16) (((uint8_t *)&(u16))[1]) //!< Most significant byte of \a u16.
|
||||
#endif
|
||||
|
||||
usbstick_mode_t usbstick_mode;
|
||||
|
||||
uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
|
||||
uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan);
|
||||
/* uint8_t memcmp_reverse(uint8_t * a, uint8_t * b, uint8_t num); */
|
||||
/* void mac_ethhijack_nondata(const struct mac_driver *r); */
|
||||
/* void mac_ethhijack(const struct mac_driver *r); */
|
||||
|
||||
/* extern void (*sicslowmac_snifferhook)(const struct mac_driver *r); */
|
||||
|
||||
|
||||
//! Location of TRANSLATE (TR) bit in Ethernet address
|
||||
#define TRANSLATE_BIT_MASK (1<<2)
|
||||
//! Location of LOCAL (GL) bit in Ethernet address
|
||||
#define LOCAL_BIT_MASK (1<<1)
|
||||
//! Location of MULTICAST (MU) bit in Ethernet address
|
||||
#define MULTICAST_BIT_MASK (1<<0)
|
||||
|
||||
#define PREFIX_BUFFER_SIZE 32
|
||||
|
||||
uint8_t prefixCounter;
|
||||
uint8_t prefixBuffer[PREFIX_BUFFER_SIZE][3];
|
||||
|
||||
/* 6lowpan max size + ethernet header size + 1 */
|
||||
uint8_t raw_buf[127+ UIP_LLH_LEN +1];
|
||||
|
||||
|
||||
/* void tcpip_input( void ) */
|
||||
/* { */
|
||||
/* mac_LowpanToEthernet(); */
|
||||
/* } */
|
||||
|
||||
/**
|
||||
* \brief Perform any setup needed
|
||||
*/
|
||||
/* struct mac_driver * pmac; */
|
||||
void mac_ethernetSetup(void)
|
||||
{
|
||||
usbstick_mode.sicslowpan = 1;
|
||||
usbstick_mode.sendToRf = 1;
|
||||
usbstick_mode.translate = 1;
|
||||
usbstick_mode.raw = 1;
|
||||
|
||||
/* sicslowinput = pinput; */
|
||||
|
||||
|
||||
/* pmac = sicslowmac_get_driver(); */
|
||||
/* pmac->set_receive_function(mac_ethhijack); */
|
||||
/* sicslowmac_snifferhook = mac_ethhijack_nondata; */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Take a packet received over the ethernet link, and send it
|
||||
* out over 802.15.4
|
||||
*/
|
||||
void mac_ethernetToLowpan(uint8_t * ethHeader)
|
||||
{
|
||||
//Dest address
|
||||
uip_lladdr_t destAddr;
|
||||
uip_lladdr_t *destAddrPtr = NULL;
|
||||
|
||||
PRINTF("Packet type: %x\n", ((struct uip_eth_hdr *) ethHeader)->type);
|
||||
|
||||
//RUM doesn't support sending data
|
||||
#if UIP_CONF_USE_RUM
|
||||
return;
|
||||
#endif
|
||||
|
||||
//If not IPv6 we don't do anything
|
||||
if (((struct uip_eth_hdr *) ethHeader)->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) {
|
||||
PRINTF("eth2low: Packet is not IPv6, dropping\n");
|
||||
/* rndis_stat.txbad++; */
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
|
||||
// In sniffer mode we don't ever send anything
|
||||
if (usbstick_mode.sendToRf == 0) {
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
|
||||
/* IPv6 uses 33-33-xx-xx-xx-xx prefix for multicast ND stuff */
|
||||
if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0x33) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0x33) )
|
||||
{
|
||||
PRINTF("eth2low: Ethernet multicast packet received\n");
|
||||
;//Do Nothing
|
||||
} else if ( (((struct uip_eth_hdr *) ethHeader)->dest.addr[0] == 0xFF) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[1] == 0xFF) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[2] == 0xFF) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[3] == 0xFF) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[4] == 0xFF) &&
|
||||
(((struct uip_eth_hdr *) ethHeader)->dest.addr[5] == 0xFF) ) {
|
||||
/* IPv6 does not use broadcast addresses, hence this should not happen */
|
||||
PRINTF("eth2low: Ethernet broadcast address received, should not happen?\n");
|
||||
/* rndis_stat.txbad++; */
|
||||
uip_clear_buf();
|
||||
return;
|
||||
} else {
|
||||
PRINTF("eth2low: Addressed packet received... ");
|
||||
//Check this returns OK
|
||||
if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) {
|
||||
PRINTF(" translation failed\n");
|
||||
/* rndis_stat.txbad++; */
|
||||
uip_clear_buf();
|
||||
return;
|
||||
}
|
||||
PRINTF(" translated OK\n");
|
||||
destAddrPtr = &destAddr;
|
||||
}
|
||||
|
||||
//Remove header from length before passing onward
|
||||
if(uip_len > UIP_LLH_LEN) {
|
||||
uip_len -= UIP_LLH_LEN;
|
||||
|
||||
//Some IP packets have link layer in them, need to change them around!
|
||||
if (usbstick_mode.translate) {
|
||||
/* uint8_t transReturn = */
|
||||
mac_translateIPLinkLayer(ll_802154_type);
|
||||
PRINTF("IPTranslation: returns %d\n", transReturn);
|
||||
}
|
||||
|
||||
if (usbstick_mode.sendToRf){
|
||||
tcpip_output(destAddrPtr);
|
||||
/* rndis_stat.txok++; */
|
||||
}
|
||||
}
|
||||
|
||||
uip_clear_buf();
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Take a packet received over the 802.15.4 link, and send it
|
||||
* out over ethernet, performing any translations needed.
|
||||
*/
|
||||
void mac_LowpanToEthernet(void)
|
||||
{
|
||||
/* parsed_frame = sicslowmac_get_frame(); */
|
||||
|
||||
//Setup generic ethernet stuff
|
||||
ETHBUF(uip_buf)->type = uip_htons(UIP_ETHTYPE_IPV6);
|
||||
|
||||
//Check for broadcast message
|
||||
if(packetbuf_holds_broadcast()) {
|
||||
/* if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) && */
|
||||
/* ( parsed_frame->dest_addr->addr16 == 0xffff) ) { */
|
||||
ETHBUF(uip_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(uip_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(uip_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(uip_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(uip_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(uip_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
} else {
|
||||
//Otherwise we have a real address
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
}
|
||||
|
||||
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(uip_buf)->src.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
|
||||
//We only do address translation in network mode!
|
||||
if (usbstick_mode.translate) {
|
||||
//Some IP packets have link layer in them, need to change them around!
|
||||
mac_translateIPLinkLayer(ll_8023_type);
|
||||
}
|
||||
|
||||
PRINTF("Low2Eth: Sending packet to ethernet\n");
|
||||
|
||||
uip_len += UIP_LLH_LEN;
|
||||
|
||||
/* rndis_send(uip_buf, uip_len, 1); */
|
||||
/* rndis_stat.rxok++; */
|
||||
/* uip_clear_buf(); */
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Translate IP packet's possible link-layer addresses, passing
|
||||
* the message to the appropriate higher level function for this
|
||||
* packet (aka: ICMP)
|
||||
* \param target The target we want to end up with - either ll_8023_type
|
||||
* for ethernet, or ll_802154_type for 802.15.4
|
||||
* \return Returns how successful the translation was
|
||||
* \retval 0 Addresses, if present, were translated.
|
||||
* \retval <0 Negative return values indicate various errors, as defined
|
||||
* by the higher level function.
|
||||
*/
|
||||
int8_t mac_translateIPLinkLayer(lltype_t target)
|
||||
{
|
||||
|
||||
#if UIP_LLADDR_LEN == 8
|
||||
if (UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
|
||||
PRINTF("eth2low: ICMP Message detected\n");
|
||||
return mac_translateIcmpLinkLayer(target);
|
||||
}
|
||||
return 0;
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#include "net/ipv6/uip-icmp6.h"
|
||||
#include "net/ipv6/uip-nd6.h"
|
||||
|
||||
typedef struct {
|
||||
uint8_t type;
|
||||
uint8_t length;
|
||||
uint8_t data[16];
|
||||
} icmp_opts_t;
|
||||
|
||||
#define UIP_ICMP_BUF ((struct uip_icmp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#define UIP_ICMP_OPTS(x) ((icmp_opts_t *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN + x])
|
||||
|
||||
void slide(uint8_t * data, uint8_t length, int16_t slide);
|
||||
|
||||
/**
|
||||
* \brief Translate the link-layer (L2) addresses in an ICMP packet.
|
||||
* This will just be NA/NS/RA/RS packets currently.
|
||||
* \param target The target we want to end up with - either ll_8023_type
|
||||
* for ethernet, or ll_802154_type for 802.15.4
|
||||
* \return Returns how successful the translation was
|
||||
* \retval 0 Addresses, if present, were translated.
|
||||
* \retval -1 ICMP message was unknown type, nothing done.
|
||||
* \retval -2 ICMP Length does not make sense?
|
||||
* \retval -3 Unknown 'target' type
|
||||
*/
|
||||
int8_t mac_translateIcmpLinkLayer(lltype_t target)
|
||||
{
|
||||
uint16_t icmp_opt_offset = 0;
|
||||
int16_t len = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0] << 8);
|
||||
|
||||
uint16_t iplen;
|
||||
|
||||
uint8_t i;
|
||||
|
||||
int16_t sizechange;
|
||||
|
||||
uint8_t llbuf[16];
|
||||
|
||||
//Figure out offset to start of options
|
||||
switch(UIP_ICMP_BUF->type) {
|
||||
case ICMP6_NS:
|
||||
case ICMP6_NA:
|
||||
icmp_opt_offset = 24;
|
||||
break;
|
||||
|
||||
case ICMP6_RS:
|
||||
icmp_opt_offset = 8;
|
||||
break;
|
||||
|
||||
case ICMP6_RA:
|
||||
icmp_opt_offset = 16;
|
||||
break;
|
||||
|
||||
case ICMP6_REDIRECT:
|
||||
icmp_opt_offset = 40;
|
||||
break;
|
||||
|
||||
/** Things without link-layer */
|
||||
case ICMP6_DST_UNREACH:
|
||||
case ICMP6_PACKET_TOO_BIG:
|
||||
case ICMP6_TIME_EXCEEDED:
|
||||
case ICMP6_PARAM_PROB:
|
||||
case ICMP6_ECHO_REQUEST:
|
||||
case ICMP6_ECHO_REPLY:
|
||||
return 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Figure out length of options
|
||||
len -= icmp_opt_offset;
|
||||
|
||||
//Sanity check
|
||||
if (len < 8) return -2;
|
||||
|
||||
//While we have options to do...
|
||||
while (len >= 8){
|
||||
|
||||
//If we have one of these, we have something useful!
|
||||
if (((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_SLLAO) ||
|
||||
((UIP_ICMP_OPTS(icmp_opt_offset)->type) == UIP_ND6_OPT_TLLAO) ) {
|
||||
|
||||
/* Shrinking the buffer may thrash things, so we store the old
|
||||
link-layer address */
|
||||
for(i = 0; i < (UIP_ICMP_OPTS(icmp_opt_offset)->length*8 - 2); i++) {
|
||||
llbuf[i] = UIP_ICMP_OPTS(icmp_opt_offset)->data[i];
|
||||
}
|
||||
|
||||
//Shrink/grow buffer as needed
|
||||
if (target == ll_802154_type) {
|
||||
//Current is 802.3, Hence current link-layer option is 6 extra bytes
|
||||
sizechange = 8;
|
||||
slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 6, len - 6, sizechange);
|
||||
} else if (target == ll_8023_type) {
|
||||
/* Current is 802.15.4, Hence current link-layer option is 14 extra
|
||||
* bytes.
|
||||
* (Actual LL is 8 bytes, but total option length is in multiples of
|
||||
* 8 Bytes, hence 8 + 2 = 10. Closest is 16 bytes, then 16 bytes for
|
||||
* total optional length - 2 bytes for type + length leaves 14 )
|
||||
*/
|
||||
sizechange = -8;
|
||||
slide(UIP_ICMP_OPTS(icmp_opt_offset)->data + 14, len - 14, sizechange);
|
||||
} else {
|
||||
return -3; //Uh-oh!
|
||||
}
|
||||
|
||||
//Translate addresses
|
||||
if (target == ll_802154_type) {
|
||||
mac_createSicslowpanLongAddr(llbuf, (uip_lladdr_t *)UIP_ICMP_OPTS(icmp_opt_offset)->data);
|
||||
} else {
|
||||
mac_createEthernetAddr(UIP_ICMP_OPTS(icmp_opt_offset)->data, (uip_lladdr_t *)llbuf);
|
||||
}
|
||||
|
||||
//Adjust the length
|
||||
if (target == ll_802154_type) {
|
||||
UIP_ICMP_OPTS(icmp_opt_offset)->length = 2;
|
||||
} else {
|
||||
UIP_ICMP_OPTS(icmp_opt_offset)->length = 1;
|
||||
}
|
||||
|
||||
//Adjust the IP header length, as well as uIP length
|
||||
iplen = UIP_IP_BUF->len[1] | (UIP_IP_BUF->len[0]<<8);
|
||||
iplen += sizechange;
|
||||
len += sizechange;
|
||||
|
||||
UIP_IP_BUF->len[1] = (uint8_t)iplen;
|
||||
UIP_IP_BUF->len[0] = (uint8_t)(iplen >> 8);
|
||||
|
||||
uip_len += sizechange;
|
||||
|
||||
//We broke ICMP checksum, be sure to fix that
|
||||
UIP_ICMP_BUF->icmpchksum = 0;
|
||||
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
|
||||
|
||||
//Finally set up next run in while loop
|
||||
len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
|
||||
icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
|
||||
} else {
|
||||
|
||||
//Not an option we care about, ignore it
|
||||
len -= 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
|
||||
|
||||
//This shouldn't happen!
|
||||
if (UIP_ICMP_OPTS(icmp_opt_offset)->length == 0) {
|
||||
PRINTF("Option in ND packet has length zero, error?\n");
|
||||
len = 0;
|
||||
}
|
||||
|
||||
icmp_opt_offset += 8 * UIP_ICMP_OPTS(icmp_opt_offset)->length;
|
||||
|
||||
} //If ICMP_OPT is one we care about
|
||||
|
||||
} //while(len >= 8)
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Create a 802.15.4 long address from a 802.3 address
|
||||
* \param ethernet Pointer to ethernet address
|
||||
* \param lowpan Pointer to 802.15.4 address
|
||||
*/
|
||||
uint8_t mac_createSicslowpanLongAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
||||
{
|
||||
uint8_t index;
|
||||
|
||||
#if UIP_LLADDR_LEN == 8
|
||||
//Special case - if the address is our address, we just copy over what we know to be
|
||||
//our 802.15.4 address
|
||||
|
||||
/* if (memcmp_reverse((uint8_t *)&rndis_ethernet_addr, ethernet, 6) == 0) { */
|
||||
if (memcmp((uint8_t *)&uip_lladdr.addr[2], ethernet, 6) == 0) {
|
||||
memcpy((uint8_t *)lowpan, uip_lladdr.addr, 8);
|
||||
/* byte_reverse((uint8_t *)lowpan, 8); */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//Check if translate bit is set, hence we have to look up the prefix
|
||||
if (ethernet[0] & TRANSLATE_BIT_MASK) {
|
||||
|
||||
//Get top bits
|
||||
index = ethernet[0] >> 3;
|
||||
|
||||
//Check this is plausible...
|
||||
if (index >= prefixCounter) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Copy over prefix
|
||||
lowpan->addr[0] = prefixBuffer[index][0];
|
||||
lowpan->addr[3] = prefixBuffer[index][1];
|
||||
lowpan->addr[4] = prefixBuffer[index][2];
|
||||
|
||||
//Bit is clear
|
||||
//so we copy all six
|
||||
} else {
|
||||
lowpan->addr[0] = ethernet[0];
|
||||
lowpan->addr[3] = 0xff;
|
||||
lowpan->addr[4] = 0xfe;
|
||||
}
|
||||
|
||||
//Copy over reamining five bytes
|
||||
lowpan->addr[1] = ethernet[1];
|
||||
lowpan->addr[2] = ethernet[2];
|
||||
lowpan->addr[5] = ethernet[3];
|
||||
lowpan->addr[6] = ethernet[4];
|
||||
lowpan->addr[7] = ethernet[5];
|
||||
|
||||
#else
|
||||
uint8_t i;
|
||||
|
||||
for(i = 0; i < UIP_LLADDR_LEN; i++) {
|
||||
lowpan->addr[i] = ethernet[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Create a 802.3 address from a 802.15.4 long address
|
||||
* \param ethernet Pointer to ethernet address
|
||||
* \param lowpan Pointer to 802.15.4 address
|
||||
*/
|
||||
uint8_t mac_createEthernetAddr(uint8_t * ethernet, uip_lladdr_t * lowpan)
|
||||
{
|
||||
uint8_t index = 0;
|
||||
uint8_t i;
|
||||
/* uint8_t j, match; */
|
||||
|
||||
#if UIP_LLADDR_LEN == 8
|
||||
|
||||
//Special case - if the address is our address, we just copy over what we know to be
|
||||
//our 802.3 address
|
||||
/* if (memcmp_reverse(uip_lladdr.addr, (uint8_t *)lowpan, 8) == 0) { */
|
||||
if (memcmp(uip_lladdr.addr, (uint8_t *)lowpan, 8) == 0) {
|
||||
memcpy(ethernet, &uip_lladdr.addr[2], 6);
|
||||
/* byte_reverse(ethernet, 6); */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
//Check if we need to do anything:
|
||||
if ((lowpan->addr[3] == 0xff) && (lowpan->addr[4] == 0xfe) &&
|
||||
((lowpan->addr[0] & TRANSLATE_BIT_MASK) == 0) &&
|
||||
((lowpan->addr[0] & MULTICAST_BIT_MASK) == 0) &&
|
||||
(lowpan->addr[0] & LOCAL_BIT_MASK)) {
|
||||
|
||||
/** Nope: just copy over 6 bytes **/
|
||||
ethernet[0] = lowpan->addr[0];
|
||||
ethernet[1] = lowpan->addr[1];
|
||||
ethernet[2] = lowpan->addr[2];
|
||||
ethernet[3] = lowpan->addr[5];
|
||||
ethernet[4] = lowpan->addr[6];
|
||||
ethernet[5] = lowpan->addr[7];
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
/** Yes: need to store prefix **/
|
||||
for (i = 0; i < prefixCounter; i++) {
|
||||
//Check the current prefix - if it fails, check next one
|
||||
|
||||
|
||||
if ((lowpan->addr[0] == prefixBuffer[i][0]) &&
|
||||
(lowpan->addr[3] == prefixBuffer[i][1]) &&
|
||||
(lowpan->addr[4] == prefixBuffer[i][2])) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
index = i;
|
||||
|
||||
//Deal with overflow, iron-fist style
|
||||
if (index >= PREFIX_BUFFER_SIZE) {
|
||||
index = 0;
|
||||
prefixCounter = PREFIX_BUFFER_SIZE;
|
||||
} else {
|
||||
//Are we making a new one?
|
||||
if (index == prefixCounter) {
|
||||
prefixCounter++;
|
||||
}
|
||||
}
|
||||
|
||||
//Copy the prefix over, no matter if we have a new or old one
|
||||
prefixBuffer[index][0] = lowpan->addr[0];
|
||||
prefixBuffer[index][1] = lowpan->addr[3];
|
||||
prefixBuffer[index][2] = lowpan->addr[4];
|
||||
|
||||
//Create ethernet MAC address now
|
||||
ethernet[1] = lowpan->addr[1];
|
||||
ethernet[2] = lowpan->addr[2];
|
||||
ethernet[3] = lowpan->addr[5];
|
||||
ethernet[4] = lowpan->addr[6];
|
||||
ethernet[5] = lowpan->addr[7];
|
||||
|
||||
|
||||
ethernet[0] = TRANSLATE_BIT_MASK | LOCAL_BIT_MASK | (index << 3);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
//Create ethernet MAC address now
|
||||
for(i = 0; i < UIP_LLADDR_LEN; i++) {
|
||||
ethernet[i] = lowpan->addr[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Slide the pointed to memory up a certain amount,
|
||||
* growing/shrinking a buffer
|
||||
* \param data Pointer to start of data buffer
|
||||
* \param length Length of the data buffer
|
||||
* \param slide How many bytes to slide the buffer up in memory (if +) or
|
||||
* down in memory (if -)
|
||||
*/
|
||||
void slide(uint8_t * data, uint8_t length, int16_t slide)
|
||||
{
|
||||
//Sanity checks
|
||||
if (!length) return;
|
||||
if (!slide) return;
|
||||
|
||||
uint8_t i = 0;
|
||||
|
||||
while(length) {
|
||||
length--;
|
||||
|
||||
//If we are sliding up, we do from the top of the buffer down
|
||||
if (slide > 0) {
|
||||
*(data + length + slide) = *(data + length);
|
||||
|
||||
//If we are sliding down, we do from the bottom of the buffer up
|
||||
} else {
|
||||
*(data + slide + i) = *(data + i);
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/** \brief Process a received 6lowpan packet. Hijack function.
|
||||
* \param r The MAC layer
|
||||
*
|
||||
* The 6lowpan packet is put in packetbuf by the MAC. This routine calls
|
||||
* any other needed layers (either 6lowpan, or just raw ethernet dump)
|
||||
*/
|
||||
#if 0
|
||||
void mac_ethhijack(const struct mac_driver *r)
|
||||
{
|
||||
if (usbstick_mode.raw) {
|
||||
mac_802154raw(r);
|
||||
}
|
||||
|
||||
if (usbstick_mode.sicslowpan) {
|
||||
|
||||
#if UIP_CONF_USE_RUM
|
||||
if (parsed_frame->payload[4]) { /* RUM 6lowpan frame type */
|
||||
#endif
|
||||
sicslowinput(r);
|
||||
#if UIP_CONF_USE_RUM
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
void mac_ethhijack_nondata(const struct mac_driver *r)
|
||||
{
|
||||
if (usbstick_mode.raw)
|
||||
mac_802154raw(r);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/*--------------------------------------------------------------------*/
|
||||
/** \brief Logs a sent 6lowpan frame
|
||||
*
|
||||
* This routine passes a frame
|
||||
* directly to the ethernet layer without decompressing.
|
||||
*/
|
||||
#if 0
|
||||
void mac_logTXtoEthernet(frame_create_params_t *p,frame_result_t *frame_result)
|
||||
{
|
||||
uint8_t sendlen;
|
||||
|
||||
/* Make sure we are supposed to do this */
|
||||
if (usbstick_mode.raw == 0) return;
|
||||
|
||||
/* Get the raw frame */
|
||||
memcpy(&raw_buf[UIP_LLH_LEN], frame_result->frame, frame_result->length);
|
||||
sendlen = frame_result->length;
|
||||
|
||||
//Setup generic ethernet stuff
|
||||
ETHBUF(raw_buf)->type = uip_htons(UIP_ETHTYPE_802154);
|
||||
|
||||
uint64_t tempaddr;
|
||||
|
||||
|
||||
//Check for broadcast message
|
||||
//if(linkaddr_cmp((const linkaddr_t *)destAddr, &linkaddr_null)) {
|
||||
if( ( p->fcf.destAddrMode == SHORTADDRMODE) &&
|
||||
( p->dest_addr.addr16 == 0xffff) ) {
|
||||
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
} else {
|
||||
|
||||
tempaddr = p->dest_addr.addr64;
|
||||
|
||||
byte_reverse((uint8_t *)&tempaddr, 8);
|
||||
|
||||
//Otherwise we have a real address
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)&tempaddr);
|
||||
|
||||
}
|
||||
|
||||
tempaddr = p->src_addr.addr64;
|
||||
|
||||
byte_reverse((uint8_t *)&tempaddr, 8);
|
||||
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),
|
||||
(uip_lladdr_t *)&tempaddr);
|
||||
|
||||
PRINTF("Low2Eth: Sending 802.15.4 packet to ethernet\n");
|
||||
|
||||
sendlen += UIP_LLH_LEN;
|
||||
|
||||
rndis_send(raw_buf, sendlen, 0);
|
||||
rndis_stat.rxok++;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------*/
|
||||
/** \brief Process a received 6lowpan packet.
|
||||
* \param r The MAC layer
|
||||
*
|
||||
* The 6lowpan packet is put in packetbuf by the MAC. This routine passes
|
||||
* it directly to the ethernet layer without decompressing.
|
||||
*/
|
||||
#if 0
|
||||
void mac_802154raw(const struct mac_driver *r)
|
||||
{
|
||||
uint8_t sendlen;
|
||||
|
||||
parsed_frame = sicslowmac_get_frame();
|
||||
|
||||
/* Get the raw frame */
|
||||
memcpy(&raw_buf[UIP_LLH_LEN], radio_frame_data(), radio_frame_length());
|
||||
sendlen = radio_frame_length();
|
||||
|
||||
//Setup generic ethernet stuff
|
||||
ETHBUF(raw_buf)->type = uip_htons(UIP_ETHTYPE_802154);
|
||||
|
||||
|
||||
//Check for broadcast message
|
||||
//if(linkaddr_cmp((const linkaddr_t *)destAddr, &linkaddr_null)) {
|
||||
if( ( parsed_frame->fcf->destAddrMode == SHORTADDRMODE) &&
|
||||
( parsed_frame->dest_addr->addr16 == 0xffff) ) {
|
||||
ETHBUF(raw_buf)->dest.addr[0] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[1] = 0x33;
|
||||
ETHBUF(raw_buf)->dest.addr[2] = UIP_IP_BUF->destipaddr.u8[12];
|
||||
ETHBUF(raw_buf)->dest.addr[3] = UIP_IP_BUF->destipaddr.u8[13];
|
||||
ETHBUF(raw_buf)->dest.addr[4] = UIP_IP_BUF->destipaddr.u8[14];
|
||||
ETHBUF(raw_buf)->dest.addr[5] = UIP_IP_BUF->destipaddr.u8[15];
|
||||
} else {
|
||||
|
||||
//Otherwise we have a real address
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->dest.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
|
||||
|
||||
}
|
||||
|
||||
mac_createEthernetAddr((uint8_t *) &(ETHBUF(raw_buf)->src.addr[0]),
|
||||
(uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||
|
||||
PRINTF("Low2Eth: Sending 802.15.4 packet to ethernet\n");
|
||||
|
||||
sendlen += UIP_LLH_LEN;
|
||||
|
||||
rndis_send(raw_buf, sendlen, 1);
|
||||
rndis_stat.rxok++;
|
||||
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/** @} */
|
||||
/** @} */
|
|
@ -1,78 +0,0 @@
|
|||
/**
|
||||
* \file sicslow_ethernet.c
|
||||
* Routines to interface between Ethernet and 6LowPan
|
||||
*
|
||||
* \author
|
||||
* Colin O'Flynn <coflynn@newae.com>
|
||||
*
|
||||
* \addtogroup usbstick
|
||||
*/
|
||||
|
||||
/* Copyright (c) 2008 by:
|
||||
|
||||
Colin O'Flynn coflynn@newae.com
|
||||
Eric Gnoske egnoske@gmail.com
|
||||
Blake Leverett bleverett@gmail.com
|
||||
Mike Vidales mavida404@gmail.com
|
||||
Kevin Brown kbrown3@uccs.edu
|
||||
Nate Bohlmann nate@elfwerks.com
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef SICSLOW_ETHERNET_H
|
||||
#define SICSLOW_ETHERNET_H
|
||||
|
||||
typedef enum {
|
||||
ll_802154_type,
|
||||
ll_8023_type
|
||||
} lltype_t;
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t sicslowpan :1;
|
||||
uint8_t sendToRf :1;
|
||||
uint8_t translate :1;
|
||||
uint8_t raw :1;
|
||||
} usbstick_mode_t;
|
||||
|
||||
|
||||
#define UIP_ETHTYPE_802154 0x809A
|
||||
|
||||
extern usbstick_mode_t usbstick_mode;
|
||||
|
||||
|
||||
int8_t mac_translateIcmpLinkLayer(lltype_t target);
|
||||
int8_t mac_translateIPLinkLayer(lltype_t target);
|
||||
void mac_LowpanToEthernet(void);
|
||||
void mac_ethernetToLowpan(uint8_t * ethHeader);
|
||||
void mac_ethernetSetup(void);
|
||||
/* void mac_802154raw(const struct mac_driver *r); */
|
||||
/* void mac_logTXtoEthernet(frame_create_params_t *p,frame_result_t *frame_result); */
|
||||
|
||||
#endif
|
|
@ -1,152 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2009, Swedish Institute of Computer Science.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the Institute nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* A brief description of what this file is
|
||||
* \author
|
||||
* Niclas Finne <nfi@sics.se>
|
||||
* Joakim Eriksson <joakime@sics.se>
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "net/ipv6/uip.h"
|
||||
#include "dev/slip.h"
|
||||
#include "dev/leds.h"
|
||||
#include "sicslow_ethernet.h"
|
||||
|
||||
#include "net/packetbuf.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
|
||||
PROCESS(uip6_bridge, "IPv6/6lowpan TAP bridge");
|
||||
PROCESS(tcpip_process, "tcpip dummy");
|
||||
AUTOSTART_PROCESSES(&uip6_bridge);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t (* outputfunc)(const uip_lladdr_t *a);
|
||||
uint8_t
|
||||
tcpip_output(const uip_lladdr_t *a)
|
||||
{
|
||||
if(outputfunc != NULL) {
|
||||
outputfunc(a);
|
||||
leds_toggle(LEDS_GREEN);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void
|
||||
tcpip_ipv6_output(void)
|
||||
{
|
||||
}
|
||||
void
|
||||
tcpip_set_outputfunc(uint8_t (*f)(const uip_lladdr_t *))
|
||||
{
|
||||
outputfunc = f;
|
||||
}
|
||||
PROCESS_THREAD(tcpip_process, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Packet from SICSLoWPAN */
|
||||
void
|
||||
tcpip_input(void)
|
||||
{
|
||||
if(uip_len > 0) {
|
||||
mac_LowpanToEthernet();
|
||||
if(uip_len > 0) {
|
||||
slip_write(uip_buf, uip_len);
|
||||
leds_toggle(LEDS_RED);
|
||||
uip_clear_buf();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Packet from SLIP */
|
||||
static void
|
||||
slip_tcpip_input(void)
|
||||
{
|
||||
/* TODO Should fix this in slip configuration */
|
||||
memmove(uip_buf, &uip_buf[UIP_LLH_LEN], uip_len);
|
||||
mac_ethernetToLowpan(uip_buf);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
slip_activity(void)
|
||||
{
|
||||
leds_toggle(LEDS_BLUE);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
PROCESS_THREAD(uip6_bridge, ev, data)
|
||||
{
|
||||
PROCESS_BEGIN();
|
||||
|
||||
printf("Setting up SLIP\n");
|
||||
|
||||
mac_ethernetSetup();
|
||||
|
||||
slip_arch_init();
|
||||
slip_set_input_callback(slip_activity);
|
||||
slip_set_tcpip_input_callback(slip_tcpip_input);
|
||||
process_start(&slip_process, NULL);
|
||||
|
||||
PROCESS_END();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
putchar(int c)
|
||||
{
|
||||
#define SLIP_END 0300
|
||||
static char debug_frame = 0;
|
||||
|
||||
if(!debug_frame) { /* Start of debug output */
|
||||
slip_arch_writeb(SLIP_END);
|
||||
slip_arch_writeb('\r'); /* Type debug line == '\r' */
|
||||
debug_frame = 1;
|
||||
}
|
||||
|
||||
slip_arch_writeb((char)c);
|
||||
|
||||
/*
|
||||
* Line buffered output, a newline marks the end of debug output and
|
||||
* implicitly flushes debug output.
|
||||
*/
|
||||
if(c == '\n') {
|
||||
slip_arch_writeb(SLIP_END);
|
||||
debug_frame = 0;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
|
@ -451,7 +451,7 @@ arp_out(struct ethip_hdr *iphdr, int len)
|
|||
arphdr->protolen = 4;
|
||||
arphdr->ethhdr.type = UIP_HTONS(UIP_ETHTYPE_ARP);
|
||||
|
||||
/* uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];*/
|
||||
/* uip_appdata = &uip_buf[UIP_IPTCPH_LEN];*/
|
||||
|
||||
return sizeof(struct arp_hdr);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue