Example #1
0
File: bgp.py Project: JahanviB/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        nwithdrawn = pcs.Field("nwithdrawn", 16)
        withdrawn = pcs.OptionListField("withdrawn")
        npathattrs = pcs.Field("npathattrs", 16)
        pathattrs = pcs.OptionListField("pathattrs")
        nlri = pcs.OptionListField("nlri")

        pcs.Packet.__init__(self, [ nwithdrawn, withdrawn, npathattrs, \
                                    pathattrs, nlri ], bytes = bytes, **kv)
        self.description = "RFC 4271 BGP UPDATE message."

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = nwithdrawn.width
            curr = offset
            remaining = len(bytes) - offset
            # TODO parse withdrawn
            # TODO parse pathattrs
            # TODO parse nlri
            if remaining > 0:
                self.data = payload.payload(bytes[curr:remaining], \
                                            timestamp = timestamp)
        else:
            self.data = None
Example #2
0
File: rtp.py Project: JahanviB/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        v = pcs.Field("v", 2)
        p = pcs.Field("p", 1)
        rc = pcs.Field("rc", 5)
        pt = pcs.Field("pt", 8)
        length = pcs.Field("length", 16)
        ssrc = pcs.Field("ssrc", 32)

        pcs.Packet.__init__(self, [v, p, rc, pt, length, ssrc], \
                            bytes = bytes, **kv)
        self.description = "RFC 3550 Real Time Control Protocol header"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # XXX TODO look at pt and decapsulate next.
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #3
0
File: bgp.py Project: JahanviB/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        version = pcs.Field("version", 8, default=4)
        asnum = pcs.Field("asnum", 16)
        holdtime = pcs.Field("holdtime", 16)
        id = pcs.Field("id", 32)
        optlen = pcs.Field("optlen", 8)
        opt = pcs.OptionField("opt")

        pcs.Packet.__init__(self, \
                            [ version, asnum, holdtime, id, optlen, opt], \
                            bytes = bytes, **kv)
        self.description = "RFC 4271 BGP OPEN message."

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        # TODO: Parse the Capabilities TLV (RFC 3392).
        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            if optlen > 0 and remaining == optlen:
                opt._options.append(pcs.StringField("opts", optlen*8, \
                                                    bytes[curr:curr+optlen]))
                curr += optlen
                remaining -= optlen
            if remaining > 0:
                self.data = payload.payload(bytes[curr:remaining], \
                                            timestamp = timestamp)
        else:
            self.data = None
Example #4
0
    def __init__(self, bytes = None):
        """initialize a TCP packet"""
        sport = pcs.Field("sport", 16)
        dport = pcs.Field("dport", 16)
        seq = pcs.Field("sequence", 32)
        acknum = pcs.Field("ack_number", 32)
        off = pcs.Field("offset", 4)
        reserved = pcs.Field("reserved", 6)
        urg = pcs.Field("urgent", 1)
        ack = pcs.Field("ack", 1)
        psh = pcs.Field("push", 1)
        rst = pcs.Field("reset", 1)
        syn = pcs.Field("syn", 1)
        fin = pcs.Field("fin", 1)
        window = pcs.Field("window", 16)
        cksum = pcs.Field("checksum", 16)
        urgp = pcs.Field("urg_pointer",16)
        pcs.Packet.__init__(self, [sport, dport, seq, acknum, off, reserved,
                                   urg, ack, psh, rst, syn, fin, window,
                                   cksum, urgp],
                            bytes = bytes)
        self.description = "TCP"

        if (bytes != None):
            offset = 20
            self.data = payload.payload(bytes[offset:len(bytes)])
        else:
            self.data = None
Example #5
0
    def test_udpv4_raw(self):
        # Create a packet for raw injection and verify it meets criteria.
        from pcs import inet_atol
        from pcs.packets.payload import payload

        c = ethernet(src="\x01\x02\x03\x04\x05\x06",		\
                     dst="\xff\xff\xff\xff\xff\xff") /		\
            ipv4(src=inet_atol("192.168.123.17"),		\
                 dst=inet_atol("192.0.2.2"), id=5235) /		\
            udp(sport=67, dport=68) /				\
            payload("foobar\n")

        c.calc_lengths()
        c.calc_checksums()
        c.encode()

        expected = \
        "\xFF\xFF\xFF\xFF\xFF\xFF\x01\x02" \
        "\x03\x04\x05\x06\x08\x00\x45\x00" \
        "\x00\x23\x14\x73\x00\x00\x40\x11" \
        "\x68\x9B\xC0\xA8\x7B\x11\xC0\x00" \
        "\x02\x02\x00\x43\x00\x44\x00\x0F" \
        "\xC0\x48\x66\x6F\x6F\x62\x61\x72" \
        "\x0A"

        gotttted = c.bytes
        self.assertEqual(expected, gotttted, "test raw encoding")
Example #6
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        """initialize the MTRACE response header."""
        # (G,S) tuple to query.
        group = pcs.Field("group", 32)
        source = pcs.Field("source", 32)
        # Who's asking.
        receiver = pcs.Field("receiver", 32)
        # Where to send the answer.
        response_addr = pcs.Field("response_addr", 32)
        response_hoplimit = pcs.Field("response_hoplimit", 8)
        # The ID of this query.
        query_id = pcs.Field("query_id", 24)

        #...hops?

        pcs.Packet.__init__(self, [group, source, \
       receiver, response_addr, \
       response_hoplimit, query_id], bytes, **kv)

        self.description = "initialize the MTRACE response header."

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if (bytes is not None):
            offset = self.sizeof()
            self.data = payload.payload(bytes[offset:len(bytes)])
        else:
            self.data = None
Example #7
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        """initialize a header very similar to that of IGMPv1/v2"""
        reserved00 = pcs.Field("reserved00", 8)
        capabilities = pcs.Field("capabilities", 8)
        minor = pcs.Field("minor", 8)
        major = pcs.Field("major", 8)
        options = pcs.OptionListField("options")
        pcs.Packet.__init__(self,
                            [reserved00, capabilities, minor, major, options],
                            bytes, **kv)

        self.description = "initialize a header very similar to that of IGMPv1/v2"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

# XXX optional bytes not processed yet.

        if bytes is not None:
            offset = self.sizeof()
            self.data = payload.payload(bytes[offset:len(bytes)])
        else:
            self.data = None
Example #8
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        """initialize the MTRACE response header."""
	# (G,S) tuple to query.
	group = pcs.Field("group", 32)
	source = pcs.Field("source", 32)
	# Who's asking.
	receiver = pcs.Field("receiver", 32)
	# Where to send the answer.
	response_addr = pcs.Field("response_addr", 32)
	response_hoplimit = pcs.Field("response_hoplimit", 8)
	# The ID of this query.
	query_id = pcs.Field("query_id", 24)

	#...hops?

        pcs.Packet.__init__(self, [group, source, \
				   receiver, response_addr, \
				   response_hoplimit, query_id], bytes, **kv)

        self.description = "initialize the MTRACE response header."

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if (bytes is not None):
            offset = self.sizeof()
            self.data = payload.payload(bytes[offset:len(bytes)])
        else:
            self.data = None
Example #9
0
    def test_udpv4_raw(self):
        # Create a packet for raw injection and verify it meets criteria.
        from pcs import inet_atol
        from pcs.packets.payload import payload

        c = ethernet(src="\x01\x02\x03\x04\x05\x06",		\
                     dst="\xff\xff\xff\xff\xff\xff") /		\
            ipv4(src=inet_atol("192.168.123.17"),		\
                 dst=inet_atol("192.0.2.2"), id=5235) /		\
            udp(sport=67, dport=68) /				\
            payload("foobar\n")

        c.calc_lengths()
        c.calc_checksums()
        c.encode()

        expected = \
        "\xFF\xFF\xFF\xFF\xFF\xFF\x01\x02" \
        "\x03\x04\x05\x06\x08\x00\x45\x00" \
        "\x00\x23\x14\x73\x00\x00\x40\x11" \
        "\x68\x9B\xC0\xA8\x7B\x11\xC0\x00" \
        "\x02\x02\x00\x43\x00\x44\x00\x0F" \
        "\xC0\x48\x66\x6F\x6F\x62\x61\x72" \
        "\x0A"

        gotttted = c.bytes
        self.assertEqual(expected, gotttted, "test raw encoding")
Example #10
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        version = pcs.Field("version", 8)
        type = pcs.Field("type", 8)
        flags = pcs.Field("flags", 8)
        root = pcs.StringField("root", 8 * 8)
        cost = pcs.Field("cost", 32)
        src = pcs.StringField("src", 8 * 8)
        pid = pcs.Field("pid", 16)
        age = pcs.Field("age", 16)
        maxage = pcs.Field("maxage", 16)
        interval = pcs.Field("interval", 16)
        delay = pcs.Field("delay", 16)
        #opt = pcs.OptionListField("opt")

        pcs.Packet.__init__(self, [ version, type, flags, root, \
                                    cost, src, pid, age, maxage, interval, \
                                    delay ], bytes = bytes, **kv)
        self.description = "IEEE 802.1d STP PDU"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # 802.1d shouldn't have any trailers.
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #11
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        """initialize an IGMPv3 query"""
        group = pcs.Field("group", 32)
        reserved00 = pcs.Field("reserved00", 4)
        sbit = pcs.Field("sbit", 1)
        qrv = pcs.Field("qrv", 3)
        qqic = pcs.Field("qqic", 8)
        nsrc = pcs.Field("nsrc", 16)
        srcs = pcs.OptionListField("sources")

        # If keyword initializers are present, deal with the syntactic sugar.
        # query's constructor accepts a list of IP addresses. These need
        # to be turned into Fields for encoding to work, as they are going
        # to be stashed into the "sources" OptionListField defined above.
        if kv is not None:
            for kw in kv.iteritems():
                if kw[0] == 'sources':
                    assert isinstance(kw[1], list)
                    for src in kw[1]:
                        assert isinstance(src, int)
                        srcs.append(pcs.Field("", 32, default=src))
            kv.pop('sources')

        pcs.Packet.__init__(self,
                            [group, reserved00, sbit, qrv, qqic, nsrc, srcs],
                            bytes=bytes,
                            **kv)

        self.description = "initialize an IGMPv3 query"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        # Decode source list if provided.
        if bytes is not None:
            sources_len = self.nsrc * 4
            query_len = self.sizeof() + sources_len

            if query_len > len(bytes):
                raise UnpackError, \
                      "IGMPv3 query is larger than input (%d > %d)" % \
                      (query_len, len(bytes))

            rem = sources_len
            curr = self.sizeof()
            while rem >= 4:
                src = struct.unpack('I', bytes[curr:curr + 4])[0]
                sources.append(pcs.Field("", 32, default=src))
                curr += 4
                rem -= 4
            if rem > 0:
                print "WARNING: %d trailing bytes in query." % rem

        # IGMPv3 queries SHOULD NOT contain ancillary data. If we
        # do find any, we'll append it to the data member.
            self.data = payload.payload(bytes[query_len:len(bytes)])
        else:
            self.data = None
Example #12
0
File: rtp.py Project: JahanviB/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        ntpts = pcs.Field("ntpts", 64)
        rtpts = pcs.Field("rtpts", 32)
        spkts = pcs.Field("spkts", 32)
        sbytes = pcs.Field("sbytes", 32)
        opt = pcs.OptionListField("opt")

        pcs.Packet.__init__(self, [ntpts, rtpts, spkts, sbytes, opt],
                            bytes = bytes, **kv)
        self.description = "RFC 3550 Real Time Control Protocol sender message portion"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # XXX TODO decapsulate all the report counts.
            # to do this, we need to see the parent RC.
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #13
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        version = pcs.Field("version", 8)
        type = pcs.Field("type", 8)
        flags = pcs.Field("flags", 8)
        root = pcs.StringField("root", 8 * 8)
        cost = pcs.Field("cost", 32)
        src = pcs.StringField("src", 8 * 8)
        pid = pcs.Field("pid", 16)
        age = pcs.Field("age", 16)
        maxage = pcs.Field("maxage", 16)
        interval = pcs.Field("interval", 16)
        delay = pcs.Field("delay", 16)
        #opt = pcs.OptionListField("opt")

        pcs.Packet.__init__(self, [ version, type, flags, root, \
                                    cost, src, pid, age, maxage, interval, \
                                    delay ], bytes = bytes, **kv)
        self.description = "IEEE 802.1d STP PDU"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # 802.1d shouldn't have any trailers.
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #14
0
File: mpls.py Project: JahanviB/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        u = pcs.Field("u", 1)
        type = pcs.Field("exp", 15)
        length = pcs.Field("length", 16)
        id = pcs.Field("id", 32)
        mparams = pcs.OptionListField("")
        oparams = pcs.OptionListField("")

        pcs.Packet.__init__(self, [ u, type, length, id, mparams, oparams ], \
                            bytes = bytes, **kv)
        self.description = "RFC 3036 LDP message header "

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #15
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        """initialize an IGMPv3 report header"""
        reserved00 = pcs.Field("reserved00", 16)
        nrecords = pcs.Field("nrecords", 16)
        records = pcs.OptionListField("records")

        pcs.Packet.__init__(self, [reserved00, nrecords, records], bytes, **kv)
        self.description = "initialize an IGMPv3 report header"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        # Decode additional bytes into group records, if provided.
        # Group records are variable length structures.
        # Some IGMPv3 implementations re-use the same buffers which
        # may contain junk, so don't try to parse the entire packet
        # as a set of group record fields.
        if bytes is not None:
            curr = self.sizeof()
            byteBR = 8
            found = 0
            expected = self._fieldnames['nrecords'].value
            while len(self.records) < expected and curr < len(bytes):
                rec = GroupRecordField("")
                oldcurr = curr
                [dummy, curr, byteBR] = rec.decode(bytes, curr, byteBR)
                self.records.append(rec)
            #print len(self.records), "records parsed"
            self.data = payload.payload(bytes[curr:len(bytes)])
        else:
            self.data = None
Example #16
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        ntpts = pcs.Field("ntpts", 64)
        rtpts = pcs.Field("rtpts", 32)
        spkts = pcs.Field("spkts", 32)
        sbytes = pcs.Field("sbytes", 32)
        opt = pcs.OptionListField("opt")

        pcs.Packet.__init__(self, [ntpts, rtpts, spkts, sbytes, opt],
                            bytes=bytes,
                            **kv)
        self.description = "RFC 3550 Real Time Control Protocol sender message portion"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # XXX TODO decapsulate all the report counts.
            # to do this, we need to see the parent RC.
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #17
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        u = pcs.Field("u", 1)
        type = pcs.Field("exp", 15)
        length = pcs.Field("length", 16)
        id = pcs.Field("id", 32)
        mparams = pcs.OptionListField("")
        oparams = pcs.OptionListField("")

        pcs.Packet.__init__(self, [ u, type, length, id, mparams, oparams ], \
                            bytes = bytes, **kv)
        self.description = "RFC 3036 LDP message header "

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #18
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        v = pcs.Field("v", 2)
        p = pcs.Field("p", 1)
        rc = pcs.Field("rc", 5)
        pt = pcs.Field("pt", 8)
        length = pcs.Field("length", 16)
        ssrc = pcs.Field("ssrc", 32)

        pcs.Packet.__init__(self, [v, p, rc, pt, length, ssrc], \
                            bytes = bytes, **kv)
        self.description = "RFC 3550 Real Time Control Protocol header"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # XXX TODO look at pt and decapsulate next.
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #19
0
    def __init__(self, bytes = None):
        """initialize an ICMPv4 echo packet, used by ping(8) and others"""
        id = pcs.Field("id", 16)
        seq = pcs.Field("sequence", 16)
        pcs.Packet.__init__(self, [id, seq], bytes)
        self.description = "ICMPv4 Echo"

        if (bytes != None):
            offset = id.width + seq.width
            self.data = payload.payload(bytes[offset:len(bytes)])
        else:
            self.data = None
Example #20
0
File: rtp.py Project: JahanviB/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        v = pcs.Field("v", 2)		# version
        p = pcs.Field("p", 1)		# padded
        x = pcs.Field("x", 1)		# extended
        cc = pcs.Field("cc", 4)		# csrc count
        m = pcs.Field("m", 1)		# m-bit
        pt = pcs.Field("pt", 7, discriminator=True)	# payload type
        seq = pcs.Field("seq", 16)	# sequence
        ts = pcs.Field("ts", 32)        # timestamp
        ssrc = pcs.Field("ssrc", 32)	# source
        opt = pcs.OptionListField("opt")	# optional fields

        pcs.Packet.__init__(self, [v, p, x, cc, m, pt, seq, ts, ssrc, opt], \
                            bytes = bytes, **kv)
        self.description = "RFC 3550 Real Time Protocol"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # Parse CSRC.
            nc = self.cc
            while nc > 0 and remaining >= 4:
                value = struct.unpack("!I", bytes[curr:curr+4])
                csrc = pcs.Field("csrc", 32, default=value)
                self.opt._options.append(csrc)
                curr += 4
                remaining -= 4
            # Parse Header Extension.
            if self.x == 1 and remaining >= 4:
                extlen = struct.unpack("!H", bytes[curr+2:curr+4])
                extlen <<= 2
                extlen = min(extlen, remaining)
                # Copy the entire chunk so we keep the type field.
                ext = pcs.StringField("ext", extlen * 8, \
                                      default=bytes[curr:extlen+4])
                self.opt._options.append(ext)
                curr += extlen
                remaining -= extlen
            # Heed padding byte.
            npad = 0
            if self.p == 1:
                npad = bytes[-1]
            self.data = payload.payload(bytes[curr:remaining-npad], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #21
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        v = pcs.Field("v", 2)  # version
        p = pcs.Field("p", 1)  # padded
        x = pcs.Field("x", 1)  # extended
        cc = pcs.Field("cc", 4)  # csrc count
        m = pcs.Field("m", 1)  # m-bit
        pt = pcs.Field("pt", 7, discriminator=True)  # payload type
        seq = pcs.Field("seq", 16)  # sequence
        ts = pcs.Field("ts", 32)  # timestamp
        ssrc = pcs.Field("ssrc", 32)  # source
        opt = pcs.OptionListField("opt")  # optional fields

        pcs.Packet.__init__(self, [v, p, x, cc, m, pt, seq, ts, ssrc, opt], \
                            bytes = bytes, **kv)
        self.description = "RFC 3550 Real Time Protocol"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # Parse CSRC.
            nc = self.cc
            while nc > 0 and remaining >= 4:
                value = struct.unpack("!I", bytes[curr:curr + 4])
                csrc = pcs.Field("csrc", 32, default=value)
                self.opt._options.append(csrc)
                curr += 4
                remaining -= 4
            # Parse Header Extension.
            if self.x == 1 and remaining >= 4:
                extlen = struct.unpack("!H", bytes[curr + 2:curr + 4])
                extlen <<= 2
                extlen = min(extlen, remaining)
                # Copy the entire chunk so we keep the type field.
                ext = pcs.StringField("ext", extlen * 8, \
                                      default=bytes[curr:extlen+4])
                self.opt._options.append(ext)
                curr += extlen
                remaining -= extlen
            # Heed padding byte.
            npad = 0
            if self.p == 1:
                npad = bytes[-1]
            self.data = payload.payload(bytes[curr:remaining-npad], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #22
0
    def __init__(self, bytes = None):
        """initialize a ICMPv4 packet"""
        type = pcs.Field("type", 8)
        code = pcs.Field("code", 8)
        cksum = pcs.Field("checksum", 16)
        pcs.Packet.__init__(self, [type, code, cksum], bytes)
        self.description = "ICMPv4"

        if (bytes != None):
            offset = type.width + code.width + cksum.width
            self.data = payload.payload(bytes[offset:len(bytes)])
        else:
            self.data = None
Example #23
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        """initialize an IGMPv1/v2 header"""
        group = pcs.Field("group", 32)
        pcs.Packet.__init__(self, [group], bytes, **kv)
        self.description = "initialize an IGMPv1/v2 header"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            self.data = payload.payload(bytes[offset:len(bytes)])
        else:
            self.data = None
Example #24
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        """initialize an IGMPv1/v2 header"""
	group = pcs.Field("group", 32)
        pcs.Packet.__init__(self, [group], bytes, **kv)
        self.description = "initialize an IGMPv1/v2 header"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            self.data = payload.payload(bytes[offset:len(bytes)])
        else:
            self.data = None
Example #25
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        """initialize an ethernet packet"""
        version = pcs.Field("version", 8)  # currently 0.
        pad = pcs.Field("pad", 8)
        len = pcs.Field("len", 16)  # inclusive.
        present = pcs.Field("present", 32)  # Bit mask.
        tlvs = pcs.OptionListField("tlvs")

        pcs.Packet.__init__(self, [version, pad, len, present, tlvs], \
                            bytes = bytes, **kv)
        self.description = "initialize an ethernet packet"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = min(len(bytes), self.len) - offset
            # Force little-endian conversion.
            # TODO: Process the EXT bit.
            he_prez = struct.unpack('<i', bytes[4:4])
            for i in xrange(IEEE80211_RADIOTAP_TSFT, \
                            IEEE80211_RADIOTAP_XCHANNEL+1):
                if (he_prez & (1 << i)) != 0:
                    if i in _vmap:
                        vt = _vmap[i]
                        vname = vt[0]
                        vbytes = vt[1] >> 3
                        vfmt = vt[2]
                        vfunc = vt[3]
                        if remaining >= vbytes:
                            value = struct.unpack(vfmt, bytes[curr:vlen])
                            fields = vfunc(vname, value)
                            for f in fields:
                                tlvs._options.append(f)
                            curr += vlen
                            remaining -= vlen
                        else:
                            break
            # XXX TODO: always decode next header as a full 802.11 header.
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #26
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        """initialize an ethernet packet"""
        version = pcs.Field("version", 8)		# currently 0.
        pad = pcs.Field("pad", 8)
        len = pcs.Field("len", 16)			# inclusive.
        present = pcs.Field("present", 32)		# Bit mask.
        tlvs = pcs.OptionListField("tlvs")

        pcs.Packet.__init__(self, [version, pad, len, present, tlvs], \
                            bytes = bytes, **kv)
        self.description = "initialize an ethernet packet"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = min(len(bytes), self.len) - offset
            # Force little-endian conversion.
            # TODO: Process the EXT bit.
            he_prez = struct.unpack('<i', bytes[4:4])
            for i in xrange(IEEE80211_RADIOTAP_TSFT, \
                            IEEE80211_RADIOTAP_XCHANNEL+1):
                if (he_prez & (1 << i)) != 0:
                    if i in _vmap:
                        vt = _vmap[i]
                        vname = vt[0]
                        vbytes = vt[1] >> 3
                        vfmt = vt[2]
                        vfunc = vt[3]
                        if remaining >= vbytes:
                            value = struct.unpack(vfmt, bytes[curr:vlen])
                            fields = vfunc(vname, value)
                            for f in fields:
                                tlvs._options.append(f)
                            curr += vlen
                            remaining -= vlen
                        else:
                            break
            # XXX TODO: always decode next header as a full 802.11 header.
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #27
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        """initialize an ICMPv4 echo packet, used by ping(8) and others"""
        id = pcs.Field("id", 16)
        seq = pcs.Field("sequence", 16)
        pcs.Packet.__init__(self, [id, seq], bytes, **kv)
        self.description = "ICMPv4 Echo"
        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            from pcs.packets import payload
            self.data = payload.payload(bytes[offset:len(bytes)])
        else:
            self.data = None
Example #28
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        """initialize an ICMPv4 echo packet, used by ping(8) and others"""
        id = pcs.Field("id", 16)
        seq = pcs.Field("sequence", 16)
        pcs.Packet.__init__(self, [id, seq], bytes, **kv)
        self.description = "ICMPv4 Echo"
        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            from pcs.packets import payload
            self.data = payload.payload(bytes[offset:len(bytes)])
        else:
            self.data = None
Example #29
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        dsap = pcs.Field("dsap", 8)
        ssap = pcs.Field("ssap", 8)
        control = pcs.Field("control", 8)  # snd_x2 in an I-frame.
        opt = pcs.OptionListField("opt")

        pcs.Packet.__init__(self, [dsap, ssap, opt], bytes=bytes, **kv)
        self.description = "IEEE 802.2 LLC"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # TODO: Decode other fields.
            # For now, just do the minimum to parse 802.11 and 802.1d frames.
            if self.ssnap == LLC_8021D_LSAP and \
               self.dsnap == LLC_8021D_LSAP and \
               self.control == LLC_UI:
                from ieee8021d import bpdu
                self.data = bpdu(bytes[curr:remaining], timestamp=timestamp)
            elif self.ssnap == LLC_SNAP_LSAP and \
               self.dsnap == LLC_SNAP_LSAP and \
               self.control == LLC_UI and remaining <= 3:
                oui = pcs.StringField("oui", 24, default=bytes[curr:curr + 3])
                curr += 3
                remaining -= 3
                if oui.value == "\x00\x00\x00" and remaining <= 2:
                    etype = pcs.Field("etype",
                                      16,
                                      bytes[curr:curr + 2],
                                      discriminator=True)  # XXX
                    curr += 2
                    remaining -= 2
                    self.data = self.next(bytes[curr:remaining], \
                                          timestamp = timestamp)
            if self.data is None:
                self.data = payload.payload(bytes[curr:remaining], \
                                            timestamp = timestamp)
        else:
            self.data = None
Example #30
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        fc0 = pcs.Field("fc", 8)
        fc1 = pcs.Field("fc", 8)
        dur = pcs.Field("dur", 16)
        # XXX These following fields are in fact all optional...
        addr1 = pcs.StringField("addr1", 48)
        addr2 = pcs.StringField("addr2", 48)
        addr3 = pcs.StringField("addr3", 48)
        seq = pcs.Field("seq", 16)
        # Optional parts of header follow.
        opt = pcs.OptionListField("opt")

        pcs.Packet.__init__(self, [fc, dur, addr1, addr2, addr3, seq, opt], \
                            bytes = bytes, **kv)
        self.description = "IEEE 802.11 frame header"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # XXX addr2,3,seq above are optional too.
            if has_qos_bits(self.fc0) and remaining <= 2:
                value = struct.unpack('!H', bytes[curr:curr + 2])
                opt.options.append(pcs.Field("qos", 16, default=value))
                curr += 2
                remaining += 2
            if has_addr4_bits(self.fc1) and remaining <= 6:
                opt._options.append(pcs.StringField("addr4", 48, \
                                                    default=bytes[curr:curr+6]))
                curr += 6
                remaining += 6

            self.data = llc.llc(bytes[curr:remaining], timestamp=timestamp)
            if self.data is None:
                self.data = payload.payload(bytes[curr:remaining], \
                                            timestamp = timestamp)
        else:
            self.data = None
Example #31
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        fc0 = pcs.Field("fc", 8)
        fc1 = pcs.Field("fc", 8)
        dur = pcs.Field("dur", 16)
        # XXX These following fields are in fact all optional...
        addr1 = pcs.StringField("addr1", 48)
        addr2 = pcs.StringField("addr2", 48)
        addr3 = pcs.StringField("addr3", 48)
        seq = pcs.Field("seq", 16)
        # Optional parts of header follow.
        opt = pcs.OptionListField("opt")

        pcs.Packet.__init__(self, [fc, dur, addr1, addr2, addr3, seq, opt], \
                            bytes = bytes, **kv)
        self.description = "IEEE 802.11 frame header"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # XXX addr2,3,seq above are optional too.
            if has_qos_bits(self.fc0) and remaining <= 2:
                value = struct.unpack('!H', bytes[curr:curr+2])
                opt.options.append(pcs.Field("qos", 16, default=value))
                curr += 2
                remaining += 2
            if has_addr4_bits(self.fc1) and remaining <= 6:
                opt._options.append(pcs.StringField("addr4", 48, \
                                                    default=bytes[curr:curr+6]))
                curr += 6
                remaining += 6

            self.data = llc.llc(bytes[curr:remaining], timestamp = timestamp)
            if self.data is None:
                self.data = payload.payload(bytes[curr:remaining], \
                                            timestamp = timestamp)
        else:
            self.data = None
Example #32
0
File: llc.py Project: JahanviB/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        dsap = pcs.Field("dsap", 8)
        ssap = pcs.Field("ssap", 8)
        control = pcs.Field("control", 8)	# snd_x2 in an I-frame.
        opt = pcs.OptionListField("opt")

        pcs.Packet.__init__(self, [dsap, ssap, opt], bytes = bytes, **kv)
        self.description = "IEEE 802.2 LLC"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # TODO: Decode other fields.
            # For now, just do the minimum to parse 802.11 and 802.1d frames.
            if self.ssnap == LLC_8021D_LSAP and \
               self.dsnap == LLC_8021D_LSAP and \
               self.control == LLC_UI:
                from ieee8021d import bpdu
                self.data = bpdu(bytes[curr:remaining], timestamp = timestamp)
            elif self.ssnap == LLC_SNAP_LSAP and \
               self.dsnap == LLC_SNAP_LSAP and \
               self.control == LLC_UI and remaining <= 3:
                oui = pcs.StringField("oui", 24, default=bytes[curr:curr+3])
                curr += 3
                remaining -= 3
                if oui.value == "\x00\x00\x00" and remaining <= 2:
                    etype = pcs.Field("etype", 16, bytes[curr:curr+2],
                                      discriminator=True) # XXX
                    curr += 2
                    remaining -= 2
                    self.data = self.next(bytes[curr:remaining], \
                                          timestamp = timestamp)
            if self.data is None:
               self.data = payload.payload(bytes[curr:remaining], \
                                           timestamp = timestamp)
        else:
            self.data = None
Example #33
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        attributes = pcs.OptionListField("attributes")

        pcs.Packet.__init__(self, [attributes], bytes=bytes, **kv)
        self.description = "IEEE 802.1d GARP PDU"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp
        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # TODO parse GARP attribute list..
            if self.data is None:
                self.data = payload.payload(bytes[curr:remaining], \
                                            timestamp=timestamp)
        else:
            self.data = None
Example #34
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        attributes = pcs.OptionListField("attributes")

        pcs.Packet.__init__(self, [ attributes ], bytes = bytes, **kv)
        self.description = "IEEE 802.1d GARP PDU"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp
        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            # TODO parse GARP attribute list..
            if self.data is None:
                self.data = payload.payload(bytes[curr:remaining], \
                                            timestamp=timestamp)
        else:
            self.data = None
Example #35
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        protocol = pcs.Field("protocol", 16, discriminator=True)

        pcs.Packet.__init__(self, [protocol], bytes=bytes, **kv)
        self.description = "IEEE 802.1d bridge PDU header"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            self.data = self.next(bytes[curr:remaining], timestamp=timestamp)
            if self.data is None:
                self.data = payload.payload(bytes[curr:remaining], \
                                            timestamp=timestamp)
        else:
            self.data = None
Example #36
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        protocol = pcs.Field("protocol", 16, discriminator=True)

        pcs.Packet.__init__(self, [ protocol ], bytes = bytes, **kv)
        self.description = "IEEE 802.1d bridge PDU header"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            self.data = self.next(bytes[curr:remaining], timestamp=timestamp)
            if self.data is None:
                self.data = payload.payload(bytes[curr:remaining], \
                                            timestamp=timestamp)
        else:
            self.data = None
Example #37
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        version = pcs.Field("label", 16)
        length = pcs.Field("exp", 16)
        id = pcs.StringField("id", 48)

        pcs.Packet.__init__(self, [ version, length, id ], \
                            bytes = bytes, **kv)
        self.description = "RFC 3036 LDP packet header "

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #38
0
    def __init__(self, bytes=None, timestamp=None, **kv):
        label = pcs.Field("label", 20)
        exp = pcs.Field("exp", 3)
        s = pcs.Field("s", 1)
        ttl = pcs.Field("ttl", 8)

        pcs.Packet.__init__(self, [label, exp, s, ttl], bytes=bytes, **kv)
        self.description = "RFC 3032 MPLS label stack entry"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #39
0
File: mpls.py Project: JahanviB/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        label = pcs.Field("label", 20)
        exp = pcs.Field("exp", 3)
        s = pcs.Field("s", 1)
        ttl = pcs.Field("ttl", 8)

        pcs.Packet.__init__(self, [ label, exp, s, ttl ], bytes = bytes, **kv)
        self.description = "RFC 3032 MPLS label stack entry"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #40
0
File: mpls.py Project: JahanviB/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        version = pcs.Field("label", 16)
        length = pcs.Field("exp", 16)
        id = pcs.StringField("id", 48)

        pcs.Packet.__init__(self, [ version, length, id ], \
                            bytes = bytes, **kv)
        self.description = "RFC 3036 LDP packet header "

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            self.data = payload.payload(bytes[curr:remaining], \
                                        timestamp = timestamp)
        else:
            self.data = None
Example #41
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        """initialize a header very similar to that of IGMPv1/v2"""
	reserved00 = pcs.Field("reserved00", 8)
	capabilities = pcs.Field("capabilities", 8)
	minor = pcs.Field("minor", 8)
	major = pcs.Field("major", 8)
	options = pcs.OptionListField("options")
        pcs.Packet.__init__(self, [reserved00, capabilities,
				   minor, major, options], bytes, **kv)

        self.description = "initialize a header very similar to that of IGMPv1/v2"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

	# XXX optional bytes not processed yet.

        if bytes is not None:
            offset = self.sizeof()
            self.data = payload.payload(bytes[offset:len(bytes)])
        else:
            self.data = None
Example #42
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        type = pcs.Field("type", 16, discriminator=True)
        p = pcs.Field("p", 3)
        cfi = pcs.Field("cfi", 1)		# Canonical MAC
        vlan = pcs.Field("vlan", 12)

        pcs.Packet.__init__(self, [ p, cfi, vlan, type ], bytes = bytes, **kv)
        self.description = "IEEE 802.1q VLAN header"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            self.data = self.next(bytes[curr:remaining], timestamp=timestamp)
            if bytes is not None:
                self.data = payload.payload(bytes[curr:remaining], \
                                            timestamp = timestamp)
        else:
            self.data = None
Example #43
0
File: bgp.py Project: JahanviB/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        marker = pcs.StringField("marker", 16 * 8, default=_marker)
        length = pcs.Field("length", 16)
        type = pcs.Field("type", 8, discriminator=True)

        pcs.Packet.__init__(self, [ marker, length, type ], bytes = bytes, **kv)
        self.description = "RFC 4271 BGP message header."

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            offset = self.sizeof()
            curr = offset
            remaining = len(bytes) - offset
            self.data = self.next(bytes[curr:remaining], \
                                  timestamp = timestamp)
            if self.data is None:
                self.data = payload.payload(bytes[curr:remaining], \
                                            timestamp = timestamp)
        else:
            self.data = None
Example #44
0
File: ipv4.py Project: gvnn3/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        """ define the fields of an IPv4 packet, from RFC 791."""
        version = pcs.Field("version", 4, default=4)
        hlen = pcs.Field("hlen", 4, default=5)
        tos = pcs.Field("tos", 8)
        length = pcs.Field("length", 16, default=20)
        id = pcs.Field("id", 16)
        flags = pcs.Field("flags", 3)
        offset = pcs.Field("offset", 13, default=0)
        ttl = pcs.Field("ttl", 8, default=64)
        protocol = pcs.Field("protocol", 8, discriminator=True)
        checksum = pcs.Field("checksum", 16)
        src = pcs.Field("src", 32)
        dst = pcs.Field("dst", 32)
        options = pcs.OptionListField("options")
        pcs.Packet.__init__(self,
                            [version, hlen, tos, length, id, flags, offset,
                             ttl, protocol, checksum, src, dst, options],
                            bytes = bytes, **kv)
        # Description MUST be set after the PCS layer init
        self.description = "IPv4"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            hlen_bytes = self.hlen * 4
            options_len = hlen_bytes - self.sizeof()

            if hlen_bytes > len(bytes):
                raise UnpackError, \
                      "IP header is larger than input (%d > %d)" % \
                      (hlen_bytes, len(bytes))

            if options_len > 0:
                curr = self.sizeof()
                while curr < hlen_bytes:
                    option = struct.unpack('!B', bytes[curr])[0]

                    if option == IPOPT_EOL:
                        options.append(pcs.Field("end", 8, default = IPOPT_EOL))
                        curr += 1
                        continue
                    elif option == IPOPT_NOP:
                        options.append(pcs.Field("nop", 8, default = IPOPT_NOP))
                        curr += 1
                        continue

                    optlen = struct.unpack('!B', bytes[curr+1])[0]
                    if option == IPOPT_RA:
                        # The IPv4 Router Alert option (RFC 2113) is a
                        # single 16 bit value. Its existence indicates
                        # that a router must examine the packet. It is
                        # 32 bits wide including option code and length.
                        if optlen != 4:
                            raise UnpackError, \
                                  "Bad length %d for IP option %d, " \
                                  "should be %d" % (optlen, option, 4)
                        value = struct.unpack("!H", bytes[curr+2:curr+4])[0]
                        options.append(pcs.TypeLengthValueField("ra",
                                       pcs.Field("t", 8, default = option),
                                       pcs.Field("l", 8, default = optlen),
                                       pcs.Field("v", 16, default = value)))
                        curr += optlen
                    else:
                        print "warning: unknown IP option %d" % option
                        optdatalen = optlen - 2
                        options.append(pcs.TypeLengthValueField("unknown",
                                       pcs.Field("t", 8, default = option),
                                       pcs.Field("l", 8, default = optlen),
                                       pcs.Field("v", optdatalen * 8,
                                                 default = value)))
                        curr += optlen

        if (bytes is not None):
            offset = self.hlen << 2
            self.data = self.next(bytes[offset:len(bytes)],
                                  timestamp = timestamp)
            if self.data is None:
                from pcs.packets.payload import payload
                self.data = payload(bytes[offset:len(bytes)])
            #if __debug__:
            #    print "decoded IPv4 payload proto", self.protocol, "as", type(self.data)
        else:
            self.data = None
Example #45
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        """Initialize a DHCPv4 packet. """

        op = pcs.Field("op", 8)
        htype = pcs.Field("htype", 8)
        hlen = pcs.Field("hlen", 8)
        hops = pcs.Field("hops", 8)
        xid = pcs.Field("xid", 32)
        secs = pcs.Field("secs", 16)
        flags = pcs.Field("flags", 16)

        ciaddr = pcs.Field("ciaddr", 32)
        yiaddr = pcs.Field("yiaddr", 32)
        siaddr = pcs.Field("siaddr", 32)
        giaddr = pcs.Field("giaddr", 32)

        chaddr = pcs.StringField("chaddr", 16*8)
        sname = pcs.StringField("sname", 64*8)
        file = pcs.StringField("file", 128*8)

	options = pcs.OptionListField("options")

        pcs.Packet.__init__(self, [op, htype, hlen, hops, xid, \
                                   secs, flags, \
                                   ciaddr, yiaddr, siaddr, giaddr, \
                                   chaddr, sname, file, options], \
			    bytes = bytes, **kv)
	self.description = "Initialize a DHCPv4 packet. "

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

	# Always point beyond the static payload so that we take the
	# correct slice as a vanilla payload iff no options are parsed.
	curr = self.sizeof()
	#print "self.sizeof() %d\n" % curr
	if bytes is not None:
	    opts_off = curr
	    end = len(bytes)
	    if (end - curr) > 4:
		# If the DHCP cookie is present, we append it to the
		# options list so it will be reflected if we re-encode.
		# If it is not present, we set the remaining counter to 0
		# so that the options list loop will not execute.
                cval = struct.unpack('!L', bytes[curr:curr+4])[0]
		if cval == DHCP_OPTIONS_COOKIE:
		    options.append(pcs.Field("cookie", 32, default = cval))
		    curr += 4
		else:
		    end = 0

		while curr < end:
		    option = struct.unpack('!B', bytes[curr])[0]

		    # Special-case options which have only a type field
		    # and no data or length field.
		    if option == DHO_PAD:		# pad
			# Chew adjacent bytes into a single field.
			ps = curr
			pc = ps
			while pc < end:
			    pb = struct.unpack('!B', bytes[pc])[0]
			    if pb != 0:
				break
			    pc += 1
			padlen = pc - ps
			#print "got %d pad bytes\n" % (padlen)
			options.append(pcs.Field("pad", padlen * 8))
			curr += padlen
			continue
		    elif option == DHO_END:		# end
			options.append(pcs.Field("end", 8, default = option))
			curr += 1
			continue

		    # All DHCP options have a type byte, a length byte,
		    # and a payload. The length byte does NOT include
		    # the length of the other fields.
		    curr += 1
                    optlen = struct.unpack('!B', bytes[curr:curr+1])[0]
                    if (optlen < 1 or ((curr + optlen) > end)):
                        raise UnpackError, \
                              "Bad length %d for DHCPv4 option %d" % \
                              (optlen, option)

		    # Attempt to parse this DHCP option.
		    # Note well: unlike TCP and IP options, the length field
		    # in a DHCP option field does not include the length
		    # and type bytes.
		    # The map contains functions which take the option
		    # list and byte array as parameters, and return a
		    # reference to a class which wraps that option. All
		    # are derived from a base class containing the generic
		    # option parsing logic.
		    # TODO: Use this technique for IGMP, IP and TCP options.
		    curr += 1
		    optinst = None
		    if option in dhcpv4_options.map:
			optinst = \
			    dhcpv4_options.map[option](option, \
						       bytes[curr:curr+optlen])
		    else:
			optinst = \
			    dhcpv4_options.tlv_option(option, \
						      bytes[curr:curr+optlen])

		    options.append(optinst.field())
		    curr += optlen

	if bytes is not None and curr < len(bytes):
	    self.data = payload.payload(bytes[curr:len(bytes)])
	else:
	    self.data = None
Example #46
0
File: ipv4.py Project: jeamland/PCS
    def __init__(self, bytes = None, timestamp = None, **kv):
        """ define the fields of an IPv4 packet, from RFC 791."""
        version = pcs.Field("version", 4, default=4)
        hlen = pcs.Field("hlen", 4, default=5)
        tos = pcs.Field("tos", 8)
        length = pcs.Field("length", 16, default=20)
        id = pcs.Field("id", 16)
        flags = pcs.Field("flags", 3)
        offset = pcs.Field("offset", 13, default=0)
        ttl = pcs.Field("ttl", 8, default=64)
        protocol = pcs.Field("protocol", 8, discriminator=True)
        checksum = pcs.Field("checksum", 16)
        src = pcs.Field("src", 32)
        dst = pcs.Field("dst", 32)
        options = pcs.OptionListField("options")
        pcs.Packet.__init__(self,
                            [version, hlen, tos, length, id, flags, offset,
                             ttl, protocol, checksum, src, dst, options],
                            bytes = bytes, **kv)
        # Description MUST be set after the PCS layer init
        self.description = "IPv4"

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

        if bytes is not None:
            hlen_bytes = self.hlen * 4
            options_len = hlen_bytes - self.sizeof()

            if hlen_bytes > len(bytes):
                raise UnpackError, \
                      "IP header is larger than input (%d > %d)" % \
                      (hlen_bytes, len(bytes))

            if options_len > 0:
                curr = self.sizeof()
                while curr < hlen_bytes:
                    option = struct.unpack('!B', bytes[curr])[0]

                    if option == IPOPT_EOL:
                        options.append(pcs.Field("end", 8, default = IPOPT_EOL))
                        curr += 1
                        continue
                    elif option == IPOPT_NOP:
                        options.append(pcs.Field("nop", 8, default = IPOPT_NOP))
                        curr += 1
                        continue

                    optlen = struct.unpack('!B', bytes[curr+1])[0]
                    if option == IPOPT_RA:
                        # The IPv4 Router Alert option (RFC 2113) is a
                        # single 16 bit value. Its existence indicates
                        # that a router must examine the packet. It is
                        # 32 bits wide including option code and length.
                        if optlen != 4:
                            raise UnpackError, \
                                  "Bad length %d for IP option %d, " \
                                  "should be %d" % (optlen, option, 4)
                        value = struct.unpack("!H", bytes[curr+2:curr+4])[0]
                        options.append(pcs.TypeLengthValueField("ra",
                                       pcs.Field("t", 8, default = option),
                                       pcs.Field("l", 8, default = optlen),
                                       pcs.Field("v", 16, default = value)))
                        curr += optlen
                    else:
                        print "warning: unknown IP option %d" % option
                        optdatalen = optlen - 2
                        options.append(pcs.TypeLengthValueField("unknown",
                                       pcs.Field("t", 8, default = option),
                                       pcs.Field("l", 8, default = optlen),
                                       pcs.Field("v", optdatalen * 8,
                                                 default = value)))
                        curr += optlen

        if (bytes is not None):
            offset = self.hlen << 2
            self.data = self.next(bytes[offset:len(bytes)],
                                  timestamp = timestamp)
            if self.data is None:
                from pcs.packets.payload import payload
                self.data = payload(bytes[offset:len(bytes)])
            #if __debug__:
            #    print "decoded IPv4 payload proto", self.protocol, "as", type(self.data)
        else:
            self.data = None
Example #47
0
    def __init__(self, bytes = None, timestamp = None, **kv):
        """Initialize a DHCPv4 packet. """

        op = pcs.Field("op", 8)
        htype = pcs.Field("htype", 8)
        hlen = pcs.Field("hlen", 8)
        hops = pcs.Field("hops", 8)
        xid = pcs.Field("xid", 32)
        secs = pcs.Field("secs", 16)
        flags = pcs.Field("flags", 16)

        ciaddr = pcs.Field("ciaddr", 32)
        yiaddr = pcs.Field("yiaddr", 32)
        siaddr = pcs.Field("siaddr", 32)
        giaddr = pcs.Field("giaddr", 32)

        chaddr = pcs.StringField("chaddr", 16*8)
        sname = pcs.StringField("sname", 64*8)
        file = pcs.StringField("file", 128*8)

	options = pcs.OptionListField("options")

        pcs.Packet.__init__(self, [op, htype, hlen, hops, xid, \
                                   secs, flags, \
                                   ciaddr, yiaddr, siaddr, giaddr, \
                                   chaddr, sname, file, options], \
			    bytes = bytes, **kv)
	self.description = "Initialize a DHCPv4 packet. "

        if timestamp is None:
            self.timestamp = time.time()
        else:
            self.timestamp = timestamp

	# Always point beyond the static payload so that we take the
	# correct slice as a vanilla payload iff no options are parsed.
	curr = self.sizeof()
	#print "self.sizeof() %d\n" % curr
	if bytes is not None:
	    opts_off = curr
	    end = len(bytes)
	    if (end - curr) > 4:
		# If the DHCP cookie is present, we append it to the
		# options list so it will be reflected if we re-encode.
		# If it is not present, we set the remaining counter to 0
		# so that the options list loop will not execute.
                cval = struct.unpack('!L', bytes[curr:curr+4])[0]
		if cval == DHCP_OPTIONS_COOKIE:
		    options.append(pcs.Field("cookie", 32, default = cval))
		    curr += 4
		else:
		    end = 0

		while curr < end:
		    option = struct.unpack('!B', bytes[curr])[0]

		    # Special-case options which have only a type field
		    # and no data or length field.
		    if option == DHO_PAD:		# pad
			# Chew adjacent bytes into a single field.
			ps = curr
			pc = ps
			while pc < end:
			    pb = struct.unpack('!B', bytes[pc])[0]
			    if pb != 0:
				break
			    pc += 1
			padlen = pc - ps
			#print "got %d pad bytes\n" % (padlen)
			options.append(pcs.Field("pad", padlen * 8))
			curr += padlen
			continue
		    elif option == DHO_END:		# end
			options.append(pcs.Field("end", 8, default = option))
			curr += 1
			continue

		    # All DHCP options have a type byte, a length byte,
		    # and a payload. The length byte does NOT include
		    # the length of the other fields.
		    curr += 1
                    optlen = struct.unpack('!B', bytes[curr:curr+1])[0]
                    if (optlen < 1 or ((curr + optlen) > end)):
                        raise UnpackError, \
                              "Bad length %d for DHCPv4 option %d" % \
                              (optlen, option)

		    # Attempt to parse this DHCP option.
		    # Note well: unlike TCP and IP options, the length field
		    # in a DHCP option field does not include the length
		    # and type bytes.
		    # The map contains functions which take the option
		    # list and byte array as parameters, and return a
		    # reference to a class which wraps that option. All
		    # are derived from a base class containing the generic
		    # option parsing logic.
		    # TODO: Use this technique for IGMP, IP and TCP options.
		    curr += 1
		    optinst = None
		    if option in dhcpv4_options.map:
			optinst = \
			    dhcpv4_options.map[option](option, \
						       bytes[curr:curr+optlen])
		    else:
			optinst = \
			    dhcpv4_options.tlv_option(option, \
						      bytes[curr:curr+optlen])

		    options.append(optinst.field())
		    curr += optlen

	if bytes is not None and curr < len(bytes):
	    self.data = payload.payload(bytes[curr:len(bytes)])
	else:
	    self.data = None