Esempio n. 1
0
class ICMPHeader(Header, PayloadMixin):
    header_len = 4

    @property
    def type(self):
        """
        The ICMP message type.
        """
        return i(self.raw[0])

    @type.setter
    def type(self, val):
        self.raw[0] = i(val)

    @property
    def code(self):
        """
        The ICMP message code.
        """
        return i(self.raw[1])

    @code.setter
    def code(self, val):
        self.raw[1] = i(val)

    cksum = raw_property('!H', 2, docs='The ICMP header checksum field.')
Esempio n. 2
0
class UDPHeader(PseudoCksumHeaderMixin, PayloadMixin, PortMixin):
    header_len = 8

    @property
    def payload(self):
        return PayloadMixin.payload.fget(self)

    @payload.setter
    def payload(self, val):
        PayloadMixin.payload.fset(self, val)
        self.payload_len = len(val)

    if not PY2 and not PY34:
        payload.__doc__ = PayloadMixin.payload.__doc__

    @property
    def payload_len(self):
        return struct.unpack_from("!H", self.raw, 4)[0] - 8

    @payload_len.setter
    def payload_len(self, val):
        self.raw[4:6] = struct.pack("!H", val + 8)

    cksum = raw_property('!H', 6, docs='The UDP header checksum field.')
Esempio n. 3
0
class IPv4Header(IPHeader, PseudoCksumHeaderMixin):
    _src_addr = slice(12, 16)
    _dst_addr = slice(16, 20)
    _af = socket.AF_INET

    @property
    def header_len(self):
        """
        The IP header length in bytes.
        """
        return self.hdr_len * 4

    @property
    def hdr_len(self):
        """
        The header length in words of 32bit.
        """
        return i(self.raw[0]) & 0x0F

    @hdr_len.setter
    def hdr_len(self, val):
        if val < 5:
            raise ValueError("IP header length must be greater or equal than 5.")
        struct.pack_into('!B', self.raw, 0, 0x40 | val)

    packet_len = raw_property('!H', 2, docs=IPHeader.packet_len.__doc__)
    tos = raw_property('!B', 1, docs='The Type Of Service field (six-bit DiffServ field and a two-bit ECN field).')
    ident = raw_property('!H', 4, docs='The Identification field.')

    reserved = flag_property('reserved', 6, 0b10000000)
    evil = flag_property('evil', 6, 0b10000000, docs='Just an april\'s fool joke for the RESERVED flag.')
    df = flag_property('df', 6, 0b01000000)
    mf = flag_property('mf', 6, 0b00100000)

    ttl = raw_property('!B', 8, docs='The Time To Live field.')
    protocol = raw_property('!B', 9, docs='The Protocol field.')
    cksum = raw_property('!H', 10, docs='The IP header Checksum field.')

    @property
    def flags(self):
        """
        The flags field: RESERVED (the evil bit), DF (don't fragment), MF (more fragments).
        """
        return i(self.raw[6]) >> 5

    @flags.setter
    def flags(self, val):
        struct.pack_into('!B', self.raw, 6, (val << 5) | (self.frag_offset & 0xFF00))

    @property
    def frag_offset(self):
        """
        The Fragment Offset field in blocks of 8 bytes.
        """
        return struct.unpack_from("!H", self.raw, 6)[0] & 0x1FFF

    @frag_offset.setter
    def frag_offset(self, val):
        self.raw[6:8] = struct.pack("!H", (self.flags << 13) | (val & 0x1FFF))

    @property
    def dscp(self):
        """
        The Differentiated Services Code Point field (originally defined as Type of Service) also known as DiffServ.
        """
        return (i(self.raw[1]) >> 2) & 0x3F

    @dscp.setter
    def dscp(self, val):
        struct.pack_into('!B', self.raw, 1, (val << 2) | self.ecn)

    diff_serv = dscp

    @property
    def ecn(self):
        """
        The Explicit Congestion Notification field.
        """
        return i(self.raw[1]) & 0x03

    @ecn.setter
    def ecn(self, val):
        struct.pack_into('!B', self.raw, 1, (self.dscp << 2) | (val & 0x03))
Esempio n. 4
0
class IPv6Header(IPHeader):
    _src_addr = slice(8, 24)
    _dst_addr = slice(24, 40)
    _af = socket.AF_INET6
    header_len = 40

    payload_len = raw_property('!H', 4, docs='The Payload Length field.')
    next_hdr = raw_property('!B', 6, docs='The Next Header field. Replaces the Protocol field in IPv4.')
    hop_limit = raw_property('!B', 7, docs='The Hop Limit field. Replaces the TTL field in IPv4.')

    @property
    def packet_len(self):
        return self.payload_len + self.header_len

    @packet_len.setter
    def packet_len(self, val):
        self.payload_len = val - self.header_len

    @property
    def traffic_class(self):
        """
        The Traffic Class field (six-bit DiffServ field and a two-bit ECN field).
        """
        return (struct.unpack_from('!H', self.raw, 0)[0] >> 4) & 0x00FF

    @traffic_class.setter
    def traffic_class(self, val):
        struct.pack_into('!H', self.raw, 0, 0x6000 | (val << 4) | (self.flow_label & 0x000F0000))

    @property
    def flow_label(self):
        """
        The Flow Label field.
        """
        return struct.unpack_from('!I', self.raw, 0)[0] & 0x000FFFFF

    @flow_label.setter
    def flow_label(self, val):
        struct.pack_into('!I', self.raw, 0, 0x60000000 | (self.traffic_class << 20) | (val & 0x000FFFFF))

    @property
    def diff_serv(self):
        """
        The DiffServ field.
        """
        return (self.traffic_class & 0xFC) >> 2

    @diff_serv.setter
    def diff_serv(self, val):
        self.traffic_class = self.ecn | (val << 2)

    @property
    def ecn(self):
        """
        The Explicit Congestion Notification field.
        """
        return self.traffic_class & 0x03

    @ecn.setter
    def ecn(self, val):
        self.traffic_class = (self.diff_serv << 2) | val

    if not PY2 and not PY34:
        packet_len.__doc__ = IPHeader.packet_len.__doc__
Esempio n. 5
0
class TCPHeader(PseudoCksumHeaderMixin, PayloadMixin, PortMixin):
    ns = flag_property("ns", 12, 0b00000001)

    cwr = flag_property("cwr", 13, 0b10000000)
    ece = flag_property("ece", 13, 0b01000000)

    urg = flag_property("syn", 13, 0b00100000)
    ack = flag_property("ack", 13, 0b00010000)
    psh = flag_property("psh", 13, 0b00001000)
    rst = flag_property("rst", 13, 0b00000100)
    syn = flag_property("syn", 13, 0b00000010)
    fin = flag_property("fin", 13, 0b00000001)

    @property
    def header_len(self):
        """
        The TCP header length.
        """
        return self.data_offset * 4

    seq_num = raw_property('!I', 4, docs='The sequence number field.')
    ack_num = raw_property('!I', 8, docs='The acknowledgement number field.')

    window_size = raw_property('!H',
                               14,
                               docs='The size of the receive window in bytes.')
    cksum = raw_property('!H', 16, docs='The TCP header checksum field.')
    urg_ptr = raw_property('!H', 18, docs='The Urgent Pointer field.')

    @property
    def data_offset(self):
        """
        The size of TCP header in 32bit words.
        """
        return i(self.raw[12]) >> 4

    @data_offset.setter
    def data_offset(self, val):
        if val < 5 or val > 15:
            raise ValueError(
                "TCP data offset must be greater or equal than 5 and less than 15."
            )
        struct.pack_into('!B', self.raw, 12,
                         (val << 4) | (self.reserved << 1) | self.ns)

    @property
    def reserved(self):
        """
        The reserved field.
        """
        return (i(self.raw[12]) >> 1) & 0x07

    @reserved.setter
    def reserved(self, val):
        struct.pack_into('!B', self.raw, 12,
                         (self.data_offset << 4) | (val << 1) | self.ns)

    @property
    def control_bits(self):
        """
        The Control Bits field.
        """
        return struct.unpack_from('!H', self.raw, 12)[0] & 0x01FF

    @control_bits.setter
    def control_bits(self, val):
        struct.pack_into('!H', self.raw, 12, (self.data_offset << 12) |
                         (self.reserved << 9) | (val & 0x01FF))