Exemplo n.º 1
0
/**
\brief Indicate some packet was sent to some neighbor.

This function should be called for each transmitted (non-ACK) packet so
neighbor statistics in the neighbor table can be updated.

The fields which are updated are:
- numTx
- numTxACK
- asn

\param[in] l2_dest MAC destination address of the packet, i.e. the neighbor
   who I just sent the packet to.
\param[in] numTxAttempts Number of transmission attempts to this neighbor.
\param[in] was_finally_acked TRUE iff the packet was ACK'ed by the neighbor
   on final transmission attempt.
\param[in] asnTs ASN of the last transmission attempt.
*/
void neighbors_indicateTx(open_addr_t* l2_dest,
                          uint8_t      numTxAttempts,
                          bool         was_finally_acked,
                          asn_t*       asnTs) {
   uint8_t i;
   // don't run through this function if packet was sent to broadcast address
   if (packetfunctions_isBroadcastMulticast(l2_dest)==TRUE) {
      return;
   }
   
   // loop through neighbor table
   for (i=0;i<MAXNUMNEIGHBORS;i++) {
      if (isThisRowMatching(l2_dest,i)) {
         // handle roll-over case
        
          if (neighbors_vars.neighbors[i].numTx>(0xff-numTxAttempts)) {
              neighbors_vars.neighbors[i].numWraps++; //counting the number of times that tx wraps.
              neighbors_vars.neighbors[i].numTx/=2;
              neighbors_vars.neighbors[i].numTxACK/=2;
           }
         // update statistics
        neighbors_vars.neighbors[i].numTx += numTxAttempts; 
        
        if (was_finally_acked==TRUE) {
            neighbors_vars.neighbors[i].numTxACK++;
            memcpy(&neighbors_vars.neighbors[i].asn,asnTs,sizeof(asn_t));
        }
        break;
      }
   }
}
Exemplo n.º 2
0
 OpenQueueEntry_t* openqueue_macGetDataPacket(open_addr_t* toNeighbor) {
   uint8_t i;
   INTERRUPT_DECLARATION();
   DISABLE_INTERRUPTS();
   if (toNeighbor->type==ADDR_64B) {
      // a neighbor is specified, look for a packet unicast to that neigbhbor
      for (i=0;i<QUEUELENGTH;i++) {
         if (openqueue_vars.queue[i].owner==COMPONENT_RES_TO_IEEE802154E &&
            packetfunctions_sameAddress(toNeighbor,&openqueue_vars.queue[i].l2_nextORpreviousHop)) {
            ENABLE_INTERRUPTS();
            return &openqueue_vars.queue[i];
         }
      }
   } else if (toNeighbor->type==ADDR_ANYCAST) {
      // anycast case: look for a packet which is either not created by RES
      // or an KA (created by RES, but not broadcast)
      for (i=0;i<QUEUELENGTH;i++) {
         if (openqueue_vars.queue[i].owner==COMPONENT_RES_TO_IEEE802154E &&
             ( openqueue_vars.queue[i].creator!=COMPONENT_RES ||
                (
                   openqueue_vars.queue[i].creator==COMPONENT_RES &&
                   packetfunctions_isBroadcastMulticast(&(openqueue_vars.queue[i].l2_nextORpreviousHop))==FALSE
                )
             )
            ) {
            ENABLE_INTERRUPTS();
            return &openqueue_vars.queue[i];
         }
      }
   }
   ENABLE_INTERRUPTS();
   return NULL;
}
Exemplo n.º 3
0
/**
\brief Transfer packet to MAC.

This function adds a IEEE802.15.4 header to the packet and leaves it the 
OpenQueue buffer. The very last thing it does is assigning this packet to the 
virtual component COMPONENT_RES_TO_IEEE802154E. Whenever it gets a change,
IEEE802154E will handle the packet.

\param [in] msg The packet to the transmitted

\returns E_SUCCESS iff successful.
*/
error_t res_send_internal(OpenQueueEntry_t* msg) {
   // assign a number of retries
   if (packetfunctions_isBroadcastMulticast(&(msg->l2_nextORpreviousHop))==TRUE) {
      msg->l2_retriesLeft = 1;
   } else {
      msg->l2_retriesLeft = TXRETRIES;
   }
   // record this packet's dsn (for matching the ACK)
   msg->l2_dsn = res_vars.dsn++;
   // this is a new packet which I never attempted to send
   msg->l2_numTxAttempts = 0;
   // transmit with the default TX power
   msg->l1_txPower = TX_POWER;
   // record the location, in the packet, where the l2 payload starts
   msg->l2_payload = msg->payload;
   // add a IEEE802.15.4 header
   ieee802154_prependHeader(msg,
                            msg->l2_frameType,
                            IEEE154_SEC_NO_SECURITY,
                            msg->l2_dsn,
                            &(msg->l2_nextORpreviousHop)
                            );
   // reserve space for 2-byte CRC
   packetfunctions_reserveFooterSize(msg,2);
   // change owner to IEEE802154E fetches it from queue
   msg->owner  = COMPONENT_RES_TO_IEEE802154E;
   return E_SUCCESS;
}
Exemplo n.º 4
0
 OpenQueueEntry_t* openqueue_macGetAdvPacket() {
   uint8_t i;
   INTERRUPT_DECLARATION();
   DISABLE_INTERRUPTS();
   for (i=0;i<QUEUELENGTH;i++) {
      if (openqueue_vars.queue[i].owner==COMPONENT_RES_TO_IEEE802154E &&
          openqueue_vars.queue[i].creator==COMPONENT_RES              &&
          packetfunctions_isBroadcastMulticast(&(openqueue_vars.queue[i].l2_nextORpreviousHop))) {
    	  ENABLE_INTERRUPTS();
          return &openqueue_vars.queue[i];
      }
   }
   ENABLE_INTERRUPTS();
   return NULL;
}
Exemplo n.º 5
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);
          }
        }
      }
}
Exemplo n.º 6
0
void getNextHop(open_addr_t* destination128b, open_addr_t* addressToWrite64b) {
  uint8_t i;
  open_addr_t temp_prefix64btoWrite;
  if (packetfunctions_isBroadcastMulticast(destination128b)) {
    // IP destination is broadcast, send to 0xffffffffffffffff
    addressToWrite64b->type = ADDR_64B;
    for (i=0;i<8;i++) {
      addressToWrite64b->addr_64b[i] = 0xff;
    }
  } else if (neighbors_isStableNeighbor(destination128b)) {
    // IP destination is 1-hop neighbor, send directly
    packetfunctions_ip128bToMac64b(destination128b,&temp_prefix64btoWrite,addressToWrite64b);
  } else {
    // destination is remote, send to preferred parent
    neighbors_getPreferredParent(addressToWrite64b,ADDR_64B);
  }
}
Exemplo n.º 7
0
void neighbors_indicateTx(open_addr_t* dest,
                          uint8_t      numTxAttempts,
                          bool         was_finally_acked,
                          asn_t*       asnTimestamp) {
   uint8_t i=0;
   if (packetfunctions_isBroadcastMulticast(dest)==FALSE) {
      for (i=0;i<MAXNUMNEIGHBORS;i++) {
         if (isThisRowMatching(dest,i)) {
            if (neighbors_vars.neighbors[i].numTx==255) {
               neighbors_vars.neighbors[i].numTx/=2;
               neighbors_vars.neighbors[i].numTxACK/=2;
            }
            neighbors_vars.neighbors[i].numTx += numTxAttempts;
            if (was_finally_acked==TRUE) {
               neighbors_vars.neighbors[i].numTxACK++;
               memcpy(&neighbors_vars.neighbors[i].asn,asnTimestamp,sizeof(asn_t));
            }
            return;
         }
      }
   }
}
Exemplo n.º 8
0
/**
\brief Prepend the IEEE802.15.4 MAC header to a (to be transmitted) packet.

Note that we are writing the field from the end of the header to the beginning.

\param[in,out] msg              The message to append the header to.
\param[in]     frameType        Type of IEEE802.15.4 frame.
\param[in]     ielistpresent    Is the IE list present¿
\param[in]     frameVersion     IEEE802.15.4 frame version.
\param[in]     securityEnabled  Is security enabled on this frame?
\param[in]     sequenceNumber   Sequence number of this frame.
\param[in]     nextHop          Address of the next hop
*/
void ieee802154_prependHeader(OpenQueueEntry_t* msg,
                              uint8_t           frameType,
                              uint8_t           ielistpresent,
                              uint8_t           frameVersion,
                              bool              securityEnabled,
                              uint8_t           sequenceNumber,
                              open_addr_t*      nextHop) {
   uint8_t temp_8b;
   
   //General IEs here (those that are carried in all packets) -- None by now.
   
   // previousHop address (always 64-bit)
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_64B),OW_LITTLE_ENDIAN);
   // nextHop address
   if (packetfunctions_isBroadcastMulticast(nextHop)) {
      //broadcast address is always 16-bit
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
   } else {
      switch (nextHop->type) {
         case ADDR_16B:
         case ADDR_64B:
            packetfunctions_writeAddress(msg,nextHop,OW_LITTLE_ENDIAN);
            break;
         default:
            openserial_printCritical(COMPONENT_IEEE802154,ERR_WRONG_ADDR_TYPE,
                                  (errorparameter_t)nextHop->type,
                                  (errorparameter_t)1);
      }
      
   }
   // destpan
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_PANID),OW_LITTLE_ENDIAN);
   //dsn
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = sequenceNumber;
   //fcf (2nd byte)
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   temp_8b              = 0;
   if (packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
   } else {
      switch (nextHop->type) {
         case ADDR_16B:
            temp_8b    |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
            break;
         case ADDR_64B:
            temp_8b    |= IEEE154_ADDR_EXT                << IEEE154_FCF_DEST_ADDR_MODE;
            break;
         // no need for a default, since it would have been caught above.
      }
   }
   temp_8b             |= IEEE154_ADDR_EXT                << IEEE154_FCF_SRC_ADDR_MODE;
   //poipoi xv IE list present
   temp_8b             |= ielistpresent                   << IEEE154_FCF_IELIST_PRESENT;
   temp_8b             |= frameVersion                    << IEEE154_FCF_FRAME_VERSION;
     
   *((uint8_t*)(msg->payload)) = temp_8b;
   //fcf (1st byte)
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   temp_8b              = 0;
   temp_8b             |= frameType                       << IEEE154_FCF_FRAME_TYPE;
   temp_8b             |= securityEnabled                 << IEEE154_FCF_SECURITY_ENABLED;
   temp_8b             |= IEEE154_PENDING_NO_FRAMEPENDING << IEEE154_FCF_FRAME_PENDING;
   if (frameType==IEEE154_TYPE_ACK || packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ACK_NO_ACK_REQ          << IEEE154_FCF_ACK_REQ;
   } else {
      temp_8b          |= IEEE154_ACK_YES_ACK_REQ         << IEEE154_FCF_ACK_REQ;
   }
   temp_8b             |= IEEE154_PANID_COMPRESSED        << IEEE154_FCF_INTRAPAN;
   *((uint8_t*)(msg->payload)) = temp_8b;
}
Exemplo n.º 9
0
void ieee802154_prependHeader(OpenQueueEntry_t* msg,
                              uint8_t           frameType,
                              bool              securityEnabled,
                              uint8_t           sequenceNumber,
                              open_addr_t*      nextHop) {
   uint8_t temp_8b;
   //previousHop address (always 64-bit)
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_64B),LITTLE_ENDIAN);
   // poipoi: using 16-bit source address
   //packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_16B),LITTLE_ENDIAN);
   //nextHop address
   if (packetfunctions_isBroadcastMulticast(nextHop)) { //broadcast address is always 16-bit
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
      *((uint8_t*)(msg->payload)) = 0xFF;
   } else {
      // poipoi: using 16-bit destination address
//      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
//      *((uint8_t*)(msg->payload)) = nextHop->addr_64b[6];
//      packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
//      *((uint8_t*)(msg->payload)) = nextHop->addr_64b[7];
//      
      switch (nextHop->type) {
         case ADDR_16B:
         case ADDR_64B:
            packetfunctions_writeAddress(msg,nextHop,LITTLE_ENDIAN);
            break;
         default:
            openserial_printError(COMPONENT_IEEE802154,ERR_WRONG_ADDR_TYPE,
                                  (errorparameter_t)nextHop->type,
                                  (errorparameter_t)1);
      }
      
   }
   //destpan
   packetfunctions_writeAddress(msg,idmanager_getMyID(ADDR_PANID),LITTLE_ENDIAN);
   //dsn
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = sequenceNumber;
   //fcf (2nd byte)
   temp_8b              = 0;
   // poipoi: 16-bit source/dest addresses
  // temp_8b             |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
   //temp_8b             |= IEEE154_ADDR_SHORT              << IEEE154_FCF_SRC_ADDR_MODE;
   
   if (packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
   } else {
      switch (nextHop->type) {
         case ADDR_16B:
            temp_8b    |= IEEE154_ADDR_SHORT              << IEEE154_FCF_DEST_ADDR_MODE;
            break;
         case ADDR_64B:
            temp_8b    |= IEEE154_ADDR_EXT                << IEEE154_FCF_DEST_ADDR_MODE;
            break;
      }
   }
   temp_8b             |= IEEE154_ADDR_EXT                << IEEE154_FCF_SRC_ADDR_MODE;
   
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = temp_8b;
   //fcf (1st byte)
   temp_8b              = 0;
   temp_8b             |= frameType                       << IEEE154_FCF_FRAME_TYPE;
   temp_8b             |= securityEnabled                 << IEEE154_FCF_SECURITY_ENABLED;
   temp_8b             |= IEEE154_PENDING_NO_FRAMEPENDING << IEEE154_FCF_FRAME_PENDING;
   if (frameType==IEEE154_TYPE_ACK || packetfunctions_isBroadcastMulticast(nextHop)) {
      temp_8b          |= IEEE154_ACK_NO_ACK_REQ          << IEEE154_FCF_ACK_REQ;
   } else {
      temp_8b          |= IEEE154_ACK_YES_ACK_REQ         << IEEE154_FCF_ACK_REQ;
   }
   temp_8b             |= IEEE154_PANID_COMPRESSED        << IEEE154_FCF_INTRAPAN;
   packetfunctions_reserveHeaderSize(msg,sizeof(uint8_t));
   *((uint8_t*)(msg->payload)) = temp_8b;
}
Exemplo n.º 10
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) {
Exemplo n.º 11
0
/**
\brief Send a packet originating at this mote.

This function is called by an upper layer, and only concerns packets originated
at this mote.

\param[in,out] msg Packet to send.
*/
owerror_t forwarding_send(OpenMote* self, OpenQueueEntry_t* msg) {
    ipv6_header_iht      ipv6_outer_header;
    ipv6_header_iht      ipv6_inner_header;
    rpl_option_ht        rpl_option;
    open_addr_t*         myprefix;
    open_addr_t*         myadd64;
    uint32_t             flow_label = 0;

    open_addr_t          temp_dest_prefix;
    open_addr_t          temp_dest_mac64b;
    open_addr_t*         p_dest;
    open_addr_t*         p_src;  
    open_addr_t          temp_src_prefix;
    open_addr_t          temp_src_mac64b; 
    uint8_t              sam;
    uint8_t              m;
    uint8_t              dam;

    // take ownership over the packet
    msg->owner                = COMPONENT_FORWARDING;

    m   = IPHC_M_NO;

    // retrieve my prefix and EUI64
    myprefix                  = idmanager_getMyID(self, ADDR_PREFIX);
    myadd64                   = idmanager_getMyID(self, ADDR_64B);

    // set source address (me)
    msg->l3_sourceAdd.type=ADDR_128B;
    memcpy(&(msg->l3_sourceAdd.addr_128b[0]),myprefix->prefix,8);
    memcpy(&(msg->l3_sourceAdd.addr_128b[8]),myadd64->addr_64b,8);

    // initialize IPv6 header
    memset(&ipv6_outer_header,0,sizeof(ipv6_header_iht));
    memset(&ipv6_inner_header,0,sizeof(ipv6_header_iht));

    // Set hop limit to the default in-network value as this packet is being
    // sent from upper layer. 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_inner_header.hop_limit     = IPHC_DEFAULT_HOP_LIMIT;

    // create the RPL hop-by-hop option

 forwarding_createRplOption(self, 
      &rpl_option,      // rpl_option to fill in
      0x00              // flags
    );

 packetfunctions_ip128bToMac64b(self, &(msg->l3_destinationAdd),&temp_dest_prefix,&temp_dest_mac64b);
    //xv poipoi -- get the src prefix as well
 packetfunctions_ip128bToMac64b(self, &(msg->l3_sourceAdd),&temp_src_prefix,&temp_src_mac64b);
    //XV -poipoi we want to check if the source address prefix is the same as destination prefix
    if ( packetfunctions_sameAddress(self, &temp_dest_prefix,&temp_src_prefix)) {
         // same prefix use 64B address
         sam = IPHC_SAM_64B;
         dam = IPHC_DAM_64B;
         p_dest = &temp_dest_mac64b;      
         p_src  = &temp_src_mac64b; 
    } else {
        //not the same prefix. so the packet travels to another network
        //check if this is a source routing pkt. in case it is then the DAM is elided as it is in the SrcRouting header.
        if ( packetfunctions_isBroadcastMulticast(self, &(msg->l3_destinationAdd))==FALSE){
            sam = IPHC_SAM_128B;
            dam = IPHC_DAM_128B;
            p_dest = &(msg->l3_destinationAdd);
            p_src = &(msg->l3_sourceAdd);
            
            ipv6_outer_header.src.type = ADDR_128B;
            memcpy(&ipv6_outer_header.src,p_src,sizeof(open_addr_t));
            ipv6_outer_header.hop_limit = IPHC_DEFAULT_HOP_LIMIT;
        } else {
           // this is DIO, source address elided, multicast bit is set
            sam = IPHC_SAM_ELIDED;
            m   = IPHC_M_YES;
            dam = IPHC_DAM_ELIDED;
            p_dest = &(msg->l3_destinationAdd);
            p_src = &(msg->l3_sourceAdd);
        }
    }
    //IPHC inner header and NHC IPv6 header will be added at here
 iphc_prependIPv6Header(self, msg,
                IPHC_TF_ELIDED,
                flow_label, // value_flowlabel
                IPHC_NH_INLINE,
                msg->l4_protocol, 
                IPHC_HLIM_64,
                ipv6_outer_header.hop_limit,
                IPHC_CID_NO,
                IPHC_SAC_STATELESS,
                sam,
                m,
                IPHC_DAC_STATELESS,
                dam,
                p_dest,
                p_src,            
                PCKTSEND  
                );
    // both of them are compressed
    ipv6_outer_header.next_header_compressed = TRUE;

    return forwarding_send_internal_RoutingTable(self, 
        msg,
        &ipv6_outer_header,
        &ipv6_inner_header,
        &rpl_option,
        &flow_label,
        PCKTSEND
    );
}
Exemplo n.º 12
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
                );
            }
        }
    }
}