Ejemplo n.º 1
0
    def __pre_parse_sanity_check(self, raw_packet, pseudo_header):
        """ Preliminary sanity check to be run on raw UDP packet prior to packet parsing """

        if not config.pre_parse_sanity_check:
            return True

        if inet_cksum(pseudo_header + raw_packet):
            self.logger.critical(
                f"{self.tracker} - UDP sanity check fail - wrong packet checksum"
            )
            return False

        if len(raw_packet) < 8:
            self.logger.critical(
                f"{self.tracker} - UDP sanity check fail - wrong packet length (I)"
            )
            return False

        plen = struct.unpack("!H", raw_packet[4:6])[0]
        if not 8 <= plen == len(raw_packet):
            self.logger.critical(
                f"{self.tracker} - UDP sanity check fail - wrong packet length (II)"
            )
            return False

        return True
Ejemplo n.º 2
0
    def validate_cksum(self, ip_pseudo_header):
        """ Validate packet checksum """

        # Return valid checksum if checksum is not used
        if not self.udp_cksum:
            return True

        return not bool(inet_cksum(ip_pseudo_header + self.raw_packet))
Ejemplo n.º 3
0
    def __pre_parse_sanity_check(self, raw_packet):
        """ Preliminary sanity check to be run on raw IPv4 packet prior to packet parsing """

        if not config.pre_parse_sanity_check:
            return True

        if len(raw_packet) < 20:
            self.logger.critical(
                f"{self.tracker} - IPv4 sanity check fail - wrong packet length (I)"
            )
            return False

        hlen = (raw_packet[0] & 0b00001111) << 2
        plen = struct.unpack("!H", raw_packet[2:4])[0]
        if not 20 <= hlen <= plen == len(raw_packet):
            self.logger.critical(
                f"{self.tracker} - IPv4 sanity check fail - wrong packet length (II)"
            )
            return False

        # Cannot compute checksum earlier because it depends on sanity of hlen field
        if inet_cksum(raw_packet[:hlen]):
            self.logger.critical(
                f"{self.tracker} - IPv4 sanity check fail - wrong packet checksum"
            )
            return False

        index = 20
        while index < hlen:
            if raw_packet[index] == IP4_OPT_EOL:
                break
            if raw_packet[index] == IP4_OPT_NOP:
                index += 1
                if index > hlen:
                    self.logger.critical(
                        f"{self.tracker} - IPv4 sanity check fail - wrong option length (I)"
                    )
                    return False
                continue
            if index + 1 > hlen:
                self.logger.critical(
                    f"{self.tracker} - IPv4 sanity check fail - wrong option length (II)"
                )
                return False
            if raw_packet[index + 1] == 0:
                self.logger.critical(
                    f"{self.tracker} - IPv4 sanity check fail - wrong option length (III)"
                )
                return False
            index += raw_packet[index + 1]
            if index > hlen:
                self.logger.critical(
                    f"{self.tracker} - IPv4 sanity check fail - wrong option length (IV)"
                )
                return False

        return True
Ejemplo n.º 4
0
    def __pre_parse_sanity_check(self, raw_packet, pseudo_header):
        """ Preliminary sanity check to be run on raw TCP packet prior to packet parsing """

        if not config.pre_parse_sanity_check:
            return True

        if inet_cksum(pseudo_header + raw_packet):
            self.logger.critical(f"{self.tracker} - TCP sanity check fail - wrong packet checksum")
            return False

        if len(raw_packet) < 20:
            self.logger.critical(f"{self.tracker} - TCP sanity check fail - wrong packet length (I)")
            return False

        hlen = (raw_packet[12] & 0b11110000) >> 2
        if not 20 <= hlen <= len(raw_packet):
            self.logger.critical(f"{self.tracker} - TCP sanity check fail - wrong packet length (II)")
            return False

        index = 20
        while index < hlen:
            if raw_packet[index] == TCP_OPT_EOL:
                break
            if raw_packet[index] == TCP_OPT_NOP:
                index += 1
                if index > hlen:
                    self.logger.critical(f"{self.tracker} - TCP sanity check fail - wrong option length (I)")
                    return False
                continue
            if index + 1 > hlen:
                self.logger.critical(f"{self.tracker} - TCP sanity check fail - wrong option length (II)")
                return False
            if raw_packet[index + 1] == 0:
                self.logger.critical(f"{self.tracker} - TCP sanity check fail - wrong option length (III)")
                return False
            index += raw_packet[index + 1]
            if index > hlen:
                self.logger.critical(f"{self.tracker} - TCP sanity check fail - wrong option length (IV)")
                return False

        return True
Ejemplo n.º 5
0
    def __pre_parse_sanity_check(self, raw_packet):
        """ Preliminary sanity check to be run on raw ICMPv4 packet prior to packet parsing """

        if not config.pre_parse_sanity_check:
            return True

        if inet_cksum(raw_packet):
            self.logger.critical(
                f"{self.tracker} - ICMPv4 sanity check fail - wrong packet checksum"
            )
            return False

        if len(raw_packet) < 4:
            self.logger.critical(
                f"{self.tracker} - ICMPv4 sanity check fail - wrong packet length (I)"
            )
            return False

        if raw_packet[0] == ICMP4_ECHOREPLY:
            if len(raw_packet) < 8:
                self.logger.critical(
                    f"{self.tracker} - ICMPv6 sanity check fail - wrong packet length (II)"
                )
                return False

        elif raw_packet[0] == ICMP4_UNREACHABLE:
            if len(raw_packet) < 12:
                self.logger.critical(
                    f"{self.tracker} - ICMPv6 sanity check fail - wrong packet length (II)"
                )
                return False

        elif raw_packet[0] == ICMP4_ECHOREQUEST:
            if len(raw_packet) < 8:
                self.logger.critical(
                    f"{self.tracker} - ICMPv6 sanity check fail - wrong packet length (II)"
                )
                return False

        return True
Ejemplo n.º 6
0
def handle_ip4_fragmentation(ip4_packet_rx):
    """ Check if packet is fragmented """

    # Check if IP packet is a first fragment
    if ip4_packet_rx.ip4_frag_offset == 0 and ip4_packet_rx.ip4_flag_mf:
        ip4_fragments[ip4_packet_rx.ip4_packet_id] = {}
        ip4_fragments[ip4_packet_rx.ip4_packet_id][
            ip4_packet_rx.ip4_frag_offset] = ip4_packet_rx.raw_data
        return None

    # Check if IP packet is one of middle fragments
    if ip4_packet_rx.ip4_frag_offset != 0 and ip4_packet_rx.ip4_flag_mf:
        # Check if packet is part of existing fagment flow
        if ip4_fragments.get(ip4_packet_rx.ip4_packet_id, None):
            ip4_fragments[ip4_packet_rx.ip4_packet_id][
                ip4_packet_rx.ip4_frag_offset] = ip4_packet_rx.raw_data
        return None

    # Check if IP packet is last fragment
    if ip4_packet_rx.ip4_frag_offset != 0 and not ip4_packet_rx.ip4_flag_mf:

        # Check if packet is part of existing fagment flow
        if ip4_fragments.get(ip4_packet_rx.ip4_packet_id, None):
            ip4_fragments[ip4_packet_rx.ip4_packet_id][
                ip4_packet_rx.ip4_frag_offset] = ip4_packet_rx.raw_data

            raw_data = b""
            for offset in sorted(ip4_fragments[ip4_packet_rx.ip4_packet_id]):
                raw_data += ip4_fragments[ip4_packet_rx.ip4_packet_id][offset]

            # Craft complete IP packet based on last fragment for further processing
            ip4_packet_rx.ip4_flag_mf = False
            ip4_packet_rx.ip4_frag_offset = 0
            ip4_packet_rx.ip4_plen = ip4_packet_rx.ip4_hlen + len(raw_data)
            ip4_packet_rx.ip4_cksum = 0
            ip4_packet_rx.ip4_cksum = inet_cksum(ip4_packet_rx.raw_header)
            ip4_packet_rx.raw_data = raw_data

    return ip4_packet_rx
Ejemplo n.º 7
0
    def get_raw_packet(self, ip_pseudo_header):
        """ Get packet in raw format ready to be processed by lower level protocol """

        self.udp_cksum = inet_cksum(ip_pseudo_header + self.raw_packet)

        return self.raw_packet
Ejemplo n.º 8
0
    def validate_cksum(self, ip_pseudo_header):
        """ Validate packet checksum """

        return not bool(inet_cksum(ip_pseudo_header + self.raw_packet))
Ejemplo n.º 9
0
    def validate_cksum(self):
        """ Validate packet checksum """

        return not bool(inet_cksum(self.raw_packet))
Ejemplo n.º 10
0
    def get_raw_packet(self):
        """ Get packet in raw format ready to be processed by lower level protocol """

        self.icmp4_cksum = inet_cksum(self.raw_packet)

        return self.raw_packet
Ejemplo n.º 11
0
    def validate_cksum(self):
        """ Validate packet checksum """

        return not bool(inet_cksum(self.raw_header + self.raw_options))