Example #1
0
void forwarding_receive(OpenQueueEntry_t* msg, ipv6_header_iht ipv6_header) {
  msg->owner = COMPONENT_FORWARDING;
  msg->l4_protocol            = ipv6_header.next_header;
  msg->l4_protocol_compressed = ipv6_header.next_header_compressed;
  if ((idmanager_isMyAddress(&ipv6_header.dest) 
       || packetfunctions_isBroadcastMulticast(&ipv6_header.dest))
      && ipv6_header.next_header!=SourceFWNxtHdr) {//for me and not having src routing header
        //destination address its me.
        memcpy(&(msg->l3_destinationAdd),&ipv6_header.dest,sizeof(open_addr_t));
        memcpy(&(msg->l3_sourceAdd),&ipv6_header.src,sizeof(open_addr_t));
        switch(msg->l4_protocol) {
        case IANA_TCP:
          opentcp_receive(msg);
          break;
        case IANA_UDP:
          openudp_receive(msg);
          break;
        case IANA_ICMPv6:
          icmpv6_receive(msg);
          break;
        default:
          openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL,
                                (errorparameter_t)msg->l4_protocol,
                                (errorparameter_t)1);
        }
      } else { //relay
        memcpy(&(msg->l3_destinationAdd),&ipv6_header.dest,sizeof(open_addr_t));//because initially contains source
        memcpy(&(msg->l3_sourceAdd),&ipv6_header.src,sizeof(open_addr_t));  //>>>>>> diodio
        //TBC: source address gets changed!
        // change the creator to this components (should have been MAC)
        msg->creator = COMPONENT_FORWARDING;
        if(ipv6_header.next_header !=SourceFWNxtHdr) 
        {
          // resend as if from upper layer        //>>>>>> diodio
          if (fowarding_send_internal(msg, ipv6_header,PCKTFORWARD)==E_FAIL) {
            openqueue_freePacketBuffer(msg);
          }
        }
        else
        {
          // source route
          if (fowarding_send_internal_SourceRouting(msg, ipv6_header)==E_FAIL) {
            openqueue_freePacketBuffer(msg);
          }
        }
      }
}
Example #2
0
/**
\brief Indicates a packet was received.

\param[in,out] msg               The packet just sent.
\param[in]     ipv6_header       The information contained in the IPv6 header.
\param[in]     ipv6_hop_header   The hop-by-hop header present in the packet.
\param[in]     rpl_option        The hop-by-hop options present in the packet.
*/
void forwarding_receive(
      OpenQueueEntry_t*      msg,
      ipv6_header_iht*       ipv6_header,
      ipv6_hopbyhop_iht*     ipv6_hop_header,
      rpl_option_ht*         rpl_option
   ) {
   uint8_t flags;
   uint16_t senderRank;
   
   // take ownership
   msg->owner                     = COMPONENT_FORWARDING;
   
   // determine L4 protocol
   if (ipv6_header->next_header==IANA_IPv6HOPOPT){
      // get information from ipv6_hop_header
      
      msg->l4_protocol            = ipv6_hop_header->nextHeader;
      msg->l4_protocol_compressed = ipv6_hop_header->next_header_compressed;
   } else {
      // get information from ipv6_header
      
      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)
            ||
            packetfunctions_isBroadcastMulticast(&ipv6_header->dest)
         )
         &&
         ipv6_header->next_header!=IANA_IPv6ROUTE
      ) {
      // this packet is for me, no source routing header.

      // indicate received packet to upper layer
      switch(msg->l4_protocol) {
         case IANA_TCP:
            opentcp_receive(msg);
            break;
         case IANA_UDP:
            openudp_receive(msg);
            break;
         case IANA_ICMPv6:
            icmpv6_receive(msg);
            break;
         default:
            
            // log error
            openserial_printError(
               COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL,
               (errorparameter_t)msg->l4_protocol,
               (errorparameter_t)1
            );
            
            // free packet
            openqueue_freePacketBuffer(msg);
      }
   } 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
         //check if flow label rpl header
    	 #ifdef FLOW_LABEL_RPL_DOMAIN             
             flags = (uint8_t)((uint32_t)((ipv6_header->flow_label)>>16)&0xFF);
             senderRank = (uint16_t)((uint32_t)(ipv6_header->flow_label)>>8)&0xFFFF;
             senderRank = senderRank*MINHOPRANKINCREASE;//shift it according to HopRank Increase
         #else
    	     flags = rpl_option->flags;
    	     senderRank = rpl_option->senderRank;
    	 #endif

         if ((flags & O_FLAG)!=0){
            // wrong direction
            
            // log error
            openserial_printError(
               COMPONENT_FORWARDING,
               ERR_WRONG_DIRECTION,
               (errorparameter_t)flags,
               (errorparameter_t)senderRank
            );
         }
         

         if (senderRank < neighbors_getMyDAGrank()){
            // loop
            
            // set flag
            #ifdef FLOW_LABEL_RPL_DOMAIN
        	    flags |= R_FLAG;
        	    ipv6_header->flow_label|= ((uint32_t)flags<<16);
            #else
        	    rpl_option->flags |= R_FLAG;
            #endif

            // log error
            openserial_printError(
               COMPONENT_FORWARDING,
               ERR_LOOP_DETECTED,
               (errorparameter_t) senderRank,
               (errorparameter_t) neighbors_getMyDAGrank()
            );
         }
         

         forwarding_createRplOption(rpl_option, rpl_option->flags);
         #ifdef FLOW_LABEL_RPL_DOMAIN
         // do not recreate flow label, relay the same but adding current flags
         //forwarding_createFlowLabel(&(ipv6_header->flow_label),flags);
         #endif
         // resend as if from upper layer
         if (
               forwarding_send_internal_RoutingTable(
                  msg,
                  ipv6_header,
                  rpl_option,
                  &(ipv6_header->flow_label),
                  PCKTFORWARD 
               )==E_FAIL
            ) {
            openqueue_freePacketBuffer(msg);
         }
      } else {
         // source routing header present
         
         if (forwarding_send_internal_SourceRouting(msg, ipv6_header)==E_FAIL) {
Example #3
0
error_t fowarding_send_internal_SourceRouting(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header) {
  // It has to be forwarded to dest. so, next hop should be extracted from the message.
  uint8_t local_CmprE;
  uint8_t local_CmprI,numAddr,hlen;
  uint8_t addressposition;
  uint8_t* runningPointer;
  uint8_t octetsAddressSize;
  ipv6_Source_Routing_Header_t * ipv6_Source_Routing_Header;
  
  open_addr_t* prefix=idmanager_getMyID(ADDR_PREFIX);
 
  ipv6_Source_Routing_Header=(ipv6_Source_Routing_Header_t*)(msg->payload);
  
  
  runningPointer=(msg->payload) + sizeof(ipv6_Source_Routing_Header_t);
  
  // getting local_CmprE and CmprI;
  local_CmprE=ipv6_Source_Routing_Header->CmprICmprE & 0xf;
  local_CmprI= ipv6_Source_Routing_Header->CmprICmprE & 0xf0;
  //local_CmprI>>4; // shifting it by 4.
  local_CmprI=local_CmprI>>4; // shifting it by 4.
  
//  foundFlag=0;

    //see processing header algorithm in RFC6554 page 9
    
    numAddr=(((ipv6_Source_Routing_Header->HdrExtLen*8)-ipv6_Source_Routing_Header->PadRes -(16-local_CmprE))/(16-local_CmprI))+1;
  
  if(ipv6_Source_Routing_Header->SegmentsLeft==0){
    //we are there!..
    //process the next header in the pkt.. i.e push stack up..
    msg->l4_protocol=ipv6_Source_Routing_Header->nextHeader;
    hlen=ipv6_Source_Routing_Header->HdrExtLen;
        
    //toss header
    packetfunctions_tossHeader(msg,sizeof(ipv6_Source_Routing_Header_t));
    
    //toss list of addresses.
    if(local_CmprE==0)
    {
      octetsAddressSize=2;
      //remove 
      packetfunctions_tossHeader(msg,octetsAddressSize*hlen);   
    }
    else if(local_CmprE==8)
    {
      octetsAddressSize=8;
      packetfunctions_tossHeader(msg,octetsAddressSize*hlen);
    }
    else if(local_CmprE==2)
    {
      octetsAddressSize=16;
      packetfunctions_tossHeader(msg,octetsAddressSize*hlen);
    }
    else
    {
      msg->l2_nextORpreviousHop.type = ADDR_NONE;
      //error!
      while(1);
    }
    
    switch(msg->l4_protocol) {
    case IANA_TCP:
      opentcp_receive(msg);
      break;
    case IANA_UDP:
      openudp_receive(msg);
      break;
    case IANA_ICMPv6:
      icmpv6_receive(msg);
      break;
    default:
      openserial_printError(COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL,
                            (errorparameter_t)msg->l4_protocol,
                            (errorparameter_t)1);
    }
    
    return E_SUCCESS;
  }else{    
    if(ipv6_Source_Routing_Header->SegmentsLeft>numAddr){
      //not good.. error.
      //send and ICMPv6 parameter problem, code 0, to the src address 
      //then discard the packet.
      //TODO
      while (1);
    }else{
      //still hops remaining 
      ipv6_Source_Routing_Header->SegmentsLeft--;
      //find the address in the vector.
      addressposition=numAddr-(ipv6_Source_Routing_Header->SegmentsLeft);
      
      if(local_CmprE==0)
      {
        msg->l2_nextORpreviousHop.type = ADDR_16B;
        msg->l3_destinationAdd.type = ADDR_16B;
        octetsAddressSize=2;
        memcpy(&(msg->l2_nextORpreviousHop.addr_16b),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
        memcpy(&(msg->l3_destinationAdd.addr_16b),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
      }
      else if(local_CmprE==8)
      {
        msg->l2_nextORpreviousHop.type = ADDR_64B;
        msg->l3_destinationAdd.type = ADDR_128B;
        octetsAddressSize=8;
        memcpy(&(msg->l2_nextORpreviousHop.addr_64b),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
     
        memcpy(&(msg->l3_destinationAdd.addr_128b[0]),prefix->prefix,8);
        memcpy(&(msg->l3_destinationAdd.addr_128b[8]),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
      }
      else if(local_CmprE==2)
      {
        msg->l2_nextORpreviousHop.type = ADDR_128B;
        msg->l3_destinationAdd.type = ADDR_128B;
        
        octetsAddressSize=16;
        memcpy(&(msg->l2_nextORpreviousHop.addr_128b),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
        memcpy(&(msg->l3_destinationAdd.addr_128b),runningPointer+((addressposition-1)*octetsAddressSize),octetsAddressSize);
      }
      else
      {
        msg->l2_nextORpreviousHop.type = ADDR_NONE;
        //error!
        while(1);
      }
    }
  }
  
  if (msg->l2_nextORpreviousHop.type==ADDR_NONE) {
    openserial_printError(COMPONENT_FORWARDING,ERR_NO_NEXTHOP,
                          (errorparameter_t)0,
                          (errorparameter_t)0);
    return E_FAIL;
  }
  return iphc_sendFromForwarding(msg, ipv6_header,PCKTFORWARD);
}
Example #4
0
/**
\brief Indicates a packet was received.

\param[in,out] msg               The packet just sent.
\param[in]     ipv6_header       The information contained in the IPv6 header.
\param[in]     ipv6_hop_header   The hop-by-hop header present in the packet.
\param[in]     rpl_option        The hop-by-hop options present in the packet.
*/
void forwarding_receive(OpenMote* self, 
      OpenQueueEntry_t*      msg,
      ipv6_header_iht*       ipv6_outer_header,
      ipv6_header_iht*       ipv6_inner_header,
      rpl_option_ht*         rpl_option
    ) {
    uint8_t flags;
    uint16_t senderRank;
   
    // take ownership
    msg->owner                     = COMPONENT_FORWARDING;
   
    // determine L4 protocol
    // get information from ipv6_header
    msg->l4_protocol            = ipv6_inner_header->next_header;
    msg->l4_protocol_compressed = ipv6_inner_header->next_header_compressed;
   
    // populate packets metadata with L3 information
    memcpy(&(msg->l3_destinationAdd),&ipv6_inner_header->dest, sizeof(open_addr_t));
    memcpy(&(msg->l3_sourceAdd),     &ipv6_inner_header->src,  sizeof(open_addr_t));
   
    if (
        (
 idmanager_isMyAddress(self, &(msg->l3_destinationAdd))
            ||
 packetfunctions_isBroadcastMulticast(self, &(msg->l3_destinationAdd))
        )
        &&
        ipv6_outer_header->next_header!=IANA_IPv6ROUTE
    ) {
        if (ipv6_outer_header->src.type != ADDR_NONE){
 packetfunctions_tossHeader(self, msg,ipv6_outer_header->header_length);
        }
        // this packet is for me, no source routing header // toss iphc inner header
 packetfunctions_tossHeader(self, msg,ipv6_inner_header->header_length);
        // indicate received packet to upper layer
        switch(msg->l4_protocol) {
        case IANA_TCP:
 opentcp_receive(self, msg);
            break;
        case IANA_UDP:
 openudp_receive(self, msg);
            break;
        case IANA_ICMPv6:
 icmpv6_receive(self, msg);
            break;
        default:
            // log error
 openserial_printError(self, 
                COMPONENT_FORWARDING,ERR_WRONG_TRAN_PROTOCOL,
                (errorparameter_t)msg->l4_protocol,
                (errorparameter_t)1
            );
            
            // free packet
 openqueue_freePacketBuffer(self, msg);
        }
    } else {
        // this packet is not for me: relay
      
        // change the creator of the packet
        msg->creator = COMPONENT_FORWARDING;
      
        if (ipv6_outer_header->next_header!=IANA_IPv6ROUTE) {
            flags = rpl_option->flags;
            senderRank = rpl_option->senderRank;
            if ((flags & O_FLAG)!=0){
                // wrong direction
                // log error
 openserial_printError(self, 
                    COMPONENT_FORWARDING,
                    ERR_WRONG_DIRECTION,
                    (errorparameter_t)flags,
                    (errorparameter_t)senderRank
                );
            }
            if (senderRank < neighbors_getMyDAGrank(self)){
                // loop detected
                // set flag
                rpl_option->flags |= R_FLAG;
                // log error
 openserial_printError(self, 
                    COMPONENT_FORWARDING,
                    ERR_LOOP_DETECTED,
                    (errorparameter_t) senderRank,
                    (errorparameter_t) neighbors_getMyDAGrank(self)
                );
            }
 forwarding_createRplOption(self, rpl_option, rpl_option->flags);
            // resend as if from upper layer
            if (
 forwarding_send_internal_RoutingTable(self, 
                    msg,
                    ipv6_outer_header,
                    ipv6_inner_header,
                    rpl_option,
                    &(ipv6_outer_header->flow_label),
                    PCKTFORWARD 
                )==E_FAIL
            ) {
 openqueue_freePacketBuffer(self, msg);
            }
        } else {
            // source routing header present
            if (
 forwarding_send_internal_SourceRouting(self, 
                    msg,
                    ipv6_outer_header,
                    ipv6_inner_header,
                    rpl_option
                )==E_FAIL
            ) {
                // log error
 openserial_printError(self, 
                    COMPONENT_FORWARDING,
                    ERR_INVALID_FWDMODE,
                    (errorparameter_t)0,
                    (errorparameter_t)0
                );
            }
        }
    }
}