class TestThisExpressions(unittest.TestCase): this_example = Struct( "this_example", # straight-forward usage: instead of passing (lambda ctx: ctx["length"]) use this.length UBInt8("length"), Field("value", this.length), # an example of nesting: '_' refers to the parent's scope Struct("nested", UBInt8("b1"), UBInt8("b2"), Computed("b3", this.b1 * this.b2 + this._.length)), # and conditions work as expected IfThenElse( "condition", this.nested.b1 > 50, UBInt32("foo"), UBInt8("bar"), )) def test_parse(self): res = self.this_example.parse(b"\x05helloABXXXX") expected = Container(length=5)(value=b'hello')(nested=Container(b1=65)( b2=66)(b3=4295))(condition=1482184792) self.assertEquals(res, expected) def test_build(self): obj = dict(length=5, value=b'hello', nested=dict(b1=65, b2=66, b3=None), condition=1482184792) data = self.this_example.build(obj) self.assertEquals(data, b"\x05helloABXXXX")
def damage_request(name='damage_request'): return Struct(name, UBInt32('source_entity_id'), UBInt32('target_entity_id'), UBInt8('hit_type'), UBInt8('damage_type'), BFloat32('damage'), BFloat32('knockback_x'), BFloat32('knockback_y'), UBInt32('source_entity_id_wut'), star_string('damage_source_kind'), GreedyRange(star_string('stuats_effects')))
def __init__(self): self.constructFrame = Struct( 'parser', OptionalGreedyRange( Struct( 'packets', UBInt8('header'), UBInt16('plen'), UBInt8('functype'), UBInt64('nodeid'), UBInt8('sum'), )))
def RRName(name): ''' A Resource Record Name structure. Supports DNS pointer compression through the MovingPointer class ''' return Struct( name, Anchor('_start'), Union( 'length_or_offset', UBInt8('length'), # regular label UBInt16('offset'), # compression pointer ), IfThenElse( 'name', this.length_or_offset.length & 0xc0 == 0xc0, # compression pointer MovingPointer( lambda ctx: ctx.length_or_offset.offset & ~0xc000, Label(name), offset=1, whence=os.SEEK_CUR, ), # regular label MovingPointer(this._start, Label(name)), ), )
def InfiniPacket(name, identifier, subconstruct): """ Common header structure for packets. This is possibly not the best way to go about building these kinds of things. """ header = Struct("header", # XXX Should this be Magic(chr(identifier))? Const(UBInt8("identifier"), identifier), UBInt8("flags"), UBInt32("length"), ) return Struct(name, header, subconstruct)
def __init__(self): self.constructFrameParse = Struct( "parser", OptionalGreedyRange(UBInt8("packets")), Value( "checkSum", lambda ctx: str(hex((255 - sum(ctx.packets[3:])) & 0xff))[ 2:].zfill(2)[-2:]))
def data_class(self): """ A :py:func:`construct.macros.UBInt8` construct that requires the input value to be equal to 6. """ return TLSExprValidator(UBInt8('input_byte'), lambda obj, ctx: obj == 6)
def __init__(self): self.constructFrameParse = Struct( "parser", OptionalGreedyRange(UBInt8("packets")), Value( "checkSum", lambda ctx: int((hex( (255 - sum(ctx.packets[3:])) & 0xffffffffffffffff)[-3:-1]), 16)))
def test(self): pstring = Struct( "pstring", UBInt8("length"), Struct( "inner", UBInt8("inner_length"), Bytes("data", foo), )) obj = pstring.parse(b"\x03\x02helloXXX") print(repr(obj)) self.assertEqual( obj, Container(length=3, inner=Container(inner_length=2, data=b"hello"))) size = pstring._sizeof(Container(inner_length=2, _=Container(length=3))) self.assertEqual(size, 7)
class InstantSoupData(object): # common server = Struct("server", CString("server_id"), PrefixedArray(CString('channels'), UBInt8("num_channels"))) # structures from rfc opt_client_nick = CString('nickname') opt_client_membership = PrefixedArray(server, UBInt8("num_servers")) opt_server = Struct("opt_server", UBInt16("port")) opt_server_channels = Struct( "opt_server_channels", PrefixedArray(CString("channels"), UBInt8("num_channels"))) opt_server_invite = Struct( "opt_server_invite", CString("channel_id"), PrefixedArray(CString("client_id"), UBInt8("num_clients"))) # option fields option = Struct( "option", Enum(UBInt8("option_id"), CLIENT_NICK_OPTION=0x01, CLIENT_MEMBERSHIP_OPTION=0x02, SERVER_OPTION=0x10, SERVER_CHANNELS_OPTION=0x11, SERVER_INVITE_OPTION=0x12), Switch( "option_data", lambda ctx: ctx["option_id"], { "CLIENT_NICK_OPTION": opt_client_nick, "CLIENT_MEMBERSHIP_OPTION": opt_client_membership, "SERVER_OPTION": opt_server, "SERVER_CHANNELS_OPTION": opt_server_channels, "SERVER_INVITE_OPTION": opt_server_invite })) # the peer pdu itself peer_pdu = Struct("peer_pdu", CString('id'), OptionalGreedyRange(option)) command = PascalString("command", length_field=UBInt32("length"), encoding='utf8')
def TLSUBInt8Length5Array(self): # noqa """ Like :py:meth:`TLSPrefixedArrayWithLengthValidator.TLSUBInt8Length5Array`, but only accepts arrays of length 5. """ return TLSPrefixedArray("data", UBInt8("datum"), length_validator=Equals5)
def tls_array(self): """ A :py:func:`tls._common._constructs.TLSPrefixedArray` of :py:func:`construct.macros.UBInt8` where the length prefix for the array size is specified with a :py:class`UBInt24` value. """ return TLSPrefixedArray("digits", UBInt8("digit"), length_field_size=UBInt24)
def UBInt8EnumMappedStructWithDefault(self): # noqa """ Like ``UBInt8EnumMappedStruct`` but with a default value. """ return Struct( "UBInt8EnumMappedStructWithDefault", *EnumSwitch(type_field=UBInt8("type"), type_enum=IntegerEnum, value_field="value", value_choices={IntegerEnum.FIRST: UBInt16("UBInt16")}, default=Pass))
class TranslucentColor(Color): classID = 31 _construct = Struct( "", Embed(Color._construct), UBInt8("alpha"), # I think. ) _construct_32 = Struct( "", UBInt8("alpha"), UBInt8("r"), UBInt8("g"), UBInt8("b"), ) def __init__(self, value): self.value = value def to_value(self): (r, g, b, alpha) = self.value return Container(r=r, g=g, b=b, alpha=alpha) @classmethod def from_value(cls, value): return cls((value.r, value.g, value.b, value.alpha)) @classmethod def from_32bit_raw_argb(cls, raw): container = cls._construct_32.parse(raw) parts = cls.from_value(container) color = cls(*(x << 2 for x in parts.value)) if color.alpha == 0 and (color.r > 0 or color.g > 0 or color.b > 0): color.alpha = 1023 return color def to_rgba_array(self): return array('B', self.to_8bit()) def to_argb_array(self): (r, g, b, a) = self.to_8bit() return bytearray((a, r, g, b))
def __init__(self): self.constructFrame = Struct( "parser", OptionalGreedyRange( Struct( "packets", UBInt8("header"), UBInt16("plen"), UBInt8("dir"), ULInt64("nodeid"), UBInt16("funcid"), Array( lambda ctx: (ctx.plen - 1 - 8 - 2) / 8, Struct( "datas", ULInt16("type"), ULInt16("unit"), LFloat32("value"), )), UBInt8("sum"), # UBInt8("simulation") ), ), OptionalGreedyRange(UBInt8("leftovers"), ), )
def UBInt8EnumMappedStruct(self): # noqa """ A :py:class:`construct.core.Struct` containing an :py:func:`tls._common._constructs.EnumSwitch` that switches on :py:class:`IntegerEnum`. The struct's ``value`` field varies depending on the value of its ``type`` and the corresponding enum member specified in the ``value_choices`` dictionary passed to the :py:func:`tls._common._constructs.EnumSwitch`. """ return Struct( "UBInt8EnumMappedStruct", *EnumSwitch(type_field=UBInt8("type"), type_enum=IntegerEnum, value_field="value", value_choices={ IntegerEnum.FIRST: UBInt16("UBInt16"), IntegerEnum.SECOND: UBInt24("UBInt24") }))
def setUp(self): self.o = OneOf(UBInt8("foo"), [4, 5, 6, 7])
class Color(FixedObject): """A 32-bit RGB color value. Each component r, g, b has a value between 0 and 1023. However, Colors are considered equal if they have the same 8-bit value. """ classID = 30 _construct = BitStruct( "value", Padding(2), Bits("r", 10), Bits("g", 10), Bits("b", 10), ) _construct_32_rgba = Struct( "", UBInt8("r"), UBInt8("g"), UBInt8("b"), UBInt8("alpha"), ) def __init__(self, value): self.value = value def __eq__(self, other): return (isinstance(other, Color) and self.to_8bit() == other.to_8bit()) def __ne__(self, other): return not self == other @classmethod def from_value(cls, value): return cls((value.r, value.g, value.b)) def to_value(self): (r, g, b) = self.value return Container(r=r, g=g, b=b) @classmethod def from_8bit(self, r, g=None, b=None): if g is None and b is None: rgb = r else: rgb = (r, g, b) return Color((x << 2 for x in rgb)) def to_8bit(self): """Returns value with components between 0-255.""" return tuple(x >> 2 for x in self.value) def __repr__(self): return "%s(%s)" % ( self.__class__.__name__, repr(self.value).strip("()"), ) def to_rgba_array(self): (r, g, b) = self.to_8bit() return array('B', (r, g, b, 255)) def to_argb_array(self): (r, g, b) = self.to_8bit() return bytearray((255, r, g, b))
EP_ACT_CCAP = 3 EP_ACT_UE_REPORT = 4 EP_ACT_UE_MEASURE = 5 EP_ACT_HANDOVER = 7 PT_BYE = 0xFF00 PT_REGISTER = 0xFF01 PT_UE_JOIN = 0xFF02 PT_UE_LEAVE = 0xFF03 E_TYPE_SINGLE = 0x01 E_TYPE_SCHED = 0x02 E_TYPE_TRIG = 0x03 HEADER = Struct("header", UBInt8("type"), UBInt8("version"), UBInt32("enbid"), UBInt16("cellid"), UBInt32("modid"), UBInt16("length"), UBInt32("seq")) E_SCHED = Struct("e_sched", UBInt8("action"), UBInt8("dir"), UBInt8("op"), UBInt32("interval")) E_SINGLE = Struct("e_sched", UBInt8("action"),
from empower.main import RUNTIME R_GT = 'GT' R_LT = 'LT' R_EQ = 'EQ' R_GE = 'GE' R_LE = 'LE' RELATIONS = {R_EQ: 0, R_GT: 1, R_LT: 2, R_GE: 3, R_LE: 4} PT_ADD_BUSYNESS = 0x39 PT_BUSYNESS = 0x40 PT_DEL_BUSYNESS = 0x41 ADD_BUSYNESS_TRIGGER = Struct("add_busyness_trigger", UBInt8("version"), UBInt8("type"), UBInt32("length"), UBInt32("seq"), UBInt32("module_id"), Bytes("hwaddr", 6), UBInt8("channel"), UBInt8("band"), UBInt8("relation"), UBInt32("value"), UBInt16("period")) BUSYNESS_TRIGGER = Struct("busyness_trigger", UBInt8("version"), UBInt8("type"), UBInt32("length"), UBInt32("seq"),
from empower.lvapp.lvappserver import ModuleLVAPPWorker from empower.core.module import Module from empower.core.app import EmpowerApp from empower.main import RUNTIME PT_WTP_STATS_REQUEST = 0x41 PT_WTP_STATS_RESPONSE = 0x42 WTP_STATS = Sequence("stats", Bytes("lvap", 6), UBInt16("bytes"), UBInt32("count")) WTP_STATS_REQUEST = Struct("stats_request", UBInt8("version"), UBInt8("type"), UBInt32("length"), UBInt32("seq"), UBInt32("module_id")) WTP_STATS_RESPONSE = \ Struct("stats_response", UBInt8("version"), UBInt8("type"), UBInt32("length"), UBInt32("seq"), UBInt32("module_id"), Bytes("wtp", 6), UBInt16("nb_tx"), UBInt16("nb_rx"), Array(lambda ctx: ctx.nb_tx + ctx.nb_rx, WTP_STATS))
from construct import Struct, UBInt8, UBInt16, OptionalGreedyRange, Container #OptionalGreedyRange(subcon) berguna agar field tersebut berupa optional yang artinya boleh kosong kalau error juga akan diisi kongong mo_payload = Struct('mo_payload', UBInt8('destination'), UBInt8('flags'), UBInt16('msg_id'), OptionalGreedyRange(UBInt8("payload"))) payload = "Ini pesannya" a = Container(destination=1, msg_id=1, flags=1, payload=payload) print "a : ", a #build b = mo_payload.build(a) print "b : ", b #parse c = mo_payload.parse(b) print "c : ", c print "====================================" #lihat isi payload "ini pesannya hilang karna yang diutuhkan adalah Unsign bigendianes Integer 8 bit" #maka bisa dengan bantuan fungsi ord yang mengubah character dalam bentuk angka print "payload dlm bentuk symbol ASCII = ", payload print "len = ", len(payload) payload = map(ord, payload) print "payload dikonversi dari symbol ke integer= ", payload print "len = ", len(payload) hexa = map(hex, payload) print "dalam bentuk hexa(16) = ", hexa print "len dalam bentuk hexa(16) = ", len(hexa)
from construct import Struct, UBInt8, Debugger, Enum foo = Struct( "foo", UBInt8("bar"), Debugger(Enum( UBInt8("spam"), ABC=1, DEF=2, GHI=3, )), UBInt8("eggs"), ) print foo.parse("\x01\x02\x03") print foo.parse("\x01\x04\x03")
from empower.main import RUNTIME PT_POLLER_REQ_MSG_TYPE = 0x27 PT_POLLER_RESP_MSG_TYPE = 0x28 POLLER_ENTRY_TYPE = Sequence("img_entries", Bytes("addr", 6), UBInt32("last_rssi_std"), SBInt32("last_rssi_avg"), UBInt32("last_packets"), UBInt32("hist_packets"), SBInt32("ewma_rssi"), SBInt32("sma_rssi")) POLLER_REQUEST = Struct("poller_request", UBInt8("version"), UBInt8("type"), UBInt16("length"), UBInt32("seq"), UBInt32("module_id"), Bytes("addrs", 6), Bytes("hwaddr", 6), UBInt8("channel"), UBInt8("band")) POLLER_RESPONSE = Struct("poller_response", UBInt8("version"), UBInt8("type"), UBInt16("length"), UBInt32("seq"), UBInt32("module_id"), Bytes("wtp", 6),
#!/usr/bin/env python """Contains things like packet header structure, flags, and packet specific enums.""" # Required modules from construct import Container, UBInt8, UBInt32, Struct from enum import IntEnum __all__ = ["header", "HEADER_SIZE", "Flags", "PacketTypes", "PACKET_TYPES"] header = Struct("packet", UBInt8("type"), UBInt8("stream"), UBInt8("flags"), UBInt8("payload_length"), UBInt32("sequence"), UBInt32("tag")) HEADER_SIZE = 0x0c class Flags(IntEnum): # Flag fields NONE = 0X00 ALL = 0XFF INIT = (1 << 0) DATA = (1 << 1) FINISH = (1 << 2) COMPRESS = (1 << 3) META = (1 << 4) class PacketTypes(IntEnum): """Packet types""" AGENT_HELLO = 0X01 HANDLER_HELLO = 0X02 AGENT_ACK = 0X03
def setUp(self): self.n = NoneOf(UBInt8("foo"), [4, 5, 6, 7])
PT_CAPS_REQUEST = 0x16 PT_CAPS_RESPONSE = 0x17 PT_ADD_VAP = 0x32 PT_DEL_VAP = 0x33 PT_STATUS_VAP = 0x34 PT_ADD_LVAP_RESPONSE = 0x51 PT_DEL_LVAP_RESPONSE = 0x52 PT_LVAP_STATUS_REQUEST = 0x53 PT_VAP_STATUS_REQUEST = 0x54 PT_SET_TRAFFIC_RULE = 0x56 PT_DEL_TRAFFIC_RULE = 0x57 PT_STATUS_TRAFFIC_RULE = 0x58 PT_TRAFFIC_RULE_STATUS_REQUEST = 0x61 PT_PORT_STATUS_REQUEST = 0x62 HEADER = Struct("header", UBInt8("version"), UBInt8("type"), UBInt32("length")) SSIDS = Range( 1, 10, Struct("ssids", UBInt8("length"), Bytes("ssid", lambda ctx: ctx.length))) HELLO = Struct("hello", UBInt8("version"), UBInt8("type"), UBInt32("length"), UBInt32("seq"), Bytes("wtp", 6), UBInt32("period")) PROBE_REQUEST = Struct("probe_request", UBInt8("version"), UBInt8("type"), UBInt32("length"), UBInt32("seq"), Bytes("wtp", 6), Bytes("sta", 6), Bytes("hwaddr", 6), UBInt8("channel"), UBInt8("band"), UBInt8("supported_band"), Bytes("ssid", lambda ctx: ctx.length - 31)) PROBE_RESPONSE = Struct("probe_response", UBInt8("version"), UBInt8("type"),
class Bitmap(FixedObjectByteArray): classID = 13 _construct = Struct( "", UBInt32("length"), construct.String("items", lambda ctx: ctx.length * 4), # Identically named "String" class -_- ) @classmethod def from_value(cls, obj): return cls(obj.items) def to_value(self): value = self.value length = (len(value) + 3) / 4 value += "\x00" * (length * 4 - len(value)) # padding return Container(items=value, length=length) _int = Struct( "int", UBInt8("_value"), If( lambda ctx: ctx._value > 223, IfThenElse( "", lambda ctx: ctx._value <= 254, Embed( Struct( "", UBInt8("_second_byte"), Value( "_value", lambda ctx: (ctx._value - 224) * 256 + ctx._second_byte), )), Embed(Struct( "", UBInt32("_value"), )))), ) _length_run_coding = Struct( "", Embed(_int), #ERROR? Value("length", lambda ctx: ctx._value), OptionalGreedyRepeater( Struct( "data", Embed(_int), Value("data_code", lambda ctx: ctx._value % 4), Value("run_length", lambda ctx: (ctx._value - ctx.data_code) / 4), Switch( "", lambda ctx: ctx.data_code, { 0: Embed( Struct( "", StrictRepeater( get_run_length, Value("pixels", lambda ctx: "\x00\x00\x00\x00")), )), 1: Embed( Struct( "", Bytes("_b", 1), StrictRepeater( get_run_length, Value("pixels", lambda ctx: ctx._b * 4), ), )), 2: Embed( Struct( "", Bytes("_pixel", 4), StrictRepeater( get_run_length, Value("pixels", lambda ctx: ctx._pixel), ), )), 3: Embed( Struct( "", StrictRepeater( get_run_length, Bytes("pixels", 4), ), )), }), ))) @classmethod def from_byte_array(cls, bytes_): """Decodes a run-length encoded ByteArray and returns a Bitmap. The ByteArray decompresses to a sequence of 32-bit values, which are stored as a byte string. (The specific encoding depends on Form.depth.) """ runs = cls._length_run_coding.parse(bytes_) pixels = (run.pixels for run in runs.data) data = "".join(itertools.chain.from_iterable(pixels)) return cls(data) def compress(self): """Compress to a ByteArray""" raise NotImplementedError
from empower.core.app import EmpowerApp from empower.datatypes.etheraddress import EtherAddress from empower.core.vbs import Cell from empower.vbsp.vbspserver import ModuleVBSPWorker from empower.core.module import ModuleTrigger from empower.vbsp import PT_VERSION from empower.vbsp import E_TYPE_TRIG from empower.vbsp import EP_DIR_REQUEST from empower.vbsp import EP_OPERATION_ADD from empower.main import RUNTIME EP_ACT_MAC_REPORTS = 0x06 MAC_REPORTS_REQ = Struct("mac_reports_req", UBInt8("type"), UBInt8("version"), UBInt32("enbid"), UBInt16("cellid"), UBInt32("modid"), UBInt16("length"), UBInt32("seq"), UBInt8("action"), UBInt8("dir"), UBInt8("op"), UBInt16("deadline")) MAC_REPORTS_RESP = Struct("mac_reports_resp", UBInt8("DL_prbs_total"), UBInt8("DL_prbs_in_use"), UBInt16("DL_prbs_avg"), UBInt8("UL_prbs_total"), UBInt8("UL_prbs_in_use"), UBInt16("UL_prbs_avg")) class MACReports(ModuleTrigger): """ LVAPStats object. """ MODULE_NAME = "mac_reports" REQUIRED = ['module_type', 'worker', 'tenant_id', 'cell', 'deadline']
from construct import SBInt8, SBInt16, SBInt32, SBInt64 from construct import BFloat32, BFloat64 from construct import BitStruct, BitField DUMP_ALL_PACKETS = False # Our tricky Java string decoder. # Note that Java has a weird encoding for the NULL byte which we do not # respect or honor since no client will generate it. Instead, we will get two # NULL bytes in a row. AlphaString = functools.partial(PascalString, length_field=UBInt16("length"), encoding="utf8") # Flying, position, and orientation, reused in several places. grounded = Struct("grounded", UBInt8("grounded")) position = Struct("position", BFloat64("x"), BFloat64("y"), BFloat64("stance"), BFloat64("z")) orientation = Struct("orientation", BFloat32("rotation"), BFloat32("pitch")) # Notchian item packing items = Struct( "items", SBInt16("primary"), If( lambda context: context["primary"] >= 0, Embed( Struct( "item_information", UBInt8("count"), UBInt16("secondary"),