class IntegrityHandler(object): __result = False __sequence_handler = None def __init__(self): self.__sequence_handler = SequenceHandler() def __isIntegrityValid(self, afdxPacket): rsn = afdxPacket.getFrameSequenceNumber() if rsn == None: return False vlId = afdxPacket.getDestinedVl() prsn = self.__sequence_handler.getPRSN(vlId) prsn_next_1 = self.__sequence_handler.getNextSequenceNumber(prsn, SEQUENCE_FRAME) prsn_next_2 = self.__sequence_handler.getNextSequenceNumber(prsn_next_1, SEQUENCE_FRAME) if (rsn in (prsn_next_1, prsn_next_2)) or (prsn == -1) or \ (rsn == 0 and prsn != 0): if (rsn == 0 and prsn != 0): self.__sequence_handler.setASN(vlId, 0) self.__sequence_handler.setRSN(vlId, rsn) return True return False def doCheck(self, afdxPacket): self.__result = False if not self.__isIntegrityValid(afdxPacket): if afdxPacket[IP] != None: print "Integrity check failed for packet with ip id", \ afdxPacket[IP].id #afdxLogger.error("The packet failed integrity check") return self.__result = True #afdxLogger.info("The packet has passed the integrity check") def getResult(self): return self.__result def reset(self): self.__sequence_handler = SequenceHandler()
def __init__(self): self.__sequence_handler = SequenceHandler()
class Transmitter(object): __port = None __packet = None def __init__(self): self._sn_handler = SequenceHandler() def __addEthernetDetails(self): eth = Ether() src_mac_padding = '%04x' % self.__port.vl_id eth.dst = "%s:%s:%s" % (get("MAC_PREFIX_RX"), src_mac_padding[:2], src_mac_padding[2:]) eth.src = get("MAC_PREFIX_TX") + ":20" eth.type = 0x800 self.__packet = eth def __addIpDetails(self): port = self.__port ip_layer = IP() ip_layer.src = port.ip_src ip_layer.dst = port.ip_dst #ip_layer.id = self._sn_handler.getNextIpId() #ip_layer.prot = 0x17 self.__packet = self.__packet/ip_layer def __addUDPDetails(self): port = self.__port udp_layer = UDP() udp_layer.sport = port.udp_src udp_layer.dport = port.udp_dst udp_layer.chksum = 0x00 #udp_layer.len = len(port.payload) self.__packet = self.__packet/udp_layer def __addPayload(self): self.__packet /= self.__port.payload def __normalize(self): port = self.__port # any payload size greater than 1472 needs to be fragmented # as the its the ethernet limitation if len(port.payload) > 1472 or len(port.payload) > port.max_frame_size: self.__packet = self.fragment(self.__packet) else: self.__packet = [self.__packet] def __addPadding(self, packet): payload_length = len(packet) padding = '' # the size index 17 is caculated as 60 - (ethHdr + ipHdr + udpHdr) = 18 # but here we are using the size index as 17 because the last bit will # be the sequence number which will be added at 'transmit' function if payload_length < 59: padding = '\0' * (59 - payload_length) sn = self._sn_handler.getNextFrameSequenceNumber(self.__port.vl_id) if sn == 0: padding += '\0' else: padding += chr(sn) packet /= Padding(padding) return packet def __createPacket(self): if self.__port == None: return if (not hasattr(self.__port, 'payload')) or self.__port.payload == None: return self.__addEthernetDetails() self.__addIpDetails() if not isinstance(self.__port.payload, SNMPresponse): self.__addUDPDetails() self.__addPayload() self.__normalize() def transmit(self, port, network): self.__port = port self.__createPacket() time.sleep(0.5) # to be removed, only for testing redundancy management network = 'A' for packet in self.__packet: packet = self.__addPadding(packet) if NETWORK_A in network: packet[Ether].src = get("MAC_PREFIX_TX") + ":20" sendp(packet, iface = get("NETWORK_INTERFACE_A"), verbose = False) if NETWORK_B in network: packet[Ether].src = get("MAC_PREFIX_TX") + ":40" sendp(packet, iface = get("NETWORK_INTERFACE_B"), verbose = False) def reset(self): pass def fragment(self, packet): max_frame_size = 1472 if self.__port.max_frame_size > 1472 else \ self.__port.max_frame_size # we aren't using packet[UDP].len because if the packet is a SNMP # packet, the length we are getting is None !!. Hence this workaroud payload_length = len(packet[UDP]) - 8 if max_frame_size < payload_length: return fragment(packet, max_frame_size) else: return [packet]
def reset(self): self.__sequence_handler = SequenceHandler()
class RedundancyHandler(object): __result = False __sequence_handler = None _accepted_sns = dict() def __init__(self): self.__sequence_handler = SequenceHandler() def __addAcceptedSN(self, vlId, sn): if self._accepted_sns.has_key(vlId): if len(self._accepted_sns[vlId]) > 10: self._accepted_sns[vlId] = self._accepted_sns[vlId][5:] self._accepted_sns[vlId].append(sn) else: self._accepted_sns[vlId] = [sn] def __getLatestAcceptedSNs(self, vlId): if self._accepted_sns.has_key(vlId): sns = self._accepted_sns[vlId] return sns[-5:] return tuple() def __checkForRedundancy(self, afdxPacket): rsn = afdxPacket.getFrameSequenceNumber() if rsn == None: return False vlId = afdxPacket.getDestinedVl() pasn = self.__sequence_handler.getPASN(vlId) # the below condition is as per the specification #acceptable_asn = [self.__sequence_handler.getNextSequenceNumber( # pasn + i, SEQUENCE_FRAME) \ # for i in range(0, 66)] # this condition is as per what kailash has thought of. # the dict "_accepted_sns" contains list of 5 recently accepted # sequence numbers for a vl. If the rsn is in any of the received # sn's then the packet is a redundant packet, hence reject else # accept and proceed forward acceptable_asn = self.__getLatestAcceptedSNs(vlId) #print pasn, rsn, acceptable_asn, vlId, rsn in acceptable_asn if (pasn == -1) or (rsn not in acceptable_asn): #print 'accepted' self.__sequence_handler.setASN(vlId, rsn) self.__addAcceptedSN(vlId, rsn) return True return False def doCheck(self, afdxPacket): self.__result = False if not self.__checkForRedundancy(afdxPacket): print 'Redundancy check failed for packet with ip id', \ afdxPacket[IP].id #afdxLogger.error("The packet failed with redundancy check") return self.__result = True #afdxLogger.info("The packet has passed the redundancy check") def getResult(self): return self.__result def reset(self): self._accepted_sns.clear() self.__result = False