Esempio n. 1
0
error_t fowarding_send_internal(OpenQueueEntry_t *msg, ipv6_header_iht ipv6_header, uint8_t fw_SendOrfw_Rcv) {
  getNextHop(&(msg->l3_destinationAdd),&(msg->l2_nextORpreviousHop));
 // getNextHop(&(msg->l3_sourceAdd),&(msg->l2_nextORpreviousHop));
  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,fw_SendOrfw_Rcv);
}
Esempio n. 2
0
/**
\brief Send a packet using the routing table to find the next hop.

\param[in,out] msg             The packet to send.
\param[in]     ipv6_header     The packet's IPv6 header.
\param[in]     rpl_option      The hop-by-hop option to add in this packet.
\param[in]     flow_label      The flowlabel to add in the 6LoWPAN header.
\param[in]     fw_SendOrfw_Rcv The packet is originating from this mote
   (PCKTSEND), or forwarded (PCKTFORWARD).
*/
owerror_t forwarding_send_internal_RoutingTable(OpenMote* self, 
      OpenQueueEntry_t*      msg,
      ipv6_header_iht*       ipv6_outer_header,
      ipv6_header_iht*       ipv6_inner_header,
      rpl_option_ht*         rpl_option,
      uint32_t*              flow_label,
      uint8_t                fw_SendOrfw_Rcv
   ) {
   
   // retrieve the next hop from the routing table
 forwarding_getNextHop(self, &(msg->l3_destinationAdd),&(msg->l2_nextORpreviousHop));
   if (msg->l2_nextORpreviousHop.type==ADDR_NONE) {
 openserial_printError(self, 
         COMPONENT_FORWARDING,
         ERR_NO_NEXTHOP,
         (errorparameter_t)0,
         (errorparameter_t)0
      );
      return E_FAIL;
   }
   
   if (ipv6_outer_header->src.type != ADDR_NONE){
 packetfunctions_tossHeader(self, msg,ipv6_outer_header->header_length);
   }
   
   // send to next lower layer
   return iphc_sendFromForwarding(self, 
      msg,
      ipv6_outer_header,
      ipv6_inner_header,
      rpl_option,
      flow_label,
      NULL,  // no rh3
      0,
      fw_SendOrfw_Rcv
   );
}
Esempio n. 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);
}
Esempio n. 4
0
/**
\brief Send a packet using the source rout to find the next hop.

\note This is always called for packets being forwarded.

How to process the routing header is detailed in
http://tools.ietf.org/html/rfc6554#page-9.

\param[in,out] msg             The packet to send.
\param[in]     ipv6_header     The packet's IPv6 header.
*/
owerror_t forwarding_send_internal_SourceRouting(OpenMote* self, 
    OpenQueueEntry_t* msg,
    ipv6_header_iht*  ipv6_outer_header,
    ipv6_header_iht*  ipv6_inner_header,
    rpl_option_ht*    rpl_option
    ) {
    uint8_t              temp_8b;
    uint8_t              type;
    uint8_t              next_type;
    uint8_t              size;
    uint8_t              next_size;
    uint8_t              hlen;
    open_addr_t          firstAddr;
    open_addr_t          nextAddr;
    open_addr_t          temp_prefix;
    open_addr_t          temp_addr64;
    
    uint8_t              rpi_length;
    uint8_t              flags;
    uint16_t             senderRank;
    
    uint8_t              RH3_copy[127];
    uint8_t              RH3_length;
    
    memset(&RH3_copy[0],0,127);
    RH3_length = 0;
    memcpy(&msg->l3_destinationAdd,&ipv6_inner_header->dest,sizeof(open_addr_t));
    memcpy(&msg->l3_sourceAdd,&ipv6_inner_header->src,sizeof(open_addr_t));
    
    // initial first Address by compression reference
    firstAddr.type = ADDR_128B;
    if (ipv6_outer_header->src.type != ADDR_NONE){
        if (rpl_option->rplInstanceID == 0){
 icmpv6rpl_getRPLDODAGid(self, &firstAddr.addr_128b[0]);
        }
    } else {
        memcpy(&firstAddr,&ipv6_inner_header->src,sizeof(open_addr_t));
    }
    
    hlen = 0;
    
    temp_8b = *((uint8_t*)(msg->payload)+hlen);
    type    = *((uint8_t*)(msg->payload)+hlen+1);
    
    hlen += 2;
    // get the first address
    switch(type){
    case RH3_6LOTH_TYPE_0:
        memcpy(&firstAddr.addr_128b[15],msg->payload+hlen,1);
        hlen += 1;
        break;
    case RH3_6LOTH_TYPE_1:
        memcpy(&firstAddr.addr_128b[14],msg->payload+hlen,2);
        hlen += 2;
        break;
    case RH3_6LOTH_TYPE_2:
        memcpy(&firstAddr.addr_128b[12],msg->payload+hlen,4);
        hlen += 4;
        break;
    case RH3_6LOTH_TYPE_3:
        memcpy(&firstAddr.addr_128b[8],msg->payload+hlen,8);
        hlen += 8;
        break;
    case RH3_6LOTH_TYPE_4:
        memcpy(&firstAddr.addr_128b[0],msg->payload+hlen,16);
        hlen += 16;
        break;
    }
    
 packetfunctions_ip128bToMac64b(self, &firstAddr,&temp_prefix,&temp_addr64);
    if (
 packetfunctions_sameAddress(self, &temp_prefix, idmanager_getMyID(self, ADDR_PREFIX)) &&
 packetfunctions_sameAddress(self, &temp_addr64, idmanager_getMyID(self, ADDR_64B))
    ){
        size = temp_8b & RH3_6LOTH_SIZE_MASK;
        if (size > 0){
            // there are at least 2 entries in the header, 
            // the router removes the first entry and decrements the Size (by 1) 
            size -= 1;
 packetfunctions_tossHeader(self, msg,hlen);
 packetfunctions_reserveHeaderSize(self, msg,2);
            msg->payload[0] = CRITICAL_6LORH | size;
            msg->payload[1] = type;
            // get next hop
            memcpy(&nextAddr,&firstAddr,sizeof(open_addr_t));
            switch(type){
            case RH3_6LOTH_TYPE_0:
                memcpy(&nextAddr.addr_128b[15],msg->payload+2,1);
                break;
            case RH3_6LOTH_TYPE_1:
                memcpy(&nextAddr.addr_128b[14],msg->payload+2,2);
                break;
            case RH3_6LOTH_TYPE_2:
                memcpy(&nextAddr.addr_128b[12],msg->payload+2,4);
                break;
            case RH3_6LOTH_TYPE_3:
                memcpy(&nextAddr.addr_128b[8],msg->payload+2,8);
                break;
            case RH3_6LOTH_TYPE_4:
                memcpy(&nextAddr.addr_128b[0],msg->payload+2,16);
                break;
            }
 packetfunctions_ip128bToMac64b(self, 
                &nextAddr,
                &temp_prefix,
                &msg->l2_nextORpreviousHop
            );
        } else {
            temp_8b   = *((uint8_t*)(msg->payload)+hlen);
            next_type = *((uint8_t*)(msg->payload)+hlen+1);
            if (
                (temp_8b & FORMAT_6LORH_MASK) == CRITICAL_6LORH &&
                next_type<=RH3_6LOTH_TYPE_4
            ) {
                // there is another RH3-6LoRH following, check the type
                if (next_type >= type){
 packetfunctions_tossHeader(self, msg,hlen);
                    // get next hop
                    memcpy(&nextAddr,&firstAddr,sizeof(open_addr_t));
                    switch(next_type){
                    case RH3_6LOTH_TYPE_0:
                        memcpy(&nextAddr.addr_128b[15],msg->payload+2,1);
                        break;
                    case RH3_6LOTH_TYPE_1:
                        memcpy(&nextAddr.addr_128b[14],msg->payload+2,2);
                        break;
                    case RH3_6LOTH_TYPE_2:
                        memcpy(&nextAddr.addr_128b[12],msg->payload+2,4);
                        break;
                    case RH3_6LOTH_TYPE_3:
                        memcpy(&nextAddr.addr_128b[8],msg->payload+2,8);
                        break;
                    case RH3_6LOTH_TYPE_4:
                        memcpy(&nextAddr.addr_128b[0],msg->payload+2,16);
                        break;
                    }
 packetfunctions_ip128bToMac64b(self, 
                        &nextAddr,
                        &temp_prefix,
                        &msg->l2_nextORpreviousHop
                    );
                } else {
                    hlen += 2;
                    switch(next_type){
                    case RH3_6LOTH_TYPE_0:
                        memcpy(&firstAddr.addr_128b[15],msg->payload+hlen,1);
                        hlen += 1;
                        break;
                    case RH3_6LOTH_TYPE_1:
                        memcpy(&firstAddr.addr_128b[14],msg->payload+hlen,2);
                        hlen += 2;
                        break;
                    case RH3_6LOTH_TYPE_2:
                        memcpy(&firstAddr.addr_128b[12],msg->payload+hlen,4);
                        hlen += 4;
                        break;
                    case RH3_6LOTH_TYPE_3:
                        memcpy(&firstAddr.addr_128b[8],msg->payload+hlen,8);
                        hlen += 8;
                        break;
                    }
                    next_size = temp_8b & RH3_6LOTH_SIZE_MASK;
 packetfunctions_tossHeader(self, msg,hlen);
                    if (next_size>0){
                        next_size -= 1;
 packetfunctions_reserveHeaderSize(self, msg,2);
                        msg->payload[0] = CRITICAL_6LORH | next_size;
                        msg->payload[1] = next_type;
                    }
                    // add first address
                    switch(type){
                    case RH3_6LOTH_TYPE_0:
 packetfunctions_reserveHeaderSize(self, msg,1);
                        msg->payload[0] = firstAddr.addr_128b[15];
                        break;
                    case RH3_6LOTH_TYPE_1:
 packetfunctions_reserveHeaderSize(self, msg,2);
                        memcpy(&msg->payload[0],&firstAddr.addr_128b[14],2);
                        break;
                    case RH3_6LOTH_TYPE_2:
 packetfunctions_reserveHeaderSize(self, msg,4);
                        memcpy(&msg->payload[0],&firstAddr.addr_128b[12],4);
                        break;
                    case RH3_6LOTH_TYPE_3:
 packetfunctions_reserveHeaderSize(self, msg,8);
                        memcpy(&msg->payload[0],&firstAddr.addr_128b[8],8);
                        break;
                    case RH3_6LOTH_TYPE_4:
 packetfunctions_reserveHeaderSize(self, msg,16);
                        memcpy(&msg->payload[0],&firstAddr.addr_128b[0],16);
                        break;
                    }
 packetfunctions_reserveHeaderSize(self, msg,2);
                    msg->payload[0] = CRITICAL_6LORH | 0;
                    msg->payload[1] = type;
 packetfunctions_ip128bToMac64b(self, 
                        &firstAddr,
                        &temp_prefix,
                        &msg->l2_nextORpreviousHop
                    );
                }
            } else {
                // there is no next RH3-6loRH, remove current one
 packetfunctions_tossHeader(self, msg,hlen);
 packetfunctions_ip128bToMac64b(self, 
                    &msg->l3_destinationAdd,
                    &temp_prefix,
                    &msg->l2_nextORpreviousHop
                );
            }
        }
    } else {
        // log error
 openserial_printError(self, 
            COMPONENT_IPHC,
            ERR_6LOWPAN_UNSUPPORTED,
            (errorparameter_t)16,
            (errorparameter_t)(temp_addr64.addr_64b[7])
        );
    }
    // copy RH3s before toss them
    if (
        ipv6_outer_header->src.type != ADDR_NONE &&
        ipv6_outer_header->hopByhop_option != NULL
    ){
        // check the length of RH3s
        RH3_length = ipv6_outer_header->hopByhop_option-msg->payload;
        memcpy(&RH3_copy[0],msg->payload,RH3_length);
 packetfunctions_tossHeader(self, msg,RH3_length);
        
        // retrieve hop-by-hop header (includes RPL option)
        rpi_length = iphc_retrieveIPv6HopByHopHeader(self, 
                          msg,
                          rpl_option
                     );
     
        // toss the headers
 packetfunctions_tossHeader(self, 
            msg,
            rpi_length
        );
      
        flags = rpl_option->flags;
        senderRank = rpl_option->senderRank;
        if ((flags & O_FLAG)!=O_FLAG){
            // 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);
        // toss the IP in IP 6LoRH
 packetfunctions_tossHeader(self, msg, ipv6_outer_header->header_length);
    } else {
        RH3_length = 0;
    }
    
    // send to next lower layer
    return iphc_sendFromForwarding(self, 
        msg,
        ipv6_outer_header,
        ipv6_inner_header,
        rpl_option,
        &ipv6_outer_header->flow_label,
        &RH3_copy[0],
        RH3_length,
        PCKTFORWARD
    );
}