def test_sourceRoute(expectedSourceRoute):
    """
    This tests the following topology
    
    MOTE_A <- MOTE_B <- MOTE_C <- MOTE_D
    """

    rpl = RPL.RPL()

    rpl.parents = {tuple(MOTE_B): [MOTE_A], tuple(MOTE_C): [MOTE_B], tuple(MOTE_D): [MOTE_C]}

    expectedDestination = json.loads(expectedSourceRoute)[0]
    expectedRoute = json.loads(expectedSourceRoute)[1]
    calculatedRoute = rpl.getRouteTo(expectedDestination)

    # log
    output = []
    output += ["\n"]
    output += ["expectedDestination: {0}".format(u.formatAddress(expectedDestination))]
    output += ["expectedRoute:"]
    for m in expectedRoute:
        output += ["- {0}".format(u.formatAddress(m))]
    output += ["calculatedRoute:"]
    for m in calculatedRoute:
        output += ["- {0}".format(u.formatAddress(m))]
    output = "\n".join(output)
    log.debug(output)

    assert calculatedRoute == expectedRoute
Example #2
0
def test_sourceRoute(expectedSourceRoute):
    '''
    This tests the following topology
    
    MOTE_A <- MOTE_B <- MOTE_C <- MOTE_D
    '''
    
    rpl = RPL.RPL()
    
    rpl.parents = {
        tuple(MOTE_B): [MOTE_A],
        tuple(MOTE_C): [MOTE_B],
        tuple(MOTE_D): [MOTE_C],
    }
    
    expectedDestination = json.loads(expectedSourceRoute)[0]
    expectedRoute       = json.loads(expectedSourceRoute)[1]
    calculatedRoute     = rpl.getRouteTo(expectedDestination)
    
    # log
    output              = []
    output             += ['\n']
    output             += ['expectedDestination: {0}'.format(u.formatAddress(expectedDestination))]
    output             += ['expectedRoute:']
    for m in expectedRoute:
            output     += ['- {0}'.format(u.formatAddress(m))]
    output             += ['calculatedRoute:']
    for m in calculatedRoute:
            output     += ['- {0}'.format(u.formatAddress(m))]
    output               = '\n'.join(output)
    log.debug(output)
    
    assert calculatedRoute==expectedRoute
Example #3
0
    def indicateDAO(self, dao):
        '''
        \brief Indicate a new DAO was received.
        
        This function parses the received packet, and if valid, updates the
        information needed to compute source routes.
        '''

        # retrieve source and destination
        try:
            destination = dao[0:8]
            source = dao[8:16]
            dao = dao[16:]
        except IndexError:
            log.warning(
                "DAO too short ({0} bytes), no space for destination and source"
                .format(len(dao)))
            return

        # log
        output = []
        output += ['received DAO:']
        output += ['- destination : {0}'.format(u.formatAddress(destination))]
        output += ['- source :      {0}'.format(u.formatAddress(source))]
        output += ['- dao :         {0}'.format(u.formatBuf(dao))]
        output = '\n'.join(output)
        log.debug(output)

        # retrieve DAO header
        dao_header = {}
        dao_transit_information = {}
        dao_target_information = {}

        try:
            # IPHC header
            dao_header['IPHC_b0'] = dao[0]
            dao_header['IPHC_b1'] = dao[1]
            dao_header['IPv6_nextHeader'] = dao[2]
            dao_header['IPv6_hoplimit'] = dao[3]
            dao_header['source_address'] = dao[4:12]
            # ICMPv6 header
            dao_header['ICMPv6_RPLType'] = dao[12]
            dao_header['ICMPv6_Code'] = dao[13]
            dao_header['ICMPv6_CheckSum_b0'] = dao[14]
            dao_header['ICMPv6_CheckSum_b1'] = dao[15]
            # RPL header
            dao_header['RPL_InstanceID'] = dao[16]
            dao_header['RPL_flags'] = dao[17]
            dao_header['RPL_Reserved'] = dao[18]
            dao_header['RPL_DAO_Sequence'] = dao[19]
            # DODAGID
            dao_header['DODAGID'] = dao[20:36]

            dao = dao[36:]
            # retrieve transit information header and parents
            parents = []
            children = []

            while (len(dao) > 0):
                if (dao[0] == self._TRANSIT_INFORMATION_TYPE):
                    # transit information option
                    dao_transit_information['Transit_information_type'] = dao[
                        0]
                    dao_transit_information[
                        'Transit_information_length'] = dao[1]
                    dao_transit_information['Transit_information_flags'] = dao[
                        2]
                    dao_transit_information[
                        'Transit_information_path_control'] = dao[3]
                    dao_transit_information[
                        'Transit_information_path_sequence'] = dao[4]
                    dao_transit_information[
                        'Transit_information_path_lifetime'] = dao[5]
                    parents += [dao[6:14]]  #address of the parent.
                    dao = dao[14:]
                elif (dao[0] == self._TARGET_INFORMATION_TYPE):
                    dao_target_information['Target_information_type'] = dao[0]
                    dao_target_information['Target_information_length'] = dao[
                        1]
                    dao_target_information['Target_information_flags'] = dao[2]
                    dao_target_information[
                        'Target_information_prefix_length'] = dao[3]
                    children += [dao[4:12]]  #address of the parent.
                    dao = dao[12:]
                else:
                    log.warning(
                        "DAO with wrong Option. Neither Transit nor Target. Option is ({0})"
                        .format(dao[0]))
                    return
        except IndexError:
            log.warning(
                "DAO too short ({0} bytes), no space for DAO header".format(
                    len(dao)))
            return

        # log
        output = []
        output += ['parents:']
        for p in parents:
            output += ['- {0}'.format(u.formatAddress(p))]
        output = '\n'.join(output)
        log.debug(output)

        output = []
        output += ['children:']
        for p in children:
            output += ['- {0}'.format(u.formatAddress(p))]
        output = '\n'.join(output)
        log.debug(output)

        # if you get here, the DAO was parsed correctly

        # update parents information with parents collected
        with self.dataLock:
            self.parents.update({tuple(source): parents})
Example #4
0
 def indicateDAO(self,dao):    
     '''
     \brief Indicate a new DAO was received.
     
     This function parses the received packet, and if valid, updates the
     information needed to compute source routes.
     '''
     
     # retrieve source and destination
     try:
         destination      = dao[0:8]
         source           = dao[8:16]
         dao              = dao[16:]
     except IndexError:
         log.warning("DAO too short ({0} bytes), no space for destination and source".format(len(dao)))
         return
     
     # log
     output               = []
     output              += ['received DAO:']
     output              += ['- destination : {0}'.format(u.formatAddress(destination))]
     output              += ['- source :      {0}'.format(u.formatAddress(source))]
     output              += ['- dao :         {0}'.format(u.formatBuf(dao))]
     output               = '\n'.join(output)
     log.debug(output)
     
     # retrieve DAO header
     dao_header              = {}
     dao_transit_information = {}
     dao_target_information = {}
     
     try:
         # IPHC header
         dao_header['IPHC_b0']                               = dao[0]
         dao_header['IPHC_b1']                               = dao[1]
         dao_header['IPv6_nextHeader']                       = dao[2]
         dao_header['IPv6_hoplimit']                         = dao[3]
         dao_header['source_address']                        = dao[4:12]
         # ICMPv6 header
         dao_header['ICMPv6_RPLType']                        = dao[12]
         dao_header['ICMPv6_Code']                           = dao[13]
         dao_header['ICMPv6_CheckSum_b0']                    = dao[14]
         dao_header['ICMPv6_CheckSum_b1']                    = dao[15]
         # RPL header
         dao_header['RPL_InstanceID']                        = dao[16]
         dao_header['RPL_flags']                             = dao[17]
         dao_header['RPL_Reserved']                          = dao[18]
         dao_header['RPL_DAO_Sequence']                      = dao[19]
         # DODAGID
         dao_header['DODAGID']                               = dao[20:36]
        
         dao              = dao[36:]
         # retrieve transit information header and parents
         parents              = []
         children             = []
                       
         while (len(dao)>0):  
            if (dao[0]==self._TRANSIT_INFORMATION_TYPE): 
            # transit information option
                dao_transit_information['Transit_information_type']              = dao[0]
                dao_transit_information['Transit_information_length']            = dao[1]
                dao_transit_information['Transit_information_flags']             = dao[2]
                dao_transit_information['Transit_information_path_control']      = dao[3]
                dao_transit_information['Transit_information_path_sequence']     = dao[4]
                dao_transit_information['Transit_information_path_lifetime']     = dao[5]
                parents += [dao[6:14]]#address of the parent.
                dao=dao[14:]
            elif  (dao[0]==self._TARGET_INFORMATION_TYPE):
                dao_target_information['Target_information_type']                = dao[0]
                dao_target_information['Target_information_length']              = dao[1]
                dao_target_information['Target_information_flags']               = dao[2]
                dao_target_information['Target_information_prefix_length']       = dao[3]
                children += [dao[4:12]]#address of the parent.
                dao=dao[12:]
            else:
                log.warning("DAO with wrong Option. Neither Transit nor Target. Option is ({0})".format(dao[0]))
                return
     except IndexError:
         log.warning("DAO too short ({0} bytes), no space for DAO header".format(len(dao)))
         return
     
     # log
     output               = []
     output              += ['parents:']
     for p in parents:
         output          += ['- {0}'.format(u.formatAddress(p))]
     output               = '\n'.join(output)
     log.debug(output)
     
     
     output               = []
     output              += ['children:']
     for p in children:
         output          += ['- {0}'.format(u.formatAddress(p))]
     output               = '\n'.join(output)
     log.debug(output)
     
     # if you get here, the DAO was parsed correctly
     
     # update parents information with parents collected
     with self.dataLock:
         self.parents.update({tuple(source):parents})