*** stock_iot-lab_M3/openwsn/03a-IPHC/iphc.c Thu Apr 24 11:01:36 2014 --- riot-openwsn-wip/openwsn/03a-IPHC/iphc.c Thu Apr 24 16:55:54 2014 *************** *** 12,18 **** //=========================== prototypes ====================================== ! error_t prependIPv6Header( OpenQueueEntry_t* msg, uint8_t tf, uint32_t value_flowLabel, --- 12,18 ---- //=========================== prototypes ====================================== ! owerror_t prependIPv6Header( OpenQueueEntry_t* msg, uint8_t tf, uint32_t value_flowLabel, *************** *** 31,44 **** uint8_t fw_SendOrfw_Rcv ); ipv6_header_iht retrieveIPv6Header(OpenQueueEntry_t* msg); ! //=========================== public ========================================== ! void iphc_init() { } //send from upper layer: I need to add 6LoWPAN header ! error_t iphc_sendFromForwarding(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, uint8_t fw_SendOrfw_Rcv) { open_addr_t temp_dest_prefix; open_addr_t temp_dest_mac64b; open_addr_t* p_dest; --- 31,46 ---- uint8_t fw_SendOrfw_Rcv ); ipv6_header_iht retrieveIPv6Header(OpenQueueEntry_t* msg); ! //hop by hop header ! void prependIPv6HopByHopHeader(OpenQueueEntry_t* msg,uint8_t nextheader, bool nh, rpl_hopoption_ht *hopbyhop_option); ! void retrieveIPv6HopByHopHeader(OpenQueueEntry_t* msg, ipv6_hopbyhop_ht *hopbyhop_header, rpl_hopoption_ht *rpl_option); //=========================== public ========================================== ! void iphc_init(void) { } //send from upper layer: I need to add 6LoWPAN header ! owerror_t iphc_sendFromForwarding(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, rpl_hopoption_ht *hopbyhop_option, uint8_t fw_SendOrfw_Rcv) { open_addr_t temp_dest_prefix; open_addr_t temp_dest_mac64b; open_addr_t* p_dest; *************** *** 48,54 **** uint8_t sam; uint8_t dam; uint8_t nh; ! // take ownership over the packet msg->owner = COMPONENT_IPHC; --- 50,58 ---- uint8_t sam; uint8_t dam; uint8_t nh; ! uint8_t next_header; ! //option header ! // take ownership over the packet msg->owner = COMPONENT_IPHC; *************** *** 85,90 **** --- 89,95 ---- if (fw_SendOrfw_Rcv==PCKTFORWARD){ sam = IPHC_SAM_64B; //case forwarding a packet p_src = &temp_src_mac64b; + //poipoi xv forcing elided addresses on src routing, this needs to be fixed so any type of address should be supported supported. } else if (fw_SendOrfw_Rcv==PCKTSEND){ sam = IPHC_SAM_ELIDED; p_src = NULL; *************** *** 92,100 **** openserial_printCritical(COMPONENT_IPHC,ERR_INVALID_FWDMODE, (errorparameter_t)0, (errorparameter_t)0); ! } ! dam = IPHC_DAM_ELIDED; ! p_dest = NULL; } else { //else, not a direct neighbour use 64B address sam = IPHC_SAM_64B; --- 97,105 ---- openserial_printCritical(COMPONENT_IPHC,ERR_INVALID_FWDMODE, (errorparameter_t)0, (errorparameter_t)0); ! } ! dam = IPHC_DAM_ELIDED; ! p_dest = NULL; } else { //else, not a direct neighbour use 64B address sam = IPHC_SAM_64B; *************** *** 113,119 **** }else{ //source routing sam = IPHC_SAM_128B; ! dam = IPHC_DAM_ELIDED; p_dest = NULL; p_src = &(msg->l3_sourceAdd); } --- 118,124 ---- }else{ //source routing sam = IPHC_SAM_128B; ! dam = IPHC_DAM_ELIDED; //poipoi xv not true, should not be elided. p_dest = NULL; p_src = &(msg->l3_sourceAdd); } *************** *** 125,135 **** // decrement the packet's hop limit ipv6_header.hop_limit--; if (prependIPv6Header(msg, IPHC_TF_ELIDED, 0, // value_flowlabel is not copied nh, ! msg->l4_protocol, IPHC_HLIM_INLINE, ipv6_header.hop_limit, IPHC_CID_NO, --- 130,149 ---- // decrement the packet's hop limit ipv6_header.hop_limit--; + //prepend Option hop by hop header except when src routing and dst is not 0xffff -- this is a little trick as src routing is using an option header set to 0x00 + next_header=msg->l4_protocol; + if (hopbyhop_option->optionType==RPL_HOPBYHOP_HEADER_OPTION_TYPE + && packetfunctions_isBroadcastMulticast(&(msg->l3_destinationAdd))==FALSE ){ + prependIPv6HopByHopHeader(msg, msg->l4_protocol, nh, hopbyhop_option); + //change nh to point to the newly added header + next_header=IANA_IPv6HOPOPT;// use 0x00 as NH to indicate option header -- see rfc 2460 + } + //then regular header if (prependIPv6Header(msg, IPHC_TF_ELIDED, 0, // value_flowlabel is not copied nh, ! next_header, IPHC_HLIM_INLINE, ipv6_header.hop_limit, IPHC_CID_NO, *************** *** 144,149 **** --- 158,164 ---- )==E_FAIL) { return E_FAIL; } + return res_send(msg); } *************** *** 147,154 **** return res_send(msg); } //send from bridge: 6LoWPAN header already added by OpenLBR, send as is ! error_t iphc_sendFromBridge(OpenQueueEntry_t *msg) { msg->owner = COMPONENT_IPHC; // error checking if (idmanager_getIsBridge()==FALSE) { --- 162,172 ---- return res_send(msg); } + + + //send from bridge: 6LoWPAN header already added by OpenLBR, send as is ! owerror_t iphc_sendFromBridge(OpenQueueEntry_t *msg) { msg->owner = COMPONENT_IPHC; // error checking if (idmanager_getIsBridge()==FALSE) { *************** *** 160,166 **** return res_send(msg); } ! void iphc_sendDone(OpenQueueEntry_t* msg, error_t error) { msg->owner = COMPONENT_IPHC; if (msg->creator==COMPONENT_OPENBRIDGE) { openbridge_sendDone(msg,error); --- 178,184 ---- return res_send(msg); } ! void iphc_sendDone(OpenQueueEntry_t* msg, owerror_t error) { msg->owner = COMPONENT_IPHC; if (msg->creator==COMPONENT_OPENBRIDGE) { openbridge_sendDone(msg,error); *************** *** 171,182 **** void iphc_receive(OpenQueueEntry_t* msg) { ipv6_header_iht ipv6_header; msg->owner = COMPONENT_IPHC; ipv6_header = retrieveIPv6Header(msg); if (idmanager_getIsBridge()==FALSE || packetfunctions_isBroadcastMulticast(&(ipv6_header.dest))) { packetfunctions_tossHeader(msg,ipv6_header.header_length); ! forwarding_receive(msg,ipv6_header); //up the internal stack } else { openbridge_receive(msg); //out to the OpenVisualizer } --- 189,214 ---- void iphc_receive(OpenQueueEntry_t* msg) { ipv6_header_iht ipv6_header; + ipv6_hopbyhop_ht ipv6_hop_header; + rpl_hopoption_ht hop_by_hop_option; + msg->owner = COMPONENT_IPHC; + + //then regular header ipv6_header = retrieveIPv6Header(msg); + + if (idmanager_getIsBridge()==FALSE || packetfunctions_isBroadcastMulticast(&(ipv6_header.dest))) { packetfunctions_tossHeader(msg,ipv6_header.header_length); ! ! if (ipv6_header.next_header==IANA_IPv6HOPOPT){ ! //retrieve hop by hop header ! retrieveIPv6HopByHopHeader(msg,&ipv6_hop_header,&hop_by_hop_option); ! //toss the header + option +tlv on it if any ! packetfunctions_tossHeader(msg,IPv6HOP_HDR_LEN+ipv6_hop_header.HdrExtLen); ! } ! forwarding_receive(msg,ipv6_header,ipv6_hop_header,hop_by_hop_option); //up the internal stack } else { openbridge_receive(msg); //out to the OpenVisualizer } *************** *** 184,190 **** //=========================== private ========================================= ! error_t prependIPv6Header( OpenQueueEntry_t* msg, uint8_t tf, uint32_t value_flowLabel, --- 216,256 ---- //=========================== private ========================================= ! ! void prependIPv6HopByHopHeader(OpenQueueEntry_t *msg,uint8_t nextheader, bool nh, rpl_hopoption_ht *hopbyhop_option){ ! ! //copy them in reverse order, first option later header ! packetfunctions_reserveHeaderSize(msg,sizeof(rpl_hopoption_ht)); ! memcpy(msg->payload,hopbyhop_option,sizeof(rpl_hopoption_ht)); ! ! //hdr len as defined by rfc6282 sect 4.2 ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! *((uint8_t*)(msg->payload)) = sizeof(rpl_hopoption_ht); ! ! //next header ! switch (nh) { ! case IPHC_NH_INLINE: ! //add the next header inline ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! *((uint8_t*)(msg->payload)) = nextheader; ! ! //append NHC field on the extension header should be 1110 0000 -- see rfc 6282 sect 4.2 ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! *((uint8_t*)(msg->payload)) = NHC_IPv6EXT_ID; ! break; ! case IPHC_NH_COMPRESSED: ! packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t)); ! *((uint8_t*)(msg->payload)) = NHC_IPv6EXT_ID | 0x01; //mark last bit as 1 -- see rfc 6282 sect 4.2 ! break; ! default: ! openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, ! (errorparameter_t)3, ! (errorparameter_t)nh); ! } ! ! } ! ! owerror_t prependIPv6Header( OpenQueueEntry_t* msg, uint8_t tf, uint32_t value_flowLabel, *************** *** 216,222 **** (errorparameter_t)0); return E_FAIL; }; ! packetfunctions_writeAddress(msg,value_dest,BIG_ENDIAN); break; case IPHC_DAM_64B: if (value_dest->type!=ADDR_64B) { --- 282,288 ---- (errorparameter_t)0); return E_FAIL; }; ! packetfunctions_writeAddress(msg,value_dest,OW_BIG_ENDIAN); break; case IPHC_DAM_64B: if (value_dest->type!=ADDR_64B) { *************** *** 225,231 **** (errorparameter_t)1); return E_FAIL; }; ! packetfunctions_writeAddress(msg,value_dest,BIG_ENDIAN); break; case IPHC_DAM_128B: if (value_dest->type!=ADDR_128B) { --- 291,297 ---- (errorparameter_t)1); return E_FAIL; }; ! packetfunctions_writeAddress(msg,value_dest,OW_BIG_ENDIAN); break; case IPHC_DAM_128B: if (value_dest->type!=ADDR_128B) { *************** *** 234,240 **** (errorparameter_t)2); return E_FAIL; }; ! packetfunctions_writeAddress(msg,value_dest,BIG_ENDIAN); break; default: openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, --- 300,306 ---- (errorparameter_t)2); return E_FAIL; }; ! packetfunctions_writeAddress(msg,value_dest,OW_BIG_ENDIAN); break; default: openserial_printCritical(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, *************** *** 249,255 **** case IPHC_SAM_16B: if(fw_SendOrfw_Rcv==PCKTSEND) { ! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_16B)),BIG_ENDIAN); } if(fw_SendOrfw_Rcv==PCKTFORWARD) { --- 315,321 ---- case IPHC_SAM_16B: if(fw_SendOrfw_Rcv==PCKTSEND) { ! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_16B)),OW_BIG_ENDIAN); } if(fw_SendOrfw_Rcv==PCKTFORWARD) { *************** *** 259,271 **** (errorparameter_t)0); return E_FAIL; } ! packetfunctions_writeAddress(msg,value_src,BIG_ENDIAN); } break; case IPHC_SAM_64B: if(fw_SendOrfw_Rcv==PCKTSEND) { ! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_64B)),BIG_ENDIAN); } if(fw_SendOrfw_Rcv==PCKTFORWARD) { --- 325,337 ---- (errorparameter_t)0); return E_FAIL; } ! packetfunctions_writeAddress(msg,value_src,OW_BIG_ENDIAN); } break; case IPHC_SAM_64B: if(fw_SendOrfw_Rcv==PCKTSEND) { ! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_64B)),OW_BIG_ENDIAN); } if(fw_SendOrfw_Rcv==PCKTFORWARD) { *************** *** 275,288 **** (errorparameter_t)1); return E_FAIL; } ! packetfunctions_writeAddress(msg, value_src,BIG_ENDIAN); } break; case IPHC_SAM_128B: if(fw_SendOrfw_Rcv==PCKTSEND) { ! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_64B)),BIG_ENDIAN); ! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_PREFIX)),BIG_ENDIAN); } if(fw_SendOrfw_Rcv==PCKTFORWARD) { --- 341,354 ---- (errorparameter_t)1); return E_FAIL; } ! packetfunctions_writeAddress(msg, value_src,OW_BIG_ENDIAN); } break; case IPHC_SAM_128B: if(fw_SendOrfw_Rcv==PCKTSEND) { ! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_64B)),OW_BIG_ENDIAN); ! packetfunctions_writeAddress(msg, (idmanager_getMyID(ADDR_PREFIX)),OW_BIG_ENDIAN); } if(fw_SendOrfw_Rcv==PCKTFORWARD) { *************** *** 292,298 **** (errorparameter_t)2); return E_FAIL; } ! packetfunctions_writeAddress(msg,value_src,BIG_ENDIAN); } break; default: --- 358,364 ---- (errorparameter_t)2); return E_FAIL; } ! packetfunctions_writeAddress(msg,value_src,OW_BIG_ENDIAN); } break; default: *************** *** 374,379 **** --- 440,506 ---- return E_SUCCESS; } + + + void retrieveIPv6HopByHopHeader(OpenQueueEntry_t *msg,ipv6_hopbyhop_ht *hopbyhop_header, rpl_hopoption_ht *rpl_option){ + uint8_t temp_8b; + + hopbyhop_header->headerlen=0; + + hopbyhop_header->lowpan_nhc = *((uint8_t*)(msg->payload)+ hopbyhop_header->headerlen); + hopbyhop_header->headerlen += sizeof(uint8_t); + + //next header + switch ( hopbyhop_header->lowpan_nhc & NHC_HOP_NH_MASK) { + case IPHC_NH_INLINE: + // Full 8 bits for Next Header are carried in-line + hopbyhop_header->next_header_compressed = FALSE; + hopbyhop_header->nextHeader = *((uint8_t*)(msg->payload)+hopbyhop_header->headerlen); + hopbyhop_header->headerlen+= sizeof(uint8_t); + break; + case IPHC_NH_COMPRESSED: + // the Next header field is compressed and the next header is encoded + // using LOWPAN_NHC, which is discussed in Section 4.1 of RFC6282 + // we don't parse anything here, but will look at the (compressed) + // next header after having parsed all address fields. + hopbyhop_header->next_header_compressed = TRUE; + break; + default: + openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)7, + (errorparameter_t)hopbyhop_header->lowpan_nhc); + break; + } + + //len of options + hopbyhop_header->HdrExtLen =*((uint8_t*)(msg->payload)+hopbyhop_header->headerlen); + hopbyhop_header->headerlen+= sizeof(uint8_t); + //copy the options + memcpy(rpl_option,((uint8_t*)(msg->payload)+hopbyhop_header->headerlen),sizeof(rpl_hopoption_ht)); + hopbyhop_header->headerlen+= sizeof(rpl_hopoption_ht); + + //now in case nh compressed: + /* + During the parsing of the nh field, we found that the next header was + compressed. We now identify which next (compressed) header this is, and + populate the hopbyhop_header.nextHeader field accordingly. It's the role of the + appropriate transport module to decompress the header. + */ + if (hopbyhop_header->next_header_compressed==TRUE) { + temp_8b = *((uint8_t*)(msg->payload)+ hopbyhop_header->headerlen); + if ( (temp_8b & NHC_UDP_MASK) == NHC_UDP_ID) { + hopbyhop_header->nextHeader = IANA_UDP; + }else { + // the next header could be an IPv6 extension header, or misformed + hopbyhop_header->nextHeader = IANA_UNDEFINED; + openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, + (errorparameter_t)14, + (errorparameter_t)hopbyhop_header->nextHeader); + } + } + } + + ipv6_header_iht retrieveIPv6Header(OpenQueueEntry_t* msg) { uint8_t temp_8b; open_addr_t temp_addr_16b; *************** *** 446,451 **** --- 573,579 ---- ipv6_header.next_header_compressed = FALSE; ipv6_header.next_header = *((uint8_t*)(msg->payload)+ipv6_header.header_length); ipv6_header.header_length += sizeof(uint8_t); + break; case IPHC_NH_COMPRESSED: // the Next header field is compressed and the next header is encoded *************** *** 487,504 **** packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&(msg->l2_nextORpreviousHop),&ipv6_header.src); break; case IPHC_SAM_16B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_16B,&temp_addr_16b,BIG_ENDIAN); ipv6_header.header_length += 2*sizeof(uint8_t); packetfunctions_mac16bToMac64b(&temp_addr_16b,&temp_addr_64b); packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.src); break; case IPHC_SAM_64B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_64B,&temp_addr_64b,BIG_ENDIAN); ipv6_header.header_length += 8*sizeof(uint8_t); packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.src); break; case IPHC_SAM_128B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_128B,&ipv6_header.src,BIG_ENDIAN); ipv6_header.header_length += 16*sizeof(uint8_t); break; default: --- 615,632 ---- packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&(msg->l2_nextORpreviousHop),&ipv6_header.src); break; case IPHC_SAM_16B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_16B,&temp_addr_16b,OW_BIG_ENDIAN); ipv6_header.header_length += 2*sizeof(uint8_t); packetfunctions_mac16bToMac64b(&temp_addr_16b,&temp_addr_64b); packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.src); break; case IPHC_SAM_64B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_64B,&temp_addr_64b,OW_BIG_ENDIAN); ipv6_header.header_length += 8*sizeof(uint8_t); packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.src); break; case IPHC_SAM_128B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_128B,&ipv6_header.src,OW_BIG_ENDIAN); ipv6_header.header_length += 16*sizeof(uint8_t); break; default: *************** *** 513,530 **** packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),idmanager_getMyID(ADDR_64B),&(ipv6_header.dest)); break; case IPHC_DAM_16B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_16B,&temp_addr_16b,BIG_ENDIAN); ipv6_header.header_length += 2*sizeof(uint8_t); packetfunctions_mac16bToMac64b(&temp_addr_16b,&temp_addr_64b); packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.dest); break; case IPHC_DAM_64B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_64B,&temp_addr_64b,BIG_ENDIAN); ipv6_header.header_length += 8*sizeof(uint8_t); packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.dest); break; case IPHC_DAM_128B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_128B,&ipv6_header.dest,BIG_ENDIAN); ipv6_header.header_length += 16*sizeof(uint8_t); break; default: --- 641,658 ---- packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),idmanager_getMyID(ADDR_64B),&(ipv6_header.dest)); break; case IPHC_DAM_16B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_16B,&temp_addr_16b,OW_BIG_ENDIAN); ipv6_header.header_length += 2*sizeof(uint8_t); packetfunctions_mac16bToMac64b(&temp_addr_16b,&temp_addr_64b); packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.dest); break; case IPHC_DAM_64B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_64B,&temp_addr_64b,OW_BIG_ENDIAN); ipv6_header.header_length += 8*sizeof(uint8_t); packetfunctions_mac64bToIp128b(idmanager_getMyID(ADDR_PREFIX),&temp_addr_64b,&ipv6_header.dest); break; case IPHC_DAM_128B: ! packetfunctions_readAddress(((uint8_t*)(msg->payload+ipv6_header.header_length)),ADDR_128B,&ipv6_header.dest,OW_BIG_ENDIAN); ipv6_header.header_length += 16*sizeof(uint8_t); break; default: *************** *** 543,560 **** temp_8b = *((uint8_t*)(msg->payload)+ipv6_header.header_length); if ( (temp_8b & NHC_UDP_MASK) == NHC_UDP_ID) { ipv6_header.next_header = IANA_UDP; ! } else { // the next header could be an IPv6 extension header, or misformed ipv6_header.next_header = IANA_UNDEFINED; openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, ! (errorparameter_t)11, (errorparameter_t)ipv6_header.next_header); } } ! // this is a temporary workaround for allowing multicast RAs to go through ! //poipoi xv -- TODO -- check if this still needed. NO RAs anymore after RPL implementation. ! /*if (m==1 && dam==IPHC_DAM_ELIDED) { ! ipv6_header.header_length += sizeof(uint8_t); ! }*/ return ipv6_header; } --- 671,695 ---- temp_8b = *((uint8_t*)(msg->payload)+ipv6_header.header_length); if ( (temp_8b & NHC_UDP_MASK) == NHC_UDP_ID) { ipv6_header.next_header = IANA_UDP; ! }else if ( (temp_8b & NHC_IPv6EXT_MASK) == NHC_IPv6EXT_ID){ ! if( (temp_8b & NHC_IPv6HOP_MASK) == NHC_IPv6HOP_VAL){ ! //it is hop by hop header ! ipv6_header.next_header = IANA_IPv6HOPOPT; ! }else{ ! // the next header could be another IPv6 extension header ! ipv6_header.next_header = IANA_UNDEFINED; ! openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, ! (errorparameter_t)11, ! (errorparameter_t)ipv6_header.next_header); ! } ! }else { // the next header could be an IPv6 extension header, or misformed ipv6_header.next_header = IANA_UNDEFINED; openserial_printError(COMPONENT_IPHC,ERR_6LOWPAN_UNSUPPORTED, ! (errorparameter_t)12, (errorparameter_t)ipv6_header.next_header); } } ! return ipv6_header; }