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
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
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})
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})