def client_connect(name='client_connect'): return Struct( name, StarByteArray('asset_digest'), HexAdapter(Field('uuid', 16)), star_string('name'), star_string('species'), ChunkVariant('ship_data'), UBInt32('ship_level'), UBInt32('max_fuel'), VLQ('capabilities_length'), Array(lambda ctx: ctx.capabilities_length, Struct('capabilities', star_string('value'))), star_string('account'))
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, u): self.adapters = Struct("adapters", UBInt32("count"), Array(lambda c: c.count, Struct("adapter", UBInt32("index"), Bytes("MAC", 6))) ).parse(u.get_buffer())
class Collection(FixedObjectWithRepeater, ContainsRefs): _construct = Struct( "", UBInt32("length"), MetaRepeater(lambda ctx: ctx.length, Rename("items", field)), ) def __init__(self, value=None): if value == None: value = [] FixedObject.__init__(self, value) def __iter__(self): return iter(self.value) def __getattr__(self, name): if name in ('append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'): return getattr(self.value, name) return super(Collection, self).__getattr__(name) def __getitem__(self, index): return self.value[index] def __setitem__(self, index, value): self.value[index] = value def __delitem__(self, index): del self.value[index] def __len__(self): return len(self.value) def copy(self): return self.__class__(list(self.value.copy))
class Dictionary(Collection): classID = 24 _construct = Struct("dictionary", UBInt32("length"), MetaRepeater(lambda ctx: ctx.length, Struct("items", Rename( "key", field), Rename( "value", field), )), ) def __init__(self, value=None): if value == None: value = {} Collection.__init__(self, value) def to_value(self): items = [Container(key=key, value=value) for (key, value) in dict(self.value).items()] return Container(items=items, length=len(items)) @classmethod def from_value(cls, obj): value = dict([(item.key, item.value) for item in obj.items]) return cls(value) def __getattr__(self, name): if name.startswith('__') and name.endswith('__'): return super(Dictionary, self).__getattr__(name) return getattr(self.value, name) def copy(self): return self.__class__(self.value.copy())
def get_mds_parser(self): self.timestamp = Struct("utc_timestamp", SBInt32("day"), UBInt32("sec"), UBInt32("msec")) self.waveform_data = Struct( "wfm", Array(128, Per2048(UBInt16("average_wfm_if_corr_ku"))), Padding(172)) self.mds_record = Struct("mds_record", self.timestamp, SBInt8("quality_indicator"), Padding(3), UBInt32("source_packet_counter"), Padding(8), Array(20, self.waveform_data)) self.mds = Array(self.n_records, self.mds_record) return self.mds
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 world_start(name='world_start'): return Struct( name, Variant('planet'), StarByteArray('sky_data'), StarByteArray('weather_data'), BFloat32('x'), BFloat32('y'), # Dungeon ID stuff here Variant('world_properties'), UBInt32('client_id'), Flag('local_interpolation'))
def get_mds_parser(self): self.timestamp = Struct("utc_timestamp", SBInt32("day"), UBInt32("sec"), UBInt32("msec")) self.waveform_data = Struct( "wfm", Array(128, Per2048(UBInt16("average_wfm_if_corr_ku"))), Array(2, Per2048(UBInt16("central_filters_if_corr_ku"))), Array(64, Per8096(UBInt16("average_wfm_if_corr_s"))), Array(2, SBInt16("indexes_of_2_dft_samples")), Per256(SBInt16("delta_offset_fft_filter_units")), Padding(18), Per2048(SBInt16("noise_power_measurement")), OneHundredth(SBInt16("agc_of_noise_power_measurement")), OneHundredthDecibel(UBInt16("reference_power_value")), Padding(10)) self.mds_record = Struct("mds_record", self.timestamp, SBInt8("quality_indicator"), Padding(3), UBInt32("source_packet_counter"), Padding(8), Array(20, self.waveform_data)) self.mds = Array(self.n_records, self.mds_record) return self.mds
class SoundBuffer(FixedObjectByteArray): classID = 12 _construct = Struct("", UBInt32("length"), construct.String("items", lambda ctx: ctx.length * 2), ) @classmethod def from_value(cls, obj): return cls(obj.items) def to_value(self): value = self.value length = (len(value) + 3) / 2 value += "\x00" * (length * 2 - len(value)) # padding return Container(items=value, length=length)
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)
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')
class ByteArray(FixedObjectByteArray): classID = 11 _construct = PascalString("value", length_field=UBInt32("length")) def __repr__(self): return '<%s(%i bytes)>' % (self.__class__.__name__, len(self.value))
class Symbol(FixedObjectByteArray): classID = 10 _construct = PascalString("value", length_field=UBInt32("length")) def __repr__(self): return "Symbol(%r)" % self.value
class String(FixedObjectByteArray): classID = 9 _construct = PascalString("value", length_field=UBInt32("length"))
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"), UBInt8("dir"), UBInt8("op"))
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"), UBInt32("module_id"), Bytes("wtp", 6),
from empower.lvapp.lvappserver import LVAPPServer from empower.datatypes.etheraddress import EtherAddress 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"),
from empower.datatypes.etheraddress import EtherAddress from empower.core.resourcepool import CQM from empower.core.resourcepool import ResourceBlock from empower.core.resourcepool import ResourcePool from empower.core.module import Module from empower.lvapp import PT_VERSION 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"))
#!/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
from construct import Array from empower.datatypes.etheraddress import EtherAddress from empower.core.module import Module from empower.core.resourcepool import CQM from empower.core.resourcepool import ResourceBlock from empower.lvapp import PT_VERSION from empower.main import RUNTIME POLLER_ENTRY_TYPE = Sequence("img_entries", Bytes("addr", 6), UBInt8("last_rssi_std"), SBInt8("last_rssi_avg"), UBInt32("last_packets"), UBInt32("hist_packets"), SBInt8("mov_rssi")) POLLER_REQUEST = Struct("poller_request", UBInt8("version"), UBInt8("type"), UBInt32("length"), UBInt32("seq"), UBInt32("module_id"), Bytes("hwaddr", 6), UBInt8("channel"), UBInt8("band")) POLLER_RESPONSE = Struct("poller_response", UBInt8("version"), UBInt8("type"), UBInt32("length"),
class UTF8(FixedObjectByteArray): classID = 14 _construct = PascalString("value", length_field=UBInt32("length"), encoding="utf8")
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
If( lambda context: context["primary"] >= 0, Embed( Struct( "item_information", UBInt8("count"), UBInt16("secondary"), )), ), ) # Metadata inner container. metadata_switch = { 0: UBInt8("value"), 1: UBInt16("value"), 2: UBInt32("value"), 3: BFloat32("value"), 4: AlphaString("value"), 5: Struct( "slot", UBInt16("primary"), UBInt8("count"), UBInt16("secondary"), ), 6: Struct( "coords", UBInt32("x"), UBInt32("y"), UBInt32("z"), ), }
from construct import Adapter, Enum, Field, HexDumpAdapter, Magic, OptionalGreedyRange, Padding, Struct, UBInt32 class EpochTimeStampAdapter(Adapter): """ Convert epoch timestamp <-> localtime """ def _decode(self, obj, context): return time.ctime(obj) def _encode(self, obj, context): return int(time.mktime(time.strptime(obj))) packet_record = Struct( "packet_record", UBInt32("original_length"), UBInt32("included_length"), UBInt32("record_length"), UBInt32("cumulative_drops"), EpochTimeStampAdapter(UBInt32("timestamp_seconds")), UBInt32("timestamp_microseconds"), HexDumpAdapter(Field("data", lambda ctx: ctx.included_length)), # 24 being the static length of the packet_record header Padding(lambda ctx: ctx.record_length - ctx.included_length - 24), ) datalink_type = Enum( UBInt32("datalink"), IEEE802dot3=0, IEEE802dot4=1, IEEE802dot5=2,
from empower.core.app import EmpowerApp from empower.datatypes.etheraddress import EtherAddress from empower.core.cellpool import Cell from empower.vbsp.vbspserver import ModuleVBSPWorker from empower.core.module import ModuleTrigger from empower.vbsp import E_TYPE_TRIG from empower.vbsp import EP_OPERATION_ADD from empower.main import RUNTIME EP_ACT_MAC_REPORTS = 0x06 MAC_REPORTS_REQ = Struct("mac_reports_request", UBInt8("type"), UBInt8("version"), Bytes("enbid", 8), UBInt16("cellid"), UBInt32("xid"), BitStruct("flags", Padding(15), Bit("dir")), UBInt32("seq"), UBInt16("length"), UBInt16("action"), UBInt8("opcode"), UBInt16("deadline")) MAC_REPORTS_RESP = Struct("mac_reports_resp", UBInt8("dl_prbs_total"), UBInt32("dl_prbs_used"), UBInt8("ul_prbs_total"), UBInt32("ul_prbs_used")) class MACReports(ModuleTrigger): """ LVAPStats object. """ MODULE_NAME = "mac_reports" REQUIRED = ['module_type', 'worker', 'tenant_id', 'cell', 'deadline']
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"),
0x8d import struct struct.pack('>L', 154) struct.pack('>L', 141) struct.unpack('>2L', data[16:24]) struct.unpack('>16x2L6x', data) from construct import Struct, Magic, UBInt32, Const, String # adapted from code at https://github.com/construct fmt = Struct('png', Magic(b'\x89PNG\r\n\x1a\n'), UBInt32('length'), Const(String('type', 4), b'IHDR'), UBInt32('width'), UBInt32('height') ) data = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR' + \ b'\x00\x00\x00\x9a\x00\x00\x00\x8d\x08\x02\x00\x00\x00\xc0' result = fmt.parse(data) print(result) print(result.width, result.height) import binascii valid_png_header = b'\x89PNG\r\n\x1a\n' print(binascii.hexlify(valid_png_header))
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 .tpspage import PAGE_HEADER_STRUCT from .utils import check_value record_encoding = None RECORD_TYPE = Enum( Byte('type'), NULL=None, DATA=0xF3, METADATA=0xF6, TABLE_DEFINITION=0xFA, TABLE_NAME=0xFE, _default_='INDEX', ) DATA_RECORD_DATA = Struct('field_data', UBInt32('record_number'), Bytes('data', lambda ctx: ctx['data_size'] - 9)) METADATA_RECORD_DATA = Struct('field_metadata', Byte('metadata_type'), ULInt32('metadata_record_count'), ULInt32('metadata_record_last_access')) TABLE_DEFINITION_RECORD_DATA = Struct( 'table_definition', Bytes('table_definition_bytes', lambda ctx: ctx['data_size'] - 5)) INDEX_RECORD_DATA = Struct('field_index', Bytes('data', lambda ctx: ctx['data_size'] - 10), ULInt32('record_number')) RECORD_STRUCT = Struct(