class Trans(Layer): constructorList = [ Int(CallName='last', Pt=0, Type='uint8', Dict={0:"last", 3:"more"}), Str(CallName='res', ReprName='Reserved', Pt='\x00', Len=1, Repr="hex"), Int(CallName='len', ReprName='Length', Type='uint16'), Int(CallName='type', ReprName='Transform type', Type='uint8', \ Dict=TransformType), Str(CallName='res2', ReprName='Reserved2', Pt='\x00', Len=1, Repr="hex"), Int(CallName='tID', ReprName='Transform ID', Type='uint16'), ] def __init__(self, type=1, tID=11): Layer.__init__(self, CallName='Trans', ReprName='Transform') self.type.Pt = type self.tID.Pt = tID self.tID.Dict = TransformID[int(self.type)] self.len.Pt = self.get_payload self.len.PtFunc = lambda pay: len(pay()) + 8 # really dirty way to manage pseudo-dynamically the tID dictionnary, # depending on the type of transformation... def __repr__(self): self.tID.Dict = TransformID[int(self.type)] return Layer.__repr__(self) def show(self, with_trans=False): self.tID.Dict = TransformID[int(self.type)] return Layer.show(self, with_trans) def map(self, string=''): Layer.map(self, string) self.tID.Dict = TransformID[int(self.type)]
class MAC_ACK(MAC): constructorList = [ FrameCtrl(Type=1, Subtype=13), Int('Duration', Pt=0, Type='uint16'), Str('RA', Pt=6*'\0', Len=6, Repr='hex'), Int('FCS', Pt=0, Type='uint32', Repr='hex') ]
class TS(Layer): constructorList = [ Int(CallName='TSt', ReprName='TS Type', Type='uint8', Dict=TSType), Int(CallName='IPpID', ReprName='IP protocol ID', Type='uint8', Dict=IP_prot), Int(CallName='Slen', ReprName='Selector Length', Type='uint16'), Int(CallName='sp', ReprName='Start Port', Type='uint16'), Int(CallName='ep', ReprName='End Port', Type='uint16'), Str(CallName='sa', ReprName='Start Address'), Str(CallName='ea', ReprName='End Address'), ] def __init__(self, TSt=7, IPpID=0, sp=0, ep=65535, sa=None, ea=None): Layer.__init__(self, CallName='TS', ReprName='Traffic Selector') self.TSt.Pt = TSt self.IPpID.Pt = IPpID self.sp.Pt = sp self.ep.Pt = ep self.sa.Pt = sa self.sa.Len = self.Slen self.sa.LenFunc = lambda Slen: (int(Slen) - 8) / 2 self.ea.Pt = ea self.ea.Len = self.Slen self.ea.LenFunc = lambda Slen: (int(Slen) - 8) / 2 self.Slen.Pt = (self.sa, self.ea) self.Slen.PtFunc = lambda (sa, ea): len(sa) + len(ea) + 8 # represent the address in a nice IPv4 format, if possible def __repr__(self): if len(self.sa) == 4: self.sa.Repr = 'ipv4' if len(self.ea) == 4: self.ea.Repr = 'ipv4' return Layer.__repr__(self)
class l1ctl_pm_req(Layer): constructorList = [ Int('type', Pt=1, Type='uint8'), Str('padding', Pt='\0\0\0', Len=3, Repr='hex'), Int('band_arfcn_from', Pt=0, Type='uint16'), Int('band_arfcn_to', Pt=0, Type='uint16'), ]
class SMS_COMMAND(Layer): constructorList = [ Bit('spare', Pt=0, BitLen=1), Bit('TP_UDHI', ReprName='TP User Data Header Indicator', Pt=0, BitLen=1), Bit('TP_SRR', ReprName='TP Status Report Request', Pt=0, BitLen=1, \ Repr='hum', Dict=TP_SRR_dict), Bit('spare', Pt=0, BitLen=3), Bit('TP_MTI', ReprName='TP Message Type Indicator', Pt=0, BitLen=2, \ Repr='hum', Dict=TP_MTI_MStoSC_dict), Int('TP_MR', ReprName='TP Message Reference', Pt=0, Type='uint8'), TP_PID(), Int('TP_CT', ReprName='TP Command Type', Pt=0, Type='uint8', \ Dict=TP_CT_dict), Int('TP_MN', ReprName='TP Message Number', Pt=0, Type='uint8'), TP_Destination_Address(), # length 2-12 Int('TP_CDL', ReprName='TP Command Data Length', Type='uint8'), Str('TP_CD', Pt=''), ] def __init__(self, with_options=False, **kwargs): Layer.__init__(self, **kwargs) self.TP_CDL.Pt = self.TP_CD self.TP_CDL.PtFunc = lambda d: len(d) self.TP_CD.Len = self.TP_CDL self.TP_CD.LenFunc = lambda l: l()
class l1ctl_h1(Layer): constructorList = [ Int('hsn', Pt=0, Type='uint8'), Int('maio', Pt=0, Type='uint8'), Int('n', Pt=0, Type='uint8'), Str('padding', Pt='\0', Len=1, Repr='hex')] + \ [Int('ma_%i' % i, Pt=0, Type='uint16') for i in range(64)]
class GA_PSR_hdr(Layer): constructorList = [ Int(CallName='len', ReprName='Message Length', Type='uint16'), Bit(CallName='si', ReprName='Skip Indicator', Pt=0, BitLen=4, Repr='hex'), Bit(CallName='pd', ReprName='Protocol Discriminator', Pt=2, BitLen=4, Repr='hum', Dict=ProtocolDiscriminator), Int(CallName='type', ReprName='Message Type', Type='uint8', Dict=PSRMsgType), Int(CallName='tlli', ReprName='Temporary Logical Link Identity', Type='uint32'), ] def __init__(self, type=0, tlli=0): Layer.__init__(self, CallName='hdr') self.len.Pt = self.get_payload self.len.PtFunc = lambda pay: len(pay()) + 2 self.type.Pt = type self.tlli.Pt = tlli
class GA_RRC_hdr(Layer): constructorList = [ Int(CallName='len', ReprName='Message Length', Type='uint16'), Bit(CallName='si', ReprName='Skip Indicator', Pt=0, BitLen=4, Repr='hex'), Bit(CallName='pd', ReprName='Protocol Discriminator', Pt=3, BitLen=4, Repr='hum', Dict=ProtocolDiscriminator), Int(CallName='type', ReprName='Message Type', Type='uint8', Dict=RRCMsgType) ] def __init__(self, type=0): Layer.__init__(self, CallName='hdr') self.len.Pt = self.get_payload self.len.PtFunc = lambda pay: len(pay()) + 2 self.type.Pt = type
class NCP(Layer): constructorList = [ Int('Code', Pt=0, Type='uint8', Dict=LCPCode_dict), Int('Identifier', Pt=0, Type='uint8'), Int('Length', Type='uint16'), Str('Data', Pt=''), #, Repr='hex'), ] def __init__(self, **kwargs): Layer.__init__(self, **kwargs) self.Length.Pt = self.Data self.Length.PtFunc = lambda d: len(d) + 4 self.Data.Len = self.Length self.Data.LenFunc = lambda l: l() - 4 def map(self, s='', ipcp=True): if s: Layer.map(self, s) if ipcp: data, ipcp_list = self.Data(), [] while data: ipcp = IPCP() ipcp.map(data) data = data[len(ipcp):] ipcp_list.append(ipcp) if ipcp_list: self.Data.Val = None self.Data.Pt = tuple(ipcp_list)
class Param(Layer): constructorList = [ Int(CallName='T', ReprName='Tag', Type='uint16', Dict=Params), Int(CallName='L', ReprName='Length', Type='uint16'), Str(CallName='V', ReprName='Value'), Str(CallName='p', ReprName='Padding', Pt='', Len=0, Repr='hex'), ] padding_byte = '\0' def __init__(self, T=0, V=''): Layer.__init__(self, CallName='Param', \ ReprName='SIGTRAN common parameter') self.T.Pt = T # Lots of values are encoded as integer # corresponding with specific enum() self.V.Pt = V self.V.Len = self.L self.V.LenFunc = lambda L: int(L)-4 self.L.Pt = self.V self.L.PtFunc = lambda V: len(V)+4 self.p.Pt = self.V self.p.PtFunc = lambda V: self.__pad(V) self.p.Len = self.V self.p.LenFunc = lambda V: self.__pad_len(V) def __pad(self, V): return (4-len(V)%4)%4 * self.padding_byte def __pad_len(self, V): return (4-len(V)%4)%4
class Hdr(Layer): constructorList = [ Int(CallName='ver', ReprName='Version', Pt=1, Type='uint8'), Int(CallName='spa', ReprName='Spare', Pt=0, Type='uint8'), Int(CallName='cla', ReprName='Message Class', Type='uint8',\ Dict=Classes), Int(CallName='typ', ReprName='Message Type', Type='uint8'), Int(CallName='len', ReprName='Message Length', Pt='uint32'), ] type_dict = (MGMT, Transfer, SSNM, ASPSM, ASPTM, QPTM, MAUP,\ ConLess, ConOriented, RKM, IIM, M2PA, Security,\ DPNSSBound, V5Bound) def __init__(self, prot='SUA', cla=0, typ=0): if prot not in ('M2UA', 'M3UA', 'SUA'): prot='generic' Layer.__init__(self, CallName=prot, \ ReprName='SIGTRAN %s header' % prot) self.cla.Pt = cla self.typ.Pt = typ self.typ.Dict = self.cla self.typ.DictFunc = lambda cla: self.type_dict[cla()] self.len.Pt = self.get_payload self.len.PtFunc = lambda pay: len(pay())+8
class DHT(segment): constructorList = [ Int('mark', Pt=0xFF, Type='uint8', Repr='hex'), Int('type', Pt=0xC4, Type='uint8', Repr='hum', Dict=Seg_dict), Int('len', Pt=0, Type='uint16'), Bit('Tc', ReprName='Huffman table class', Pt=0, BitLen=4, Repr='hum'), Bit('Th', ReprName='Huffman table destination identifier', Pt=0, \ BitLen=4, Repr='hum')] + [ \ Int('L%i'%i, ReprName='Number of huffman codes of length %i'%i, \ Pt=0, Type='uint8') for i in range(1, 17)] + \ [Str('V', ReprName='Values for huffman codes of given length', Pt='')] # this is a shortcut for huffman Values def __init__(self, **kwargs): Layer.__init__(self, **kwargs) # length automation self.len.Pt = self.L1 self.len.PtFunc = lambda x: sum(map(len, self[21:])) + 19 # huffman values length automation self.V.Len = self.L1 self.V.LenFunc = lambda x: sum(map(int, self[5:21])) def map(self, s=''): Layer.map(self, s) values, pos = self.V(), 0 self.remove(self[-1]) for i in self[5:21]: for j in range(1, i() + 1): ith = int(i.CallName[1:]) self.append(\ Int('V%i%i'%(ith,j), \ ReprName='Value %i for huffman code of length %i'%(j,ith), \ Val=ord(values[pos]), Type='uint8')) pos += 1
class DAC(segment): constructorList = [ Int('mark', Pt=0xFF, Type='uint8', Repr='hex'), Int('type', Pt=0xCC, Type='uint8', Repr='hum', Dict=Seg_dict), Int('len', Pt=0, Type='uint16'), Str('pay', Pt='\0\0'), ] def __init__(self, **kwargs): Layer.__init__(self, **kwargs) # length automation self.pay.Len = self.len self.pay.LenFunc = lambda l: l() - 2 self.len.Pt = self.pay self.len.PtFunc = lambda p: len(p) + 2 def map(self, s=''): Layer.map(self, s) if len(self.pay) % 2 == 0: pay = str(self.pay) self.remove(self[-1]) while len(pay) > 0: self.append(DACComponent()) self[-1].map(pay) pay = pay[2:]
def encode_bit_str(self, obj): if isinstance(obj._val, ASN1.ASN1Obj): # obj._val: ASN1Obj, according to CONTAINING constraint V = Layer('V') V.append(Int('pad_len', Pt=0, Type='uint8')) obj._val._encode() V.extend(obj._val._msg) obj._val._msg = None # else: # obj._val: (BE uint value, BE uint bit length) val_len = obj._val[1] // 8 val_ext = obj._val[1] % 8 if val_ext: val_len += 1 V = Layer('V') V.append(Int('pad_len', Pt=(8 - val_ext) % 8, Type='uint8')) V.append( Bit('val', Pt=obj._val[0], BitLen=obj._val[1], Repr=self._REPR_BIT_STR)) if val_ext > 0: V.append( Bit('pad', Pt=0, BitLen=8 - val_ext, Repr=self._REPR_BIT_STR)) # obj._msg = BER_TLV(obj.get_name()) obj._msg.set(V) self.handle_tag_enc(obj)
class TI_PSD(Layer): _byte_aligned = False constructorList = [ Bit('unused', Pt=0, BitLen=3, Repr='bin'), Bit('GenProt', ReprName='Generic protocol', Pt=0, BitLen=1, Repr='hum', Dict=Bool_dict), Bit('BufOF', ReprName='Buffer overflow', Pt=0, BitLen=1, Repr='hum', Dict=Bool_dict), Bit('Incomp', ReprName='Incomplete packet', Pt=0, BitLen=1, Repr='hum', Dict=Bool_dict), Bit('Corrinc', ReprName='Correlation used', Pt=0, BitLen=1, Repr='hum', Dict=Bool_dict), Bit('FCSinc', ReprName='FCS included', Pt=0, BitLen=1, Repr='hum', Dict=Bool_dict), Int('Pnbr', ReprName='Packet number', Pt=0, Type='uint32'), Int('Ts', ReprName='Timestamp', Pt=0, Type='uint64'), # Length field seems to depend of SmartRF Packet Sniffer version #Int('Length', Pt=0, Type='uint16'), Int('Length', Pt=0, Type='uint8'), # TI_CC(), Str('spare', Pt='', Repr='hex') ] def __init__(self, **kwargs): Layer.__init__(self, **kwargs) self.Pnbr._endian = 'little' self.Ts._endian = 'little' self.Length._endian = 'little'
class AT_ENCR_DATA(TLV): constructorList = [ Int(CallName="T", ReprName="Type", Pt=130, Type="uint8", Dict=SIMAKAAttribute), Int(CallName="L", ReprName="Length", Type="uint8"), Str(CallName="res", ReprName="Reserved", Pt="\x00\x00", Len=2, Repr="hex"), Str(CallName="encr", ReprName="Encrypted Data", Repr="hex"), ] def __init__(self, encr=''): Layer.__init__(self, CallName='ENCR', ReprName='AT_ENCR_DATA') self.encr.Pt = encr self.encr.PtFunc = lambda encr: self.pad4( str(encr), const=4 ) self.encr.Len = self.L self.encr.LenFunc = lambda L: ( int(L)*4 ) - 4 self.L.Pt = self.encr self.L.PtFunc = lambda encr: self.len4( len(encr) + 4 ) # encryption must use AES-CBC-128 with IV from AT_IV # Encrypted Data: contains nested EAP-AKA TLV attributes # MANAGED AT THE BLOCK LEVEL # The length of the Encrypted Data must be a multiple of 16 bytes # MANAGED AT THE BLOCK LEVEL # >>> if needed AT_PADDING is used as the last nested attribute for padding to a 16-bytes multiple. # MANAGED AT THE BLOCK LEVEL: def cipher(self, data, key=4*'mich', iv=4*'mich'): if len(key) != 16: print '[WNG]: key must be 16 bytes long' if len(iv) != 16: print '[WNG]: iv must be 16 bytes long' if len(data) == 0 or len(data) % 16 != 0: print '[WNG]: data must be 16 bytes long and not null' return AES.new(key=key, mode=2, IV=iv).encrypt(data) def uncipher(self, data, key=4*'mich', iv=4*'mich'): if len(key) != 16: print '[WNG]: key must be 16 bytes long' if len(iv) != 16: print '[WNG]: iv must be 16 bytes long' if len(data) == 0 or len(data) % 16 != 0: print '[WNG]: data must be 16 bytes long and not null' return AES.new(key=key, mode=2, IV=iv).decrypt(data)
class OPEN(Layer): constructorList = [ Int('Version', Pt=4, Type='uint8'), Int('AutSys', ReprName='Sender Autonomous System', Pt=0, Type='uint16'), Int('HoldT', ReprName='Hold Timer (sec)', Pt=3, Type='uint16'), Int('BGPId', ReprName='BGP Identifier', Pt=BGP_id, Type='uint32'), Int('OptLen', ReprName='Optional Parameters Length', Pt=0, Type='uint8'), ] def __init__(self): Layer.__init__(self) self.append(Layer('Options')) self.OptLen > self.Options self.OptLen.PtFunc = lambda opt: len(opt) # overwrite .map() to fill .Options with opt() def map(self, string=''): self.map(string) string = string[len(self):] while len(string) > 0: o = opt() o.map(string) o.inc_hierarchy(self.hierarchy) self.Options.append(o) string = string[len(o):]
class SMS_SUBMIT_REPORT_RP_ERROR(Layer): constructorList = [ Bit('spare', Pt=0, BitLen=1), Bit('TP_UDHI', ReprName='TP User Data Header Indicator', Pt=0, BitLen=1), Bit('spare', Pt=0, BitLen=4), Bit('TP_MTI', ReprName='TP Message Type Indicator', Pt=0, BitLen=2, \ Repr='hum', Dict=TP_MTI_SCtoMS_dict), Int('TP_FCS', ReprName='Failure Cause', Pt=0, Type='uint8', \ Dict=TP_FCS_dict), # only on RP-ERROR TP_PI(), TP_SCTS(), TP_PID(), TP_DCS(), Int('TP_UDL', ReprName='User Data Length (in character)', Pt=0, \ Type='uint8'), Str7b('TP_UD', Pt=''), ] def __init__(self, with_options=False, **kwargs): Layer.__init__(self, **kwargs) self.TP_UDL.Pt = self.TP_UD self.TP_UDL.PtFunc = self._get_udl self.TP_UD.Len = self.TP_UDL self.TP_UD.LenFunc = self._get_ud_len if not with_options: self.TP_PID.Trans = True self.TP_DCS.Trans = True self.TP_UDL.Trans = True self.TP_UD.Trans = True def _get_udl(self, _unused): if hasattr(self.TP_DCS, 'Charset') \ and not self.TP_DCS.Charset.is_transparent(): if self.TP_DCS.Charset() == 1: return len(self.TP_UD) elif self.TP_DCS.Charset() == 2: return len(self.TP_UD)//2 return len(self.TP_UD.decode()) def _get_ud_len(self, _unused): if hasattr(self.TP_DCS, 'Charset') \ and not self.TP_DCS.Charset.is_transparent(): if self.TP_DCS.Charset() == 1: return self.TP_UDL() elif self.TP_DCS.Charset() == 2: return self.TP_UDL()*2 return int(ceil(self.TP_UDL()*7.0/8)) def map(self, s=''): s_len = len(s) if s_len < 14: self.TP_UD.Trans = True if s_len < 13: self.TP_UDL.Trans = True if s_len < 12: self.TP_DCS.Trans = True if s_len < 11: self.TP_PID.Trans = True Layer.map(self, s)
class l1ctl_dm_est_req_h1(Layer): constructorList = [ Int('tsc', Pt=0, Type='uint8'), Int('h', Pt=1, Type='uint8'), l1ctl_h1(), Int('tch_mode', Pt=0, Type='uint8'), Int('audio_mode', Pt=5, Type='uint8'), ]
class l1ctl_neigh_pm_ind(Layer): constructorList = [ Int('band_arfcn', Pt=0, Type='uint16'), Int('pm', Pt=0, Type='uint8'), Int('pm2', Pt=0, Type='uint8'), Int('tn', Pt=0, Type='uint8'), Str('padding', Pt='\0', Len=1, Repr='hex'), ]
class ESMHeader(Layer): constructorList = [ Bit('EBT', ReprName='EPS Bearer Type', Pt=0, BitLen=4, Repr='hum'), Bit('PD', ReprName='Protocol Discriminator', Pt=2, BitLen=4, Dict=PD_dict, Repr='hum'), Int('TI', ReprName='Procedure Transaction ID', Pt=0, Type='uint8'), Int('Type', Type='uint8', Dict=ESM_dict, Repr='hum'), ]
class l1ctl_dm_freq_req(Layer): constructorList = [ Int('fn', Pt=0, Type='uint16'), Int('tsc', Pt=0, Type='uint8'), Int('h', Pt=0, Type='uint8'), l1ctl_h0(), l1ctl_h1(), ]
class MAC_PSPoll(MAC): constructorList = [ FrameCtrl(Type=1, Subtype=10), Int('AID', Pt=0, Type='uint16'), Str('BSSID', Pt=6*'\0', Len=6, Repr='hex'), Str('TA', Pt=6*'\0', Len=6, Repr='hex'), Int('FCS', Pt=0, Type='uint32', Repr='hex') ]
class GlobalENBID(Layer): _byte_aligned = False constructorList = [ Int('F_PLMN', Type='uint8', Repr='hex'), PLMN(), Int('F_eNBID', Type='uint8', Repr='hex'), Bit('eNBID', BitLen=20, Repr='hex'), Bit('pad', BitLen=4, Repr='hex'), ]
def set_private(self): self.priv = Int('priv', Pt=_rand.randint(3, self.MOD()-1), Type=self.TYPE) if _with_gmpy: pub = int(pow(gmpy.mpz(self.GEN()), gmpy.mpz(self.priv()), gmpy.mpz(self.MOD()))) else: pub = pow(self.GEN(), self.priv(), self.MOD()) self.pub = Int('pub', Pt=pub, Type=self.TYPE)
class StreamSeq(Layer): constructorList = [ Int(CallName='sid', ReprName='Stream Identifier', Type='uint16'), Int(CallName='ssq', ReprName='Stream Sequence', Type='uint16'), ] def __init__(self, sid=0, ssq=0): Layer.__init__(self, CallName='sseq', ReprName='Stream Sequence') self.sid.Pt = sid self.ssq.Pt = ssq
class GapAckBlock(Layer): constructorList = [ Int(CallName='start', ReprName='Gap Ack Block Start', Type='uint16'), Int(CallName='end', ReprName='Gap Ack Block End', Type='uint16'), ] def __init__(self, start=0, end=0): Layer.__init__(self, CallName='gap', ReprName='Gap Ack Block') self.start.Pt = start self.end.Pt = end
class SOFComponent(Layer): constructorList = [ Int('C', ReprName='Component identifier', Pt=0, Type='uint8'), Bit('H', ReprName='Horizontal sampling factor', Pt=0, BitLen=4, \ Repr='hum'), Bit('V', ReprName='Vertical sampling factor', Pt=0, BitLen=4, \ Repr='hum'), Int('Tq', ReprName='Quantization table destination selector', Pt=0, \ Type='uint8'), ]
class EAPSIM_meth(Layer): constructorList = [ Int(CallName="type", ReprName="Type", Type="uint8", Dict=method_dict), Int(CallName="sub", ReprName="Subtype", Type="uint8", Dict=SIMAKASubtype), Str(CallName="res", ReprName="Reserved", Pt='\x00\x00', Len=2, Repr="hex"), ] def __init__(self, type=method_dict["sim"], sub=10): Layer.__init__(self, CallName='meth', ReprName='EAP method') self.type.Pt = type self.sub.Pt = sub
class TI_USB(Layer): constructorList = [ Int('pad', Pt=0, Type='uint8', Repr='hex'), Int('Length', Pt=0, Type='uint16'), Int('TS', Pt=0, Type='uint32'), TI_CC() ] def __init__(self, **kwargs): Layer.__init__(self, **kwargs) self.Length._endian = 'little' self.TS._endian = 'little'