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
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
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
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
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")
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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