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()
Exemple #3
0
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