Merge pull request #714 from simonduq/contrib/uip-cleanup

Safer uIP6 buffer handling
This commit is contained in:
Simon Duquennoy 2018-10-29 11:09:54 +01:00 committed by GitHub
commit 2b0c2d5e4a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
60 changed files with 932 additions and 3086 deletions

View File

@ -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];

View File

@ -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();

View File

@ -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();
}

View File

@ -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);

View File

@ -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);

View File

@ -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"

View File

@ -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 */

View File

@ -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)

View File

@ -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);

View File

@ -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

View File

@ -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"

View File

@ -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) {

View File

@ -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;

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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;
}
/*---------------------------------------------------------------------------*/

View File

@ -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();
}

View File

@ -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;
}
/*---------------------------------------------------------------------------*/

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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).
*

View File

@ -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

View File

@ -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. */

View File

@ -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);

View File

@ -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 */
/**

View File

@ -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;
}

View File

@ -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

View File

@ -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 *)&current_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;
}
}
}

View File

@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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 *)&current_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;
}
}
}
/** @}*/

View File

@ -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.

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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 */

View File

@ -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();

View File

@ -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

View File

@ -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;
}
/*---------------------------------------------------------------------------*/

View File

@ -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_ */

View File

@ -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)
{
}

View File

@ -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_ */

View File

@ -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;
};
};

View File

@ -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
/** @} */
/** @} */

View File

@ -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

View File

@ -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;
}
/*---------------------------------------------------------------------------*/

View File

@ -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);
}