Ejemplo n.º 1
0
    def post_build(self, pkt, pay):
        """
        need to set the length of the whole PDU manually
        to avoid any bit fiddling use a dummy class to build the layer content

        also add padding if frame is < 64 bytes

        Note: padding only handles Ether/n*Dot1Q/EtherCat
              (no special mumbo jumbo)

        :param pkt: raw string containing the current layer
        :param pay: raw string containing the payload
        :return: <new current layer> + payload
        """
        class _EtherCatLengthCalc(Packet):
            """
            dummy class used to generate str representation easily
            """
            fields_desc = [
                LEBitField('length', None, 11),
                LEBitField('_reserved', 0, 1),
                LEBitField('type', 0, 4),
            ]

        payload_len = len(pay)

        # length field is 11 bit
        if payload_len > 2047:
            raise ValueError('payload size {} exceeds maximum length {} '
                             'of EtherCat message.'.format(payload_len, 2047))

        self.length = payload_len

        vlan_headers_total_size = 0
        upper_layer = self.underlayer

        # add size occupied by VLAN tags
        while upper_layer and isinstance(upper_layer, Dot1Q):
            vlan_headers_total_size += 4
            upper_layer = upper_layer.underlayer

        if not isinstance(upper_layer, Ether):
            raise Exception('missing Ether layer')

        pad_len = EtherCat.ETHER_FRAME_MIN_LEN - (
            EtherCat.ETHER_HEADER_LEN + vlan_headers_total_size +
            EtherCat.ETHERCAT_HEADER_LEN + payload_len +
            EtherCat.ETHER_FSC_LEN)

        if pad_len > 0:
            pad = Padding()
            pad.load = b'\x00' * pad_len

            return raw(_EtherCatLengthCalc(length=self.length,
                                           type=self.type)) + pay + raw(pad)
        else:
            return raw(_EtherCatLengthCalc(length=self.length,
                                           type=self.type)) + pay
Ejemplo n.º 2
0
Archivo: lldp.py Proyecto: 6WIND/scapy
    def post_build(self, pkt, pay):

        last_layer = not len(pay)
        if last_layer and conf.contribs['LLDP'].strict_mode() and \
                        type(self).__name__ != LLDPDUEndOfLLDPDU.__name__:
            raise LLDPInvalidLastLayerException('Last layer must be instance '
                                                'of LLDPDUEndOfLLDPDU - '
                                                'got {}'.
                                                format(type(self).__name__))

        under_layer = self.underlayer

        if under_layer is None:
            if conf.contribs['LLDP'].strict_mode():
                raise LLDPMissingLowerLayer('No lower layer (Ethernet '
                                            'or Dot1Q) provided.')
            else:
                return pkt + pay

        not_lowest_lldpdu = under_layer.__class__.__base__.__name__ is 'LLDPDU'
        if not_lowest_lldpdu:
            return pkt + pay

        frame_size, under_layer = LLDPDU._dot1q_headers_size(under_layer)

        if not under_layer or not isinstance(under_layer, Ether):
            if conf.contribs['LLDP'].strict_mode():
                raise LLDPMissingLowerLayer('No Ethernet layer provided.')
            else:
                return pkt + pay

        frame_size += LLDPDU.ETHER_HEADER_LEN
        frame_size += len(pkt) + len(pay) + LLDPDU.ETHER_FSC_LEN
        if frame_size < LLDPDU.ETHER_FRAME_MIN_LEN:
            pad = Padding()
            pad.load = b'\x00' * (LLDPDU.ETHER_FRAME_MIN_LEN - frame_size)
            return pkt + pay + raw(pad)
        else:
            return pkt + pay
Ejemplo n.º 3
0
    def post_build(self, pkt, pay):

        last_layer = not len(pay)
        if last_layer and conf.contribs['LLDP'].strict_mode() and \
                        type(self).__name__ != LLDPDUEndOfLLDPDU.__name__:
            raise LLDPInvalidLastLayerException('Last layer must be instance '
                                                'of LLDPDUEndOfLLDPDU - '
                                                'got {}'.
                                                format(type(self).__name__))

        under_layer = self.underlayer

        if under_layer is None:
            if conf.contribs['LLDP'].strict_mode():
                raise LLDPMissingLowerLayer('No lower layer (Ethernet '
                                            'or Dot1Q) provided.')
            else:
                return pkt + pay

        not_lowest_lldpdu = under_layer.__class__.__base__.__name__ is 'LLDPDU'
        if not_lowest_lldpdu:
            return pkt + pay

        frame_size, under_layer = LLDPDU._dot1q_headers_size(under_layer)

        if not under_layer or not isinstance(under_layer, Ether):
            if conf.contribs['LLDP'].strict_mode():
                raise LLDPMissingLowerLayer('No Ethernet layer provided.')
            else:
                return pkt + pay

        frame_size += LLDPDU.ETHER_HEADER_LEN
        frame_size += len(pkt) + len(pay) + LLDPDU.ETHER_FSC_LEN
        if frame_size < LLDPDU.ETHER_FRAME_MIN_LEN:
            pad = Padding()
            pad.load = b'\x00' * (LLDPDU.ETHER_FRAME_MIN_LEN - frame_size)
            return pkt + pay + raw(pad)
        else:
            return pkt + pay