65#include "dev/watchdog.h"
66#include "net/link-stats.h"
71#include "net/ipv6/uipbuf.h"
81#define LOG_MODULE "6LoWPAN"
82#define LOG_LEVEL LOG_LEVEL_6LOWPAN
84#define GET16(ptr,index) (((uint16_t)((ptr)[(index)] << 8)) | ((ptr)[(index) + 1]))
85#define SET16(ptr,index,value) do { \
86 (ptr)[(index)] = ((value) >> 8) & 0xff; \
87 (ptr)[(index) + 1] = (value) & 0xff; \
93#define PACKETBUF_FRAG_PTR (packetbuf_ptr)
94#define PACKETBUF_FRAG_DISPATCH_SIZE 0
95#define PACKETBUF_FRAG_TAG 2
96#define PACKETBUF_FRAG_OFFSET 4
99#define PACKETBUF_IPHC_BUF ((uint8_t *)(packetbuf_ptr + packetbuf_hdr_len))
100#define PACKETBUF_PAYLOAD_END ((uint8_t *)(packetbuf_ptr + mac_max_payload))
102#define PACKETBUF_6LO_PTR (packetbuf_ptr + packetbuf_hdr_len)
103#define PACKETBUF_6LO_DISPATCH 0
104#define PACKETBUF_6LO_ENCODING 1
105#define PACKETBUF_6LO_TTL 2
107#define PACKETBUF_6LO_HC_UDP_PTR (packetbuf_ptr + packetbuf_hdr_len)
108#define PACKETBUF_6LO_HC_UDP_DISPATCH 0
109#define PACKETBUF_6LO_HC_UDP_HC1_ENCODING 1
110#define PACKETBUF_6LO_HC_UDP_UDP_ENCODING 2
111#define PACKETBUF_6LO_HC_UDP_TTL 3
112#define PACKETBUF_6LO_HC_UDP_PORTS 4
113#define PACKETBUF_6LO_HC_UDP_CHKSUM 5
122#define SICSLOWPAN_IP_BUF(buf) ((struct uip_ip_hdr *)buf)
123#define SICSLOWPAN_UDP_BUF(buf) ((struct uip_udp_hdr *)&buf[UIP_IPH_LEN])
124#define SICSLOWPAN_IPPAYLOAD_BUF(buf) (&buf[UIP_IPH_LEN])
126#define UIP_IPPAYLOAD_BUF_POS(pos) (&uip_buf[UIP_IPH_LEN + (pos)])
127#define UIP_UDP_BUF_POS(pos) ((struct uip_udp_hdr *)UIP_IPPAYLOAD_BUF_POS(pos))
128#define UIP_EXT_HDR_LEN 2
133#ifdef SICSLOWPAN_CONF_COMPRESS_EXT_HDR
134#define COMPRESS_EXT_HDR SICSLOWPAN_CONF_COMPRESS_EXT_HDR
137#define COMPRESS_EXT_HDR 1
141#define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP \
142 || x == UIP_PROTO_HBHO \
143 || x == UIP_PROTO_DESTO \
144 || x == UIP_PROTO_ROUTING \
145 || x == UIP_PROTO_FRAG)
147#define IS_COMPRESSABLE_PROTO(x) (x == UIP_PROTO_UDP)
202#if SICSLOWPAN_CONF_FRAG
203static uint16_t my_tag;
209#ifdef SICSLOWPAN_CONF_FRAGMENT_BUFFERS
210#define SICSLOWPAN_FRAGMENT_BUFFERS SICSLOWPAN_CONF_FRAGMENT_BUFFERS
212#define SICSLOWPAN_FRAGMENT_BUFFERS 12
220#ifdef SICSLOWPAN_CONF_REASS_CONTEXTS
221#define SICSLOWPAN_REASS_CONTEXTS SICSLOWPAN_CONF_REASS_CONTEXTS
223#define SICSLOWPAN_REASS_CONTEXTS 2
227#ifdef SICSLOWPAN_CONF_FRAGMENT_SIZE
228#define SICSLOWPAN_FRAGMENT_SIZE SICSLOWPAN_CONF_FRAGMENT_SIZE
231#define SICSLOWPAN_FRAGMENT_SIZE (127 - 2 - 15)
235#if SICSLOWPAN_FRAGMENT_SIZE > 255
236#error Too large SICSLOWPAN_FRAGMENT_SIZE set.
240#define SICSLOWPAN_FIRST_FRAGMENT_SIZE (SICSLOWPAN_FRAGMENT_SIZE + 38)
243struct sicslowpan_frag_info {
251 uint16_t reassembled_len;
253 struct timer reass_timer;
256 uint16_t first_frag_len;
259 uint8_t first_frag[SICSLOWPAN_FIRST_FRAGMENT_SIZE];
262static struct sicslowpan_frag_info frag_info[SICSLOWPAN_REASS_CONTEXTS];
264struct sicslowpan_frag_buf {
271 uint8_t data[SICSLOWPAN_FRAGMENT_SIZE];
274static struct sicslowpan_frag_buf frag_buf[SICSLOWPAN_FRAGMENT_BUFFERS];
278clear_fragments(uint8_t frag_info_index)
282 frag_info[frag_info_index].len = 0;
283 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
284 if(frag_buf[i].len > 0 && frag_buf[i].index == frag_info_index) {
294timeout_fragments(
int not_context)
298 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
299 if(frag_info[i].len > 0 && i != not_context &&
302 count += clear_fragments(i);
309store_fragment(uint8_t index, uint8_t offset)
316 if(len <= 0 || len > SICSLOWPAN_FRAGMENT_SIZE) {
321 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
322 if(frag_buf[i].len == 0) {
325 frag_buf[i].offset = offset;
326 frag_buf[i].len = len;
327 frag_buf[i].index = index;
339add_fragment(uint16_t tag, uint16_t frag_size, uint8_t offset)
347 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
349 if(frag_info[i].len > 0 &&
timer_expired(&frag_info[i].reass_timer)) {
354 if(found < 0 && frag_info[i].len == 0) {
362 LOG_WARN(
"reassembly: failed to store new fragment session - tag: %d\n", tag);
367 frag_info[found].len = frag_size;
368 frag_info[found].tag = tag;
370 packetbuf_addr(PACKETBUF_ADDR_SENDER));
378 for(i = 0; i < SICSLOWPAN_REASS_CONTEXTS; i++) {
379 if(frag_info[i].tag == tag && frag_info[i].len > 0 &&
380 linkaddr_cmp(&frag_info[i].sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
389 LOG_WARN(
"reassembly: failed to store N-fragment - could not find session - tag: %d offset: %d\n", tag, offset);
394 len = store_fragment(i, offset);
395 if(len < 0 && timeout_fragments(i) > 0) {
396 len = store_fragment(i, offset);
399 frag_info[i].reassembled_len += len;
404 LOG_WARN(
"reassembly: failed to store fragment - packet reassembly will fail tag:%d l\n", frag_info[i].tag);
412copy_frags2uip(
int context)
417 if(frag_info[context].len < frag_info[context].first_frag_len ||
418 frag_info[context].len >
sizeof(
uip_buf)) {
419 LOG_WARN(
"input: invalid total size of fragments\n");
420 clear_fragments(context);
425 memcpy((uint8_t *)
UIP_IP_BUF, (uint8_t *)frag_info[context].first_frag,
426 frag_info[context].first_frag_len);
429 memset((uint8_t *)
UIP_IP_BUF + frag_info[context].first_frag_len, 0,
430 frag_info[context].len - frag_info[context].first_frag_len);
432 for(i = 0; i < SICSLOWPAN_FRAGMENT_BUFFERS; i++) {
434 if(frag_buf[i].len > 0 && frag_buf[i].index == context) {
435 if(((
size_t)frag_buf[i].offset << 3) + frag_buf[i].len >
sizeof(
uip_buf)) {
436 LOG_WARN(
"input: invalid fragment offset\n");
437 clear_fragments(context);
440 memcpy((uint8_t *)
UIP_IP_BUF + (uint16_t)(frag_buf[i].offset << 3),
441 (uint8_t *)frag_buf[i].data, frag_buf[i].len);
445 clear_fragments(context);
456static struct netstack_sniffer *callback = NULL;
459netstack_sniffer_add(
struct netstack_sniffer *s)
465netstack_sniffer_remove(
struct netstack_sniffer *s)
471set_packet_attrs(
void)
475 packetbuf_set_attr(PACKETBUF_ATTR_NETWORK_ID,
UIP_IP_BUF->proto);
479 c = UIP_UDP_BUF_POS(0)->srcport;
480 if(UIP_UDP_BUF_POS(0)->destport < c) {
481 c = UIP_UDP_BUF_POS(0)->destport;
483 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_TCP) {
484 c = UIP_TCP_BUF->srcport;
485 if(UIP_TCP_BUF->destport < c) {
486 c = UIP_TCP_BUF->destport;
488 }
else if(
UIP_IP_BUF->proto == UIP_PROTO_ICMP6) {
492 packetbuf_set_attr(PACKETBUF_ATTR_CHANNEL, c);
502#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
508#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
523const uint8_t unc_llconf[] = {0x0f,0x28,0x22,0x20};
530const uint8_t unc_ctxconf[] = {0x00,0x88,0x82,0x80};
537const uint8_t unc_mxconf[] = {0x0f, 0x25, 0x23, 0x21};
540const uint8_t llprefix[] = {0xfe, 0x80};
543static const uint8_t ttl_values[] = {0, 1, 64, 255};
555#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
558 if((addr_contexts[i].used == 1) &&
559 uip_ipaddr_prefixcmp(&addr_contexts[i].prefix,
ipaddr, 64)) {
560 return &addr_contexts[i];
572#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
575 if((addr_contexts[i].used == 1) &&
576 addr_contexts[i].number == number) {
577 return &addr_contexts[i];
585compress_addr_64(uint8_t bitpos, uip_ipaddr_t *
ipaddr,
586 const uip_lladdr_t *lladdr)
611uncompress_addr(uip_ipaddr_t *
ipaddr, uint8_t
const prefix[],
612 uint8_t pref_post_count, uip_lladdr_t *lladdr)
614 uint8_t prefcount = pref_post_count >> 4;
615 uint8_t postcount = pref_post_count & 0x0f;
617 prefcount = prefcount == 15 ? 16 : prefcount;
618 postcount = postcount == 15 ? 16 : postcount;
620 LOG_DBG(
"uncompression: address %d %d ", prefcount, postcount);
623 memcpy(
ipaddr, prefix, prefcount);
625 if(prefcount + postcount < 16) {
626 memset(&
ipaddr->u8[prefcount], 0, 16 - (prefcount + postcount));
630 LOG_WARN(
"Insufficient packet data to decompress IP address\n");
635 if(postcount == 2 && prefcount < 11) {
641 }
else if (prefcount > 0) {
688 uint8_t tmp, iphc0, iphc1, *next_hdr, *next_nhc;
690 struct uip_udp_hdr *udp_buf;
692 if(LOG_DBG_ENABLED) {
694 LOG_DBG(
"compression: before (%d): ",
UIP_IP_BUF->len[1]);
695 for(ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
696 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
697 LOG_DBG_(
"%02x", data);
704#define CHECK_BUFFER_SPACE(writelen) do { \
705 if(iphc_ptr + (writelen) >= PACKETBUF_PAYLOAD_END) { \
706 LOG_WARN("Not enough packetbuf space to compress header (%u bytes, %u left). Aborting.\n", \
707 (unsigned)(writelen), (unsigned)(PACKETBUF_PAYLOAD_END - iphc_ptr)); \
717 CHECK_BUFFER_SPACE(38);
726 iphc0 = SICSLOWPAN_DISPATCH_IPHC;
728 PACKETBUF_IPHC_BUF[2] = 0;
742 if(source_context || destination_context) {
744 LOG_DBG(
"compression: dest or src ipaddr - setting CID\n");
745 iphc1 |= SICSLOWPAN_IPHC_CID;
759 tmp = ((tmp & 0x03) << 6) | (tmp >> 2);
764 iphc0 |= SICSLOWPAN_IPHC_FL_C;
768 iphc0 |= SICSLOWPAN_IPHC_TC_C;
779 iphc0 |= SICSLOWPAN_IPHC_TC_C;
796 if(IS_COMPRESSABLE_PROTO(
UIP_IP_BUF->proto)) {
797 iphc0 |= SICSLOWPAN_IPHC_NH_C;
801 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
815 iphc0 |= SICSLOWPAN_IPHC_TTL_1;
818 iphc0 |= SICSLOWPAN_IPHC_TTL_64;
821 iphc0 |= SICSLOWPAN_IPHC_TTL_255;
831 LOG_DBG(
"compression: addr unspecified - setting SAC\n");
832 iphc1 |= SICSLOWPAN_IPHC_SAC;
833 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
834 }
else if(source_context) {
836 LOG_DBG(
"compression: src with context - setting CID & SAC ctx: %d\n",
837 source_context->number);
838 iphc1 |= SICSLOWPAN_IPHC_CID | SICSLOWPAN_IPHC_SAC;
839 PACKETBUF_IPHC_BUF[2] |= source_context->number << 4;
842 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
849 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_SAM_BIT,
853 iphc1 |= SICSLOWPAN_IPHC_SAM_00;
861 iphc1 |= SICSLOWPAN_IPHC_M;
862 if(sicslowpan_is_mcast_addr_compressable8(&
UIP_IP_BUF->destipaddr)) {
863 iphc1 |= SICSLOWPAN_IPHC_DAM_11;
867 }
else if(sicslowpan_is_mcast_addr_compressable32(&
UIP_IP_BUF->destipaddr)) {
868 iphc1 |= SICSLOWPAN_IPHC_DAM_10;
873 }
else if(sicslowpan_is_mcast_addr_compressable48(&
UIP_IP_BUF->destipaddr)) {
874 iphc1 |= SICSLOWPAN_IPHC_DAM_01;
880 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
887 if(destination_context) {
889 iphc1 |= SICSLOWPAN_IPHC_DAC;
890 PACKETBUF_IPHC_BUF[2] |= destination_context->number;
893 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
895 (
const uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
901 iphc1 |= compress_addr_64(SICSLOWPAN_IPHC_DAM_BIT,
903 (
const uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER));
906 iphc1 |= SICSLOWPAN_IPHC_DAM_00;
918 LOG_DBG(
"compression: first header: %d\n", *next_hdr);
919 while(next_hdr != NULL && IS_COMPRESSABLE_PROTO(*next_hdr)) {
920 LOG_DBG(
"compression: next header: %d\n", *next_hdr);
925 proto = SICSLOWPAN_NHC_ETX_HDR_HBHO;
926 case UIP_PROTO_ROUTING:
927 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_ROUTING : proto;
929 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_FRAG : proto;
930 case UIP_PROTO_DESTO:
933 struct uip_ext_hdr *ext_hdr =
934 (
struct uip_ext_hdr *) UIP_IPPAYLOAD_BUF_POS(ext_hdr_len);
936 proto = proto == -1 ? SICSLOWPAN_NHC_ETX_HDR_DESTO : proto;
938 len = (ext_hdr->len << 3) + 8;
939 LOG_DBG(
"compression: next header %d (len:%d)\n", *next_hdr, len);
941 next_hdr = &ext_hdr->next;
945 if(!IS_COMPRESSABLE_PROTO(*next_hdr)) {
946 CHECK_BUFFER_SPACE(1);
948 LOG_DBG(
"compression: keeping the next header in this ext hdr: %d\n",
952 CHECK_BUFFER_SPACE(len);
955 ext_hdr = (
struct uip_ext_hdr *)
iphc_ptr;
956 ext_hdr->len = len - 2;
963 *next_nhc = SICSLOWPAN_NHC_EXT_HDR |
964 (IS_COMPRESSABLE_PROTO(*next_hdr) ? SICSLOWPAN_NHC_BIT : 0) |
973 udp_buf = UIP_UDP_BUF_POS(ext_hdr_len);
974 LOG_DBG(
"compression: inlined UDP ports on send side: %x, %x\n",
977 if(((
UIP_HTONS(udp_buf->srcport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN) &&
978 ((
UIP_HTONS(udp_buf->destport) & 0xfff0) == SICSLOWPAN_UDP_4_BIT_PORT_MIN)) {
980 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_11;
981 LOG_DBG(
"IPHC: remove 12 b of both source & dest with prefix 0xFOB\n");
982 CHECK_BUFFER_SPACE(1);
985 SICSLOWPAN_UDP_4_BIT_PORT_MIN) << 4) +
986 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
987 SICSLOWPAN_UDP_4_BIT_PORT_MIN));
989 }
else if((
UIP_HTONS(udp_buf->destport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
991 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_01;
992 LOG_DBG(
"IPHC: leave source, remove 8 bits of dest with prefix 0xF0\n");
993 CHECK_BUFFER_SPACE(3);
994 memcpy(
iphc_ptr, &udp_buf->srcport, 2);
996 (uint8_t)((
UIP_HTONS(udp_buf->destport) -
997 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
999 }
else if((
UIP_HTONS(udp_buf->srcport) & 0xff00) == SICSLOWPAN_UDP_8_BIT_PORT_MIN) {
1001 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_10;
1002 LOG_DBG(
"IPHC: remove 8 bits of source with prefix 0xF0, leave dest. hch: %i\n", *next_nhc);
1003 CHECK_BUFFER_SPACE(3);
1005 (uint8_t)((
UIP_HTONS(udp_buf->srcport) -
1006 SICSLOWPAN_UDP_8_BIT_PORT_MIN));
1007 memcpy(
iphc_ptr + 1, &udp_buf->destport, 2);
1011 *next_nhc = SICSLOWPAN_NHC_UDP_CS_P_00;
1012 LOG_DBG(
"IPHC: cannot compress UDP headers\n");
1013 CHECK_BUFFER_SPACE(4);
1014 memcpy(
iphc_ptr, &udp_buf->srcport, 4);
1018 CHECK_BUFFER_SPACE(2);
1019 memcpy(
iphc_ptr, &udp_buf->udpchksum, 2);
1026 LOG_ERR(
"compression: could not handle compression of header");
1029 if(next_hdr != NULL) {
1032 LOG_DBG(
"compression: last header could is not compressed: %d\n", *next_hdr);
1035 PACKETBUF_IPHC_BUF[0] = iphc0;
1036 PACKETBUF_IPHC_BUF[1] = iphc1;
1038 if(LOG_DBG_ENABLED) {
1043 LOG_DBG_(
"%02x", data);
1075 uint8_t tmp, iphc0, iphc1, nhc;
1076 struct uip_ext_hdr *exthdr;
1077 uint8_t* last_nextheader;
1078 uint8_t* ip_payload;
1079 uint8_t ext_hdr_len = 0;
1084#define CHECK_READ_SPACE(readlen) \
1085 if((iphc_ptr - packetbuf_ptr) + (readlen) > cmpr_len) { \
1086 LOG_WARN("Not enough packetbuf space to decompress header (%u bytes, %u left). Aborting.\n", \
1087 (unsigned)(readlen), (unsigned)(cmpr_len - (iphc_ptr - packetbuf_ptr))); \
1098 iphc0 = PACKETBUF_IPHC_BUF[0];
1099 iphc1 = PACKETBUF_IPHC_BUF[1];
1102 if(iphc1 & SICSLOWPAN_IPHC_CID) {
1103 LOG_DBG(
"uncompression: CID flag set - increase header with one\n");
1108 if((iphc0 & SICSLOWPAN_IPHC_FL_C) == 0) {
1110 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1112 CHECK_READ_SPACE(4);
1113 memcpy(&SICSLOWPAN_IP_BUF(buf)->tcflow,
iphc_ptr + 1, 3);
1118 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((tmp >> 2) & 0x0f);
1120 SICSLOWPAN_IP_BUF(buf)->tcflow = ((tmp >> 2) & 0x30) | (tmp << 6) |
1121 (SICSLOWPAN_IP_BUF(buf)->tcflow & 0x0f);
1124 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1126 CHECK_READ_SPACE(3);
1127 SICSLOWPAN_IP_BUF(buf)->tcflow = (*
iphc_ptr & 0x0F) |
1129 memcpy(&SICSLOWPAN_IP_BUF(buf)->flow,
iphc_ptr + 1, 2);
1135 if((iphc0 & SICSLOWPAN_IPHC_TC_C) == 0) {
1137 CHECK_READ_SPACE(1);
1138 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60 | ((*
iphc_ptr >> 2) & 0x0f);
1139 SICSLOWPAN_IP_BUF(buf)->tcflow = ((*
iphc_ptr << 6) & 0xC0) | ((*
iphc_ptr >> 2) & 0x30);
1140 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1144 SICSLOWPAN_IP_BUF(buf)->vtc = 0x60;
1145 SICSLOWPAN_IP_BUF(buf)->tcflow = 0;
1146 SICSLOWPAN_IP_BUF(buf)->flow = 0;
1151 if((iphc0 & SICSLOWPAN_IPHC_NH_C) == 0) {
1153 CHECK_READ_SPACE(1);
1154 SICSLOWPAN_IP_BUF(buf)->proto = *
iphc_ptr;
1155 LOG_DBG(
"uncompression: next header inline: %d\n", SICSLOWPAN_IP_BUF(buf)->proto);
1160 if((iphc0 & 0x03) != SICSLOWPAN_IPHC_TTL_I) {
1161 SICSLOWPAN_IP_BUF(buf)->ttl = ttl_values[iphc0 & 0x03];
1163 CHECK_READ_SPACE(1);
1164 SICSLOWPAN_IP_BUF(buf)->ttl = *
iphc_ptr;
1169 tmp = ((iphc1 & SICSLOWPAN_IPHC_SAM_11) >> SICSLOWPAN_IPHC_SAM_BIT) & 0x03;
1172 if(iphc1 & SICSLOWPAN_IPHC_SAC) {
1173 uint8_t sci = (iphc1 & SICSLOWPAN_IPHC_CID) ?
1174 PACKETBUF_IPHC_BUF[2] >> 4 : 0;
1180 if(!source_context) {
1181 LOG_ERR(
"uncompression: error source context not found\n");
1185 source_context = NULL;
1188 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr,
1189 source_context ? source_context->prefix : NULL,
1191 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
1196 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->srcipaddr, llprefix,
1198 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
1205 tmp = ((iphc1 & SICSLOWPAN_IPHC_DAM_11) >> SICSLOWPAN_IPHC_DAM_BIT) & 0x03;
1208 if(iphc1 & SICSLOWPAN_IPHC_M) {
1210 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1218 uint8_t prefix[] = {0xff, 0x02};
1219 if(tmp > 0 && tmp < 3) {
1220 CHECK_READ_SPACE(1);
1225 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, prefix,
1226 unc_mxconf[tmp], NULL)) {
1233 if(iphc1 & SICSLOWPAN_IPHC_DAC) {
1234 uint8_t dci = (iphc1 & SICSLOWPAN_IPHC_CID) ? PACKETBUF_IPHC_BUF[2] & 0x0f : 0;
1239 if(!destination_context) {
1240 LOG_ERR(
"uncompression: error destination context not found\n");
1243 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr,
1244 destination_context->prefix,
1246 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) {
1251 if(!uncompress_addr(&SICSLOWPAN_IP_BUF(buf)->destipaddr, llprefix,
1253 (uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_RECEIVER))) {
1261 nhc = iphc0 & SICSLOWPAN_IPHC_NH_C;
1263 last_nextheader = &SICSLOWPAN_IP_BUF(buf)->proto;
1264 ip_payload = SICSLOWPAN_IPPAYLOAD_BUF(buf);
1266 CHECK_READ_SPACE(1);
1267 while(nhc && (*
iphc_ptr & SICSLOWPAN_NHC_MASK) == SICSLOWPAN_NHC_EXT_HDR) {
1268 uint8_t eid = (*
iphc_ptr & 0x0e) >> 1;
1278 CHECK_READ_SPACE(1);
1282 LOG_DBG(
"uncompression: next header is inlined. Next: %d\n", next);
1284 CHECK_READ_SPACE(1);
1288 LOG_DBG(
"uncompression: found ext header id: %d next: %d len: %d\n", eid, next, len);
1290 case SICSLOWPAN_NHC_ETX_HDR_HBHO:
1293 case SICSLOWPAN_NHC_ETX_HDR_ROUTING:
1294 proto = UIP_PROTO_ROUTING;
1296 case SICSLOWPAN_NHC_ETX_HDR_FRAG:
1297 proto = UIP_PROTO_FRAG;
1299 case SICSLOWPAN_NHC_ETX_HDR_DESTO:
1300 proto = UIP_PROTO_DESTO;
1303 LOG_DBG(
"uncompression: error unsupported ext header\n");
1306 *last_nextheader = proto;
1309 if((ip_payload - buf) + UIP_EXT_HDR_LEN + len > buf_size) {
1310 LOG_WARN(
"uncompression: cannot write ext header beyond target buffer\n");
1315 exthdr = (
struct uip_ext_hdr *)ip_payload;
1316 exthdr->len = (UIP_EXT_HDR_LEN + len) / 8;
1317 if(exthdr->len == 0) {
1318 LOG_WARN(
"Extension header length is below 8\n");
1322 exthdr->next = next;
1323 last_nextheader = &exthdr->next;
1326 CHECK_READ_SPACE(len + 1);
1327 memcpy((uint8_t *)exthdr + UIP_EXT_HDR_LEN,
iphc_ptr, len);
1331 ip_payload += (exthdr->len + 1) * 8;
1332 ext_hdr_len += (exthdr->len + 1) * 8;
1334 LOG_DBG(
"uncompression: %d len: %d exthdr len: %d (calc: %d)\n",
1335 proto, len, exthdr->len, (exthdr->len + 1) * 8);
1339 CHECK_READ_SPACE(1);
1340 if(nhc && (*
iphc_ptr & SICSLOWPAN_NHC_UDP_MASK) == SICSLOWPAN_NHC_UDP_ID) {
1341 struct uip_udp_hdr *udp_buf;
1343 uint8_t checksum_compressed;
1346 if((ip_payload - buf) + UIP_UDPH_LEN > buf_size) {
1347 LOG_WARN(
"uncompression: cannot write UDP header beyond target buffer\n");
1351 udp_buf = (
struct uip_udp_hdr *)ip_payload;
1352 *last_nextheader = UIP_PROTO_UDP;
1353 checksum_compressed = *
iphc_ptr & SICSLOWPAN_NHC_UDP_CHECKSUMC;
1354 LOG_DBG(
"uncompression: incoming header value: %i\n", *
iphc_ptr);
1355 switch(*
iphc_ptr & SICSLOWPAN_NHC_UDP_CS_P_11) {
1356 case SICSLOWPAN_NHC_UDP_CS_P_00:
1358 CHECK_READ_SPACE(5);
1359 memcpy(&udp_buf->srcport,
iphc_ptr + 1, 2);
1360 memcpy(&udp_buf->destport,
iphc_ptr + 3, 2);
1361 LOG_DBG(
"uncompression: UDP ports (ptr+5): %x, %x\n",
1367 case SICSLOWPAN_NHC_UDP_CS_P_01:
1369 LOG_DBG(
"uncompression: destination address\n");
1370 CHECK_READ_SPACE(4);
1371 memcpy(&udp_buf->srcport,
iphc_ptr + 1, 2);
1372 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN + (*(
iphc_ptr + 3)));
1373 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1378 case SICSLOWPAN_NHC_UDP_CS_P_10:
1380 LOG_DBG(
"uncompression: source address\n");
1381 CHECK_READ_SPACE(4);
1382 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_8_BIT_PORT_MIN +
1384 memcpy(&udp_buf->destport,
iphc_ptr + 2, 2);
1385 LOG_DBG(
"uncompression: UDP ports (ptr+4): %x, %x\n",
1390 case SICSLOWPAN_NHC_UDP_CS_P_11:
1392 CHECK_READ_SPACE(2);
1393 udp_buf->srcport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1395 udp_buf->destport =
UIP_HTONS(SICSLOWPAN_UDP_4_BIT_PORT_MIN +
1397 LOG_DBG(
"uncompression: UDP ports (ptr+2): %x, %x\n",
1403 LOG_DBG(
"uncompression: error unsupported UDP compression\n");
1406 if(!checksum_compressed) {
1407 CHECK_READ_SPACE(2);
1408 memcpy(&udp_buf->udpchksum,
iphc_ptr, 2);
1410 LOG_DBG(
"uncompression: checksum included\n");
1412 LOG_DBG(
"uncompression: checksum *NOT* included\n");
1417 udp_buf->udplen =
UIP_HTONS(ip_len == 0 ? udp_len :
1418 ip_len - UIP_IPH_LEN - ext_hdr_len);
1419 LOG_DBG(
"uncompression: UDP length: %u (ext: %u) ip_len: %d udp_len: %d\n",
1420 UIP_HTONS(udp_buf->udplen), ext_hdr_len, ip_len, udp_len);
1430 LOG_DBG(
"uncompression: IP payload length: %d. %u - %u + %u - %u\n", len,
1434 SICSLOWPAN_IP_BUF(buf)->len[0] = len >> 8;
1435 SICSLOWPAN_IP_BUF(buf)->len[1] = len & 0x00FF;
1438 SICSLOWPAN_IP_BUF(buf)->len[0] = (ip_len - UIP_IPH_LEN) >> 8;
1439 SICSLOWPAN_IP_BUF(buf)->len[1] = (ip_len - UIP_IPH_LEN) & 0x00FF;
1447#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH
1456 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] = SICSLOWPAN_DISPATCH_PAGING | (page & 0x0f);
1478 if((PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_PAGING_MASK) == SICSLOWPAN_DISPATCH_PAGING) {
1480 curr_page = PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & 0x0f;
1509#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
1511compress_hdr_ipv6(
void)
1531 const linkaddr_t *dest;
1533 if(callback != NULL) {
1534 callback->output_callback(status);
1539 dest = packetbuf_addr(PACKETBUF_ADDR_RECEIVER);
1545 link_stats_packet_sent(dest, status, transmissions);
1548 NETSTACK_ROUTING.
link_callback(dest, status, transmissions);
1569#if SICSLOWPAN_CONF_FRAG
1579fragment_copy_payload_and_send(uint16_t uip_offset)
1589 q = queuebuf_new_from_packetbuf();
1591 LOG_WARN(
"output: could not allocate queuebuf, dropping fragment\n");
1599 queuebuf_to_packetbuf(q);
1605 LOG_ERR(
"output: error in fragment tx, dropping subsequent fragments.\n");
1640 LOG_INFO(
"output: sending IPv6 packet with len %d\n",
uip_len);
1643 packetbuf_set_attr(PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
1644 uipbuf_get_attr(UIPBUF_ATTR_MAX_MAC_TRANSMISSIONS));
1647 packetbuf_set_addr(PACKETBUF_ADDR_RECEIVER,
1650#if LLSEC802154_USES_AUX_HEADER
1652 packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL,
1653 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_LEVEL));
1654#if LLSEC802154_USES_EXPLICIT_KEYS
1655 packetbuf_set_attr(PACKETBUF_ATTR_KEY_INDEX,
1656 uipbuf_get_attr(UIPBUF_ATTR_LLSEC_KEY_ID));
1665 LOG_WARN(
"output: failed to calculate payload size - dropping packet\n");
1670#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPV6
1671 compress_hdr_ipv6();
1673#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_6LORH
1681#if SICSLOWPAN_COMPRESSION >= SICSLOWPAN_COMPRESSION_IPHC
1693 LOG_INFO(
"output: header len %d -> %d, total len %d -> %d, MAC max payload %d, frag_needed %d\n",
1699#if SICSLOWPAN_CONF_FRAG
1701 uint16_t processed_ip_out_len;
1718 int fragn_max_payload = (
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN) & 0xfffffff8;
1720 int last_fragn_max_payload =
mac_max_payload - SICSLOWPAN_FRAGN_HDR_LEN;
1722 int middle_fragn_total_payload = MAX(total_payload - frag1_payload - last_fragn_max_payload, 0);
1724 unsigned fragment_count = 2;
1725 if(middle_fragn_total_payload > 0) {
1726 fragment_count += 1 + (middle_fragn_total_payload - 1) / fragn_max_payload;
1729 size_t free_bufs = queuebuf_numfree();
1730 LOG_INFO(
"output: fragmentation needed. fragments: %u, free queuebufs: %zu\n",
1731 fragment_count, free_bufs);
1735 size_t needed_bufs = fragment_count + 1;
1736 if(free_bufs < needed_bufs) {
1737 LOG_WARN(
"output: dropping packet, not enough free bufs (needed: %zu, free: %zu)\n",
1738 needed_bufs, free_bufs);
1742 if(frag1_payload < 0) {
1746 LOG_WARN(
"output: compressed header does not fit first fragment\n");
1753 frag_tag = my_tag++;
1760 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1761 ((SICSLOWPAN_DISPATCH_FRAG1 << 8) |
uip_len));
1762 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG, frag_tag);
1769 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d)\n",
1770 curr_frag + 1, fragment_count,
1780 SET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE,
1781 ((SICSLOWPAN_DISPATCH_FRAGN << 8) |
uip_len));
1787 while(processed_ip_out_len <
uip_len) {
1790 PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET] = processed_ip_out_len >> 3;
1793 if(
uip_len - processed_ip_out_len > last_fragn_max_payload) {
1803 LOG_INFO(
"output: fragment %d/%d (tag %d, payload %d, offset %d)\n",
1804 curr_frag + 1, fragment_count,
1806 if(fragment_copy_payload_and_send(processed_ip_out_len) == 0) {
1813 LOG_ERR(
"output: Packet too large to be sent without fragmentation support; dropping packet\n");
1823 LOG_ERR(
"output: uip_len is smaller than uncomp_hdr_len (%d < %d)",
1852 uint16_t frag_size = 0;
1854 uint8_t frag_offset = 0;
1856 uint16_t buffer_size;
1858#if SICSLOWPAN_CONF_FRAG
1859 uint8_t is_fragment = 0;
1860 int8_t frag_context = 0;
1863 uint16_t frag_tag = 0;
1864 uint8_t first_fragment = 0, last_fragment = 0;
1868 link_stats_input_callback(packetbuf_addr(PACKETBUF_ADDR_SENDER));
1878 LOG_WARN(
"input: empty packet\n");
1891 uipbuf_set_attr(UIPBUF_ATTR_RSSI, packetbuf_attr(PACKETBUF_ATTR_RSSI));
1892 uipbuf_set_attr(UIPBUF_ATTR_LINK_QUALITY, packetbuf_attr(PACKETBUF_ATTR_LINK_QUALITY));
1895#if SICSLOWPAN_CONF_FRAG
1901 switch((GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) >> 8) & SICSLOWPAN_DISPATCH_FRAG_MASK) {
1902 case SICSLOWPAN_DISPATCH_FRAG1:
1904 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1905 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1910 LOG_INFO(
"input: received first element of a fragmented packet (tag %d, len %d)\n",
1911 frag_tag, frag_size);
1914 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1916 if(frag_context == -1) {
1917 LOG_ERR(
"input: failed to allocate new reassembly context\n");
1921 buffer = frag_info[frag_context].first_frag;
1922 buffer_size = SICSLOWPAN_FIRST_FRAGMENT_SIZE;
1924 case SICSLOWPAN_DISPATCH_FRAGN:
1929 frag_offset = PACKETBUF_FRAG_PTR[PACKETBUF_FRAG_OFFSET];
1930 frag_tag = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_TAG);
1931 frag_size = GET16(PACKETBUF_FRAG_PTR, PACKETBUF_FRAG_DISPATCH_SIZE) & 0x07ff;
1936 frag_context = add_fragment(frag_tag, frag_size, frag_offset);
1938 if(frag_context == -1) {
1939 LOG_ERR(
"input: reassembly context not found (tag %d)\n", frag_tag);
1947 if(frag_info[frag_context].reassembled_len >= frag_size) {
1956 if(is_fragment && !first_fragment) {
1966 LOG_INFO(
"input: page 1, 6LoRH\n");
1969 LOG_ERR(
"input: page %u not supported\n",
curr_page);
1975 (PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK) == SICSLOWPAN_DISPATCH_IPHC) {
1976 LOG_DBG(
"uncompression: IPHC dispatch\n");
1978 LOG_ERR(
"input: failed to decompress IPHC packet\n");
1981 }
else if(PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] == SICSLOWPAN_DISPATCH_IPV6) {
1982 LOG_DBG(
"uncompression: IPV6 dispatch\n");
1992 LOG_ERR(
"uncompression: unknown dispatch: 0x%02x, or IPHC disabled\n",
1993 PACKETBUF_6LO_PTR[PACKETBUF_6LO_DISPATCH] & SICSLOWPAN_DISPATCH_IPHC_MASK);
1997#if SICSLOWPAN_CONF_FRAG
2008 LOG_ERR(
"input: packet dropped due to header > total packet\n");
2013#if SICSLOWPAN_CONF_FRAG
2015 LOG_INFO(
"input: fragment (tag %d, payload %d, offset %d) -- %u %u\n",
2022 unsigned int req_size =
uncomp_hdr_len + (uint16_t)(frag_offset << 3)
2024 if(req_size >
sizeof(
uip_buf)) {
2025#if SICSLOWPAN_CONF_FRAG
2027 "input: packet and fragment context %u dropped, minimum required IP_BUF size: %d+%d+%d=%u (current size: %u)\n",
2033 clear_fragments(frag_context);
2041 if(buffer != NULL) {
2043 LOG_ERR(
"input: cannot copy the payload into the buffer\n");
2051#if SICSLOWPAN_CONF_FRAG
2054 if(first_fragment != 0) {
2060 if(last_fragment != 0) {
2061 frag_info[frag_context].reassembled_len = frag_size;
2063 if(!copy_frags2uip(frag_context)) {
2073 if(!is_fragment || last_fragment) {
2075 if(is_fragment != 0 && last_fragment != 0) {
2083 LOG_INFO(
"input: received IPv6 packet with len %d\n",
2086 if(LOG_DBG_ENABLED) {
2088 LOG_DBG(
"uncompression: after (%u):",
UIP_IP_BUF->len[1]);
2089 for (ndx = 0; ndx <
UIP_IP_BUF->len[1] + 40; ndx++) {
2090 uint8_t data = ((uint8_t *) (
UIP_IP_BUF))[ndx];
2091 LOG_DBG_(
"%02x", data);
2099 callback->input_callback();
2102#if LLSEC802154_USES_AUX_HEADER
2107 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_LEVEL,
2108 packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL));
2109#if LLSEC802154_USES_EXPLICIT_KEYS
2110 uipbuf_set_attr(UIPBUF_ATTR_LLSEC_KEY_ID,
2111 packetbuf_attr(PACKETBUF_ATTR_KEY_INDEX));
2116#if SICSLOWPAN_CONF_FRAG
2126sicslowpan_init(
void)
2129#if SICSLOWPAN_COMPRESSION == SICSLOWPAN_COMPRESSION_IPHC
2135#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 0
2136 addr_contexts[0].used = 1;
2137 addr_contexts[0].number = 0;
2138#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_0
2139 SICSLOWPAN_CONF_ADDR_CONTEXT_0;
2141 addr_contexts[0].prefix[0] = UIP_DS6_DEFAULT_PREFIX_0;
2142 addr_contexts[0].prefix[1] = UIP_DS6_DEFAULT_PREFIX_1;
2146#if SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS > 1
2150#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_1
2152 addr_contexts[1].used = 1;
2153 addr_contexts[1].number = 1;
2154 SICSLOWPAN_CONF_ADDR_CONTEXT_1;
2155#ifdef SICSLOWPAN_CONF_ADDR_CONTEXT_2
2157 addr_contexts[2].used = 1;
2158 addr_contexts[2].number = 2;
2159 SICSLOWPAN_CONF_ADDR_CONTEXT_2;
2162 addr_contexts[i].used = 0;
2165 addr_contexts[i].used = 0;
void watchdog_periodic(void)
Writes the WDT clear sequence.
static volatile uint64_t count
Num.
#define CLOCK_SECOND
A second, measured in system clock time.
void linkaddr_copy(linkaddr_t *dest, const linkaddr_t *src)
Copy a link-layer address.
bool linkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2)
Compare two link-layer addresses.
const linkaddr_t linkaddr_null
The null link-layer address.
void packetbuf_set_datalen(uint16_t len)
Set the length of the data in the packetbuf.
void * packetbuf_dataptr(void)
Get a pointer to the data in the packetbuf.
uint16_t packetbuf_datalen(void)
Get the length of the data in the packetbuf.
void packetbuf_clear(void)
Clear and reset the packetbuf.
static void digest_6lorh_hdr(void)
Digest 6lorh headers before IPHC.
static void send_packet(void)
This function is called by the 6lowpan code to send out a packet.
static uint8_t curr_page
The current page (RFC 4944)
static uint8_t * packetbuf_ptr
A pointer to the packetbuf buffer.
static int mac_max_payload
mac_max_payload is the maimum payload space on the MAC frame.
static uint8_t * iphc_ptr
Addresses contexts for IPHC.
#define sicslowpan_is_iid_16_bit_compressable(a)
check whether we can compress the IID in address 'a' to 16 bits.
static struct sicslowpan_addr_context * addr_context_lookup_by_prefix(uip_ipaddr_t *ipaddr)
find the context corresponding to prefix ipaddr
static uint8_t uncomp_hdr_len
uncomp_hdr_len is the length of the headers before compression (if HC2 is used this includes the UDP ...
static int last_tx_status
the result of the last transmitted fragment
static uint8_t output(const linkaddr_t *localdest)
Take an IP packet and format it to be sent on an 802.15.4 network using 6lowpan.
static int compress_hdr_iphc(void)
Compress IP/UDP header.
static bool uncompress_hdr_iphc(uint8_t *buf, uint16_t buf_size, uint16_t ip_len)
Uncompress IPHC (i.e., IPHC and LOWPAN_UDP) headers and put them in sicslowpan_buf.
static void add_paging_dispatch(uint8_t page)
Adds Paging dispatch byte.
static void packet_sent(void *ptr, int status, int transmissions)
Callback function for the MAC packet sent callback.
static struct sicslowpan_addr_context * addr_context_lookup_by_number(uint8_t number)
find the context with the given number
static uint8_t packetbuf_hdr_len
packetbuf_hdr_len is the total length of (the processed) 6lowpan headers (fragment headers,...
static void add_6lorh_hdr(void)
Adds 6lorh headers before IPHC.
static void input(void)
Process a received 6lowpan packet.
static int packetbuf_payload_len
The length of the payload in the Packetbuf buffer.
static void digest_paging_dispatch(void)
Digest 6lorh headers before IPHC.
void tcpip_input(void)
Deliver an incoming packet to the TCP/IP stack.
void timer_set(struct timer *t, clock_time_t interval)
Set a timer.
bool timer_expired(struct timer *t)
Check if a timer has expired.
#define uip_is_addr_mac_addr_based(a, m)
was addr (a) forged based on the mac address m a type is uip_ipaddr_t m type is uiplladdr_t
uip_lladdr_t uip_lladdr
Host L2 address.
#define uip_is_addr_unspecified(a)
Is IPv6 address a the unspecified address a is of type uip_ipaddr_t.
#define UIP_ICMP_BUF
Direct access to ICMP, UDP, and TCP headers and payload, with implicit ext header offset (global uip_...
#define uip_is_addr_mcast(a)
is address a multicast address, see RFC 4291 a is of type uip_ipaddr_t*
#define uip_is_addr_linklocal(a)
is addr (a) a link local unicast address, see RFC 4291 i.e.
void uip_ds6_set_addr_iid(uip_ipaddr_t *ipaddr, const uip_lladdr_t *lladdr)
set the last 64 bits of an IP address based on the MAC address
void uip_ds6_link_callback(int status, int numtx)
The callback function to update link-layer stats in a neighbor cache.
#define UIP_PROTO_HBHO
extension headers types
#define UIP_IP_BUF
Direct access to IPv6 header.
#define UIP_HTONS(n)
Convert 16-bit quantity from host byte order to network byte order.
#define uip_buf
Macro to access uip_aligned_buf as an array of bytes.
uint16_t uip_len
The length of the packet in the uip_buf buffer.
#define UIP_BUFSIZE
The size of the uIP packet buffer.
#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS
If we use IPHC compression, how many address contexts do we support.
#define SICSLOWPAN_REASS_MAXAGE
Timeout for packet reassembly at the 6LoWPAN layer (should be < 60s)
#define SICSLOWPAN_COMPRESSION
Determines whether the 6LoWPAN layer uses IP header compression.
Header file for the logging system.
@ MAC_TX_COLLISION
The MAC layer did not get an acknowledgement for the packet.
@ MAC_TX_OK
The MAC layer transmission was OK.
@ MAC_TX_ERR
The MAC layer transmission could not be performed because of a fatal error.
Include file for the Contiki low-layer network stack (NETSTACK)
Header file for the Packet buffer (packetbuf) management.
Header file for the Packet queue buffer management.
Routing driver header file.
Header file for the 6lowpan implementation (RFC4944 and draft-hui-6lowpan-hc-01)
int(* max_payload)(void)
Read out estimated max payload size based on payload in packetbuf.
void(* send)(mac_callback_t sent_callback, void *ptr)
Send a packet from the packetbuf
The structure of a network driver in Contiki.
uint8_t(* output)(const linkaddr_t *localdest)
Output funtion, sends from uipbuf.
void(* link_callback)(const linkaddr_t *addr, int status, int numtx)
Called by lower layers after every packet transmission.
An address context for IPHC address compression each context can have upto 8 bytes.
Header for the Contiki/uIP interface.
Header file for IPv6-related data structures.
static uip_ipaddr_t ipaddr
Pointer to prefix information option in uip_buf.
Header file for the uIP TCP/IP stack.
Configuration options for uIP.