*** stock_iot-lab_M3/openwsn/03b-IPv6/forwarding.c Thu Apr 24 11:01:36 2014 --- riot-openwsn-wip/openwsn/03b-IPv6/forwarding.c Thu Apr 24 16:55:54 2014 *************** *** 7,31 **** #include "packetfunctions.h" #include "neighbors.h" #include "icmpv6.h" #include "openudp.h" #include "opentcp.h" //=========================== variables ======================================= //=========================== prototypes ====================================== ! error_t fowarding_send_internal_RoutingTable(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, uint8_t fw_SendOrfw_Rcv); void forwarding_getNextHop_RoutingTable(open_addr_t* destination, open_addr_t* addressToWrite); ! error_t fowarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header); //=========================== public ========================================== /** \brief Initialize this module. */ ! void forwarding_init() { } /** \brief Send a packet originating at this mote. --- 7,36 ---- #include "packetfunctions.h" #include "neighbors.h" #include "icmpv6.h" + #include "icmpv6rpl.h" #include "openudp.h" #include "opentcp.h" + //#include "debugpins.h" + #include "scheduler.h" //=========================== variables ======================================= //=========================== prototypes ====================================== ! owerror_t forwarding_send_internal_RoutingTable(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, rpl_hopoption_ht hopbyhop_header, uint8_t fw_SendOrfw_Rcv); void forwarding_getNextHop_RoutingTable(open_addr_t* destination, open_addr_t* addressToWrite); ! owerror_t forwarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header); ! void forwarding_createHopByHopOption(rpl_hopoption_ht *hopbyhop_opt, uint8_t flags); //=========================== public ========================================== /** \brief Initialize this module. */ ! void forwarding_init(void) { } + /** \brief Send a packet originating at this mote. *************** *** 34,41 **** \param[in,out] msg Packet to send. */ ! error_t forwarding_send(OpenQueueEntry_t* msg) { ipv6_header_iht ipv6_header; open_addr_t* myprefix; open_addr_t* myadd64; --- 39,48 ---- \param[in,out] msg Packet to send. */ ! owerror_t forwarding_send(OpenQueueEntry_t* msg) { ipv6_header_iht ipv6_header; + rpl_hopoption_ht hopbyhop_opt; + open_addr_t* myprefix; open_addr_t* myadd64; *************** *** 58,65 **** //this is done here as send_internal is used by forwarding of packets as well which //carry a hlim. This value is required to be set to a value as the following function can decrement it ipv6_header.hop_limit = IPHC_DEFAULT_HOP_LIMIT; ! return fowarding_send_internal_RoutingTable(msg,ipv6_header,PCKTSEND); } /** --- 65,74 ---- //this is done here as send_internal is used by forwarding of packets as well which //carry a hlim. This value is required to be set to a value as the following function can decrement it ipv6_header.hop_limit = IPHC_DEFAULT_HOP_LIMIT; + //create hop by hop option + forwarding_createHopByHopOption(&hopbyhop_opt, 0x00); //flags are 0x00 -- TODO check and define macro ! return forwarding_send_internal_RoutingTable(msg,ipv6_header,hopbyhop_opt,PCKTSEND); } /** *************** *** 68,74 **** \param[in,out] msg The packet just sent. \param[in] error The outcome of sending it. */ ! void forwarding_sendDone(OpenQueueEntry_t* msg, error_t error) { // take ownership msg->owner = COMPONENT_FORWARDING; --- 77,83 ---- \param[in,out] msg The packet just sent. \param[in] error The outcome of sending it. */ ! void forwarding_sendDone(OpenQueueEntry_t* msg, owerror_t error) { // take ownership msg->owner = COMPONENT_FORWARDING; *************** *** 108,126 **** \param[in,out] msg The packet just sent. \param[in] ipv6_header The information contained in the 6LoWPAN header. */ ! void forwarding_receive(OpenQueueEntry_t* msg, ipv6_header_iht ipv6_header) { // take ownership msg->owner = COMPONENT_FORWARDING; - // populate packets metadata with l4 information - msg->l4_protocol = ipv6_header.next_header; - msg->l4_protocol_compressed = ipv6_header.next_header_compressed; ! // populate packets metadata with l3 information memcpy(&(msg->l3_destinationAdd),&ipv6_header.dest,sizeof(open_addr_t)); memcpy(&(msg->l3_sourceAdd), &ipv6_header.src, sizeof(open_addr_t)); if ( ( idmanager_isMyAddress(&ipv6_header.dest) --- 117,152 ---- \param[in,out] msg The packet just sent. \param[in] ipv6_header The information contained in the 6LoWPAN header. */ ! void forwarding_receive(OpenQueueEntry_t* msg, ! ipv6_header_iht ipv6_header, ! ipv6_hopbyhop_ht ipv6_hop_header, ! rpl_hopoption_ht hop_by_hop_option) { ! ! uint8_t temp_flags; // take ownership msg->owner = COMPONENT_FORWARDING; ! //contains a ! if (ipv6_header.next_header==IANA_IPv6HOPOPT){ ! // populate packets metadata with l4 information ! msg->l4_protocol = ipv6_hop_header.nextHeader; ! msg->l4_protocol_compressed = ipv6_hop_header.next_header_compressed; // rfc 6282 ! ! //process HOP BY HOP header ! ! ! }else{ ! msg->l4_protocol = ipv6_header.next_header; ! msg->l4_protocol_compressed = ipv6_header.next_header_compressed; // rfc 6282 ! } ! ! // populate packets metadata with l3 information memcpy(&(msg->l3_destinationAdd),&ipv6_header.dest,sizeof(open_addr_t)); memcpy(&(msg->l3_sourceAdd), &ipv6_header.src, sizeof(open_addr_t)); + if ( ( idmanager_isMyAddress(&ipv6_header.dest) *************** *** 128,136 **** packetfunctions_isBroadcastMulticast(&ipv6_header.dest) ) && ipv6_header.next_header!=IANA_IPv6ROUTE ) { ! // this packet is for me, but no routing header. // indicate received packet to upper layer switch(msg->l4_protocol) { --- 154,163 ---- packetfunctions_isBroadcastMulticast(&ipv6_header.dest) ) && + //ipv6 header - next header will be IANA_IPv6HOPOPT or IANA_IPv6ROUTE ipv6_header.next_header!=IANA_IPv6ROUTE ) { ! // this packet is for me, but no src routing header. // indicate received packet to upper layer switch(msg->l4_protocol) { *************** *** 151,178 **** } } else { // this packet is not for me: relay ! // change the creator of the packet msg->creator = COMPONENT_FORWARDING; if (ipv6_header.next_header!=IANA_IPv6ROUTE) { // no source routing header present ! // resend as if from upper layer ! if (fowarding_send_internal_RoutingTable(msg, ipv6_header,PCKTFORWARD)==E_FAIL) { openqueue_freePacketBuffer(msg); } } else { ! // source routing header present ! ! if (fowarding_send_internal_SourceRouting(msg, ipv6_header)==E_FAIL) { ! openqueue_freePacketBuffer(msg); } } } } ! //=========================== private ========================================= /** \brief Send a packet using the routing table to find the next hop. --- 178,230 ---- } } else { // this packet is not for me: relay ! // change the creator of the packet msg->creator = COMPONENT_FORWARDING; if (ipv6_header.next_header!=IANA_IPv6ROUTE) { // no source routing header present ! ! //process HOP bY HOP header ! temp_flags = hop_by_hop_option.flags; ! if ((temp_flags & O_FLAG)!=0){ ! //error wrong direction ! //what todo? print the error ! openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_DIRECTION, ! (errorparameter_t)1, ! (errorparameter_t)1); ! } ! if (hop_by_hop_option.senderRank < neighbors_getMyDAGrank()){ ! //wrong rank relation.. loop detected ! temp_flags |= R_FLAG; //set r flag. ! openserial_printError(COMPONENT_FORWARDING,ERR_LOOP_DETECTED, ! (errorparameter_t) hop_by_hop_option.senderRank, ! (errorparameter_t) neighbors_getMyDAGrank()); ! } ! ! //O flag should always be 0 as this is upstream route. ! ! forwarding_createHopByHopOption(&hop_by_hop_option, temp_flags); ! ! // resend as if from upper layer ! if (forwarding_send_internal_RoutingTable(msg, ipv6_header,hop_by_hop_option,PCKTFORWARD)==E_FAIL) { openqueue_freePacketBuffer(msg); } } else { ! // source routing header present ! if (forwarding_send_internal_SourceRouting(msg, ipv6_header)==E_FAIL) { ! //already freed by send_internal if it fails ! //todo change error type to another that says src_route failure. ! openserial_printError(COMPONENT_FORWARDING,ERR_INVALID_FWDMODE, ! (errorparameter_t)0, ! (errorparameter_t)0); } } } } ! /** \brief Send a packet using the routing table to find the next hop. *************** *** 182,188 **** \param[in] fw_SendOrfw_Rcv The packet is originating from this mote (PCKTSEND), or forwarded (PCKTFORWARD). */ ! error_t fowarding_send_internal_RoutingTable(OpenQueueEntry_t* msg, ipv6_header_iht ipv6_header, uint8_t fw_SendOrfw_Rcv) { // retrieve the next hop from the routing table forwarding_getNextHop_RoutingTable(&(msg->l3_destinationAdd),&(msg->l2_nextORpreviousHop)); --- 234,240 ---- \param[in] fw_SendOrfw_Rcv The packet is originating from this mote (PCKTSEND), or forwarded (PCKTFORWARD). */ ! owerror_t forwarding_send_internal_RoutingTable(OpenQueueEntry_t* msg, ipv6_header_iht ipv6_header, rpl_hopoption_ht hopbyhop_opt, uint8_t fw_SendOrfw_Rcv) { // retrieve the next hop from the routing table forwarding_getNextHop_RoutingTable(&(msg->l3_destinationAdd),&(msg->l2_nextORpreviousHop)); *************** *** 194,200 **** } // send to next lower layer ! return iphc_sendFromForwarding(msg, ipv6_header, fw_SendOrfw_Rcv); } /** --- 246,252 ---- } // send to next lower layer ! return iphc_sendFromForwarding(msg, ipv6_header, &hopbyhop_opt,fw_SendOrfw_Rcv); } /** *************** *** 208,214 **** \param[in,out] msg The packet to send. \param[in] ipv6_header The packet's IPv6 header. */ ! error_t fowarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header) { uint8_t local_CmprE; uint8_t local_CmprI; uint8_t numAddr; --- 260,266 ---- \param[in,out] msg The packet to send. \param[in] ipv6_header The packet's IPv6 header. */ ! owerror_t forwarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header) { uint8_t local_CmprE; uint8_t local_CmprI; uint8_t numAddr; *************** *** 218,223 **** --- 270,279 ---- uint8_t octetsAddressSize; open_addr_t* prefix; rpl_routing_ht* rpl_routing_hdr; + + rpl_hopoption_ht hopbyhop_opt; + + memset(&hopbyhop_opt,0,sizeof(rpl_hopoption_ht));//reset everything // get my prefix prefix = idmanager_getMyID(ADDR_PREFIX); *************** *** 270,275 **** --- 326,332 ---- openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL, (errorparameter_t)msg->l4_protocol, (errorparameter_t)1); + //not sure that this is correct as iphc will free it? openqueue_freePacketBuffer(msg); return E_FAIL; } *************** *** 297,304 **** rpl_routing_hdr->SegmentsLeft--; // find next hop address in source route ! addressposition = numAddr-(rpl_routing_hdr->SegmentsLeft); ! // how many octets have the address? if (rpl_routing_hdr->SegmentsLeft > 1){ octetsAddressSize = LENGTH_ADDR128b - local_CmprI; //max addr length - number of prefix octets that are elided in the internal route elements --- 354,361 ---- rpl_routing_hdr->SegmentsLeft--; // find next hop address in source route ! //addressposition = numAddr-(rpl_routing_hdr->SegmentsLeft); ! addressposition = rpl_routing_hdr->SegmentsLeft; // how many octets have the address? if (rpl_routing_hdr->SegmentsLeft > 1){ octetsAddressSize = LENGTH_ADDR128b - local_CmprI; //max addr length - number of prefix octets that are elided in the internal route elements *************** *** 311,324 **** msg->l2_nextORpreviousHop.type = ADDR_16B; memcpy( &(msg->l2_nextORpreviousHop.addr_16b), ! runningPointer+((addressposition-1)*octetsAddressSize), octetsAddressSize ); // write next hop msg->l3_destinationAdd.type = ADDR_16B; memcpy( &(msg->l3_destinationAdd.addr_16b), ! runningPointer+((addressposition-1)*octetsAddressSize), octetsAddressSize ); break; --- 368,381 ---- msg->l2_nextORpreviousHop.type = ADDR_16B; memcpy( &(msg->l2_nextORpreviousHop.addr_16b), ! runningPointer+((addressposition)*octetsAddressSize), octetsAddressSize ); // write next hop msg->l3_destinationAdd.type = ADDR_16B; memcpy( &(msg->l3_destinationAdd.addr_16b), ! runningPointer+((addressposition)*octetsAddressSize), octetsAddressSize ); break; *************** *** 327,333 **** msg->l2_nextORpreviousHop.type = ADDR_64B; memcpy( &(msg->l2_nextORpreviousHop.addr_64b), ! runningPointer+((addressposition-1)*octetsAddressSize), octetsAddressSize ); --- 384,390 ---- msg->l2_nextORpreviousHop.type = ADDR_64B; memcpy( &(msg->l2_nextORpreviousHop.addr_64b), ! runningPointer+((addressposition)*octetsAddressSize), octetsAddressSize ); *************** *** 344,350 **** memcpy( &(msg->l3_destinationAdd.addr_128b[8]), ! runningPointer+((addressposition-1)*octetsAddressSize), octetsAddressSize ); --- 401,407 ---- memcpy( &(msg->l3_destinationAdd.addr_128b[8]), ! runningPointer+((addressposition)*octetsAddressSize), octetsAddressSize ); *************** *** 354,367 **** msg->l2_nextORpreviousHop.type = ADDR_128B; memcpy( &(msg->l2_nextORpreviousHop.addr_128b), ! runningPointer+((addressposition-1)*octetsAddressSize), octetsAddressSize ); // write next hop msg->l3_destinationAdd.type = ADDR_128B; memcpy( &(msg->l3_destinationAdd.addr_128b), ! runningPointer+((addressposition-1)*octetsAddressSize), octetsAddressSize ); break; --- 411,424 ---- msg->l2_nextORpreviousHop.type = ADDR_128B; memcpy( &(msg->l2_nextORpreviousHop.addr_128b), ! runningPointer+((addressposition)*octetsAddressSize), octetsAddressSize ); // write next hop msg->l3_destinationAdd.type = ADDR_128B; memcpy( &(msg->l3_destinationAdd.addr_128b), ! runningPointer+((addressposition)*octetsAddressSize), octetsAddressSize ); break; *************** *** 378,391 **** } // send to next lower layer ! return iphc_sendFromForwarding(msg, ipv6_header, PCKTFORWARD); } /** \brief Retrieve the next hop's address from routing table. \param[in] destination128b Final IPv6 destination address. ! \param[out]addressToWrite64b Location to write the EUI64 of next hop to. */ void forwarding_getNextHop_RoutingTable(open_addr_t* destination128b, open_addr_t* addressToWrite64b) { uint8_t i; --- 435,448 ---- } // send to next lower layer ! return iphc_sendFromForwarding(msg, ipv6_header,&hopbyhop_opt, PCKTFORWARD); } /** \brief Retrieve the next hop's address from routing table. \param[in] destination128b Final IPv6 destination address. ! \param[out] addressToWrite64b Location to write the EUI64 of next hop to. */ void forwarding_getNextHop_RoutingTable(open_addr_t* destination128b, open_addr_t* addressToWrite64b) { uint8_t i; *************** *** 403,406 **** // destination is remote, send to preferred parent neighbors_getPreferredParentEui64(addressToWrite64b); } ! } \ No newline at end of file --- 460,478 ---- // destination is remote, send to preferred parent neighbors_getPreferredParentEui64(addressToWrite64b); } ! } ! /* ! * HOP BY HOP HEADER OPTION ! */ ! ! ! void forwarding_createHopByHopOption(rpl_hopoption_ht *hopbyhop_opt, uint8_t flags) { ! //set the rpl hop by hop header ! hopbyhop_opt->optionType = RPL_HOPBYHOP_HEADER_OPTION_TYPE; ! //8-bit field indicating the length of the option, in ! //octets, excluding the Option Type and Opt Data Len fields. ! hopbyhop_opt->optionLen = 0x04; //4-bytes, flags+instanceID+senderrank - no sub-tlvs ! hopbyhop_opt->flags = flags; ! hopbyhop_opt->rplInstanceID = icmpv6rpl_getRPLIntanceID(); //getit.. ! hopbyhop_opt->senderRank = neighbors_getMyDAGrank(); //TODO change to DAGRAnk(rank) instead of rank ! }