Esempio n. 1
0
 def __init__(self, *args, **kw):
     if 'val' in kw:
         val = kw['val']
         del kw['val']
     else:
         val = None
     if 'sec' in kw:
         # used within the NAS LTE EMM stack of corenet
         sec = kw['sec']
         del kw['sec']
     else:
         sec = None
     Envelope.__init__(self, *args, **kw)
     self._sec = sec
     # build a list of (tag length, tag value) for the optional part
     # configure IE set by **kw as non-transparent and set their value
     self._opts = []
     if val is None:
         # go faster by just looking for optional IE
         for ie in self._content:
             if isinstance(ie,
                           (Type1TV, Type2, Type3TV, Type4TLV, Type6TLVE)):
                 # optional IE
                 T = ie[0]
                 self._opts.append((T.get_bl(), T(), ie))
     else:
         for ie in self._content:
             if isinstance(ie, (Type1V, Type1TV)):
                 rawtype = integer_types
             else:
                 rawtype = bytes_types
             if isinstance(
                     ie,
                 (Type1V, Type3V, Type4LV, Type6LVE)) and ie._name in val:
                 # setting value for non-optional IE
                 if isinstance(val[ie._name], rawtype):
                     # setting raw value
                     ie['V'].set_val(val[ie._name])
                 else:
                     # setting embedded IE structure
                     ie.set_IE(val=val[ie._name])
             elif isinstance(ie, (Type1TV, Type3TV, Type4TLV, Type6TLVE)):
                 # optional IE
                 T = ie[0]
                 self._opts.append((T.get_bl(), T(), ie))
                 if ie._name in val:
                     ie._trans = False
                     if isinstance(val[ie._name], rawtype):
                         # setting raw value
                         ie['V'].set_val(val[ie._name])
                     else:
                         # setting embedded IE structure
                         ie.set_IE(val=val[ie._name])
             elif isinstance(ie, Type2):
                 # optional Tag-only IE
                 self._opts.append((8, ie[0](), ie))
                 if ie._name in val:
                     ie._trans = False
             elif ie._name in val:
                 ie.set_val(val[ie._name])
Esempio n. 2
0
 def _from_char(self, char):
     if self[0]._name != 'V':
         # restore the std buffer for handling the value
         self.unset_IE()
     #
     # TODO: investigate the cause to have this dirty patch within some pcaps
     # and remove it as soon as possible
     robl, chbl = self[0]._blauto(), char.len_bit()
     if chbl < robl:
         log('%s, _from_char: buffer not long enough, requests %i, max %i'\
             % (self._name, robl, chbl))
         char.append_bytes(b'\x2b' * ((robl - chbl) >> 3))
     #
     Envelope._from_char(self, char)
     # in case self._IE is defined, use it to decode char instead of V
     if self.DECODE_INNER and self._IE_stat is not None:
         if self._IE is None:
             self._IE = self._IE_stat.clone()
         iebl = self[-1].get_bl()
         ccur, clen = char._cur, char._len_bit
         char._cur -= iebl
         char._len_bit = char._cur + iebl
         try:
             self._IE._from_char(char)
         except:
             log('%s, _from_char: unable to decode IE, %s'\
                 % (self._name, self._IE._name))
         else:
             if char.len_bit() > 0:
                 log('%s, _from_char: uncorrect decoding for IE, %s'\
                     % (self._name, self._IE._name))
             else:
                 # replace V with the IE structure
                 self.replace(self[-1], self._IE)
         char._cur, char._len_bit = ccur, clen
Esempio n. 3
0
 def _from_char(self, char):
     Envelope._from_char(self, char)
     # in case self._IE is defined, use it to decode char instead of V
     if self._IE is not None:
         iebl = self[-1].get_bl()
         char_cur = char._cur
         char_lb = char._len_bit
         char._cur -= iebl
         char._len_bit = char._cur + iebl
         try:
             self._IE._from_char(char)
         except:
             log('%s, _from_char: unable to decode IE, %s'\
                 % (self._name, self._IE._name))
         else:
             if char.len_bit() > 0:
                 log('%s, _from_char: uncorrect decoding for IE, %s'\
                     % (self._name, self._IE._name))
             else:
                 # save the V buffer
                 self._V = self[-1]
                 # replace it with the IE structure
                 self.replace(self[-1], self._IE)
                 if self[-2]._name == 'L':
                     # Type4 and Type6
                     self[-2].set_valauto(self[-1].get_len)
         char._cur = char_cur
         char._len_bit = char_lb
Esempio n. 4
0
 def __init__(self, *args, **kwargs):
     Envelope.__init__(self, *args, **kwargs)
     if 'val' not in kwargs or 'off' not in kwargs['val']:
         self['off'].set_valauto(lambda: 5 + (self['opt'].get_len() >> 2))
     self['cs'].set_valauto(lambda: self.checksum())
     self['opt'].set_blauto(lambda: max(0,
                                        (self['off'].get_val() - 5) << 5))
Esempio n. 5
0
    def handle_ul(self, ipbuf):
        # check if we have a TCP SYN
        ip_proto, ip_pay = ord(ipbuf[9:10]), ipbuf[20:]
        if ip_proto != 6:
            # not TCP
            return
        if ip_pay[13:14] != b'\x02':
            # not SYN
            return

        # build the TCP SYN-ACK: invert src / dst ports, seq num (random),
        # ack num (SYN seq num + 1)
        tcpsrc, tcpdst, seq = unpack('!HHI', ip_pay[:8])
        tcp_synack = TCP(val={
            'seq': randint(1, 4294967295),
            'ack': (1 + seq) % 4294967296,
            'src': tcpdst,
            'dst': tcpsrc,
            'SYN': 1,
            'ACK': 1,
            'win': 0x1000
        },
                         hier=1)

        # build the IPv4 header: invert src / dst addr
        ipsrc, ipdst = inet_ntoa(ipbuf[12:16]), inet_ntoa(ipbuf[16:20])
        iphdr = IPv4(val={'src': ipdst, 'dst': ipsrc}, hier=0)
        #
        pkt = Envelope('p', GEN=(iphdr, tcp_synack))
        # send back the TCP SYN-ACK
        self.GTPUd.transfer_to_int(pkt.to_bytes())
Esempio n. 6
0
 def _from_char(self, char):
     if self[-1]._name != 'V':
         # restore the std buffer for handling the value
         self.unset_IE()
     Envelope._from_char(self, char)
     # in case self._IE is defined, use it to decode char instead of V
     if self.DECODE_INNER and self._IE_stat is not None:
         if self._IE is None:
             self._IE = self._IE_stat.clone()
         iebl = self[-1].get_bl()
         ccur, clen = char._cur, char._len_bit
         char._cur -= iebl
         char._len_bit = char._cur + iebl
         try:
             self._IE._from_char(char)
         except:
             log('%s, _from_char: unable to decode IE, %s'\
                 % (self._name, self._IE._name))
         else:
             if char.len_bit() > 0:
                 log('%s, _from_char: uncorrect decoding for IE, %s'\
                     % (self._name, self._IE._name))
             else:
                 # replace V with the IE structure
                 self.replace(self[-1], self._IE)
         char._cur, char._len_bit = ccur, clen
Esempio n. 7
0
 def set_val(self, vals):
     if isinstance(vals, dict) and 'Type' in vals:
         type = vals['Type']
         del vals['Type']
         self.encode(type, **vals)
     else:
         Envelope.set_val(self, vals)
Esempio n. 8
0
 def _from_char(self, char):
     # in case some optional IE are set (with transparency enabled)
     # they are decoded as much as the char buffer allows it
     # 1) decode mandatory part
     Envelope._from_char(self, char)
     # 2) decode optional part
     opts = self._opts[:]
     while char.len_bit() >= 8:
         T4, T8, dec = char.to_uint(4), char.to_uint(8), False
         for i, opt in enumerate(opts):
             # check the list of optional IEs in order
             # opt[0] is the tag length: 4 or 8
             # opt[1] is the tag value: 0 <= T <= 255
             if (opt[0] == 4 and opt[1] == T4) or opt[1] == T8:
                 opt[2]._trans = False
                 opt[2]._from_char(char)
                 dec = True
                 del opts[i]
                 break
         if not dec:
             # unknown IEI
             if self.DEC_BREAK_ON_UNK_IE:
                 log('%s, unknown IE remaining, not decoded' % self._name)
                 break
             else:
                 char._cur += 8
                 self._dec_unk_ie(T8, char)
Esempio n. 9
0
 def __init__(self, *args, **kwargs):
     Envelope.__init__(self, *args, **kwargs)
     self[2].set_valauto(self._set_hwsz_val)
     self[3].set_valauto(self._set_protsz_val)
     self[5].set_blauto(self._set_addrmac_bl)
     self[7].set_blauto(self._set_addrmac_bl)
     self[6].set_blauto(self._set_addr_bl)
     self[8].set_blauto(self._set_addr_bl)
Esempio n. 10
0
 def __init__(self, *args, **kw):
     if 'IE' in kw:
         if isinstance(kw['IE'], (Element, CSN1Obj)):
             self._IE = kw['IE'].clone()
         elif self._SAFE_STAT:
             raise(PycrateErr('IE [__init__]: IE type is {0}, expecting Element'\
                   .format(type(kw['IE']).__name__)))
     Envelope.__init__(self, *args, **kw)
Esempio n. 11
0
 def __init__(self, *args, **kwargs):
     if 'excl' in kwargs:
         self._excl = kwargs['excl']
         del kwargs['excl']
     Envelope.__init__(self, *args, **kwargs)
     self[0].set_valauto(
         lambda: sum([e.get_bl() for i, e in enumerate(self.get_env()._content) \
                      if i not in self._excl])>>3 )
Esempio n. 12
0
 def _from_char(self, char):
     Envelope._from_char(self, char)
     opts_buf = self[18].get_val()
     if opts_buf:
         opts = IPv4Options()
         opts.from_bytes(opts_buf)
         if opts.to_bytes() == opts_buf:
             self.replace(self[18], opts)
Esempio n. 13
0
 def __init__(self, *args, **kwargs):
     Envelope.__init__(self, *args, **kwargs)
     self[1].set_transauto(self._set_cs4_trans)
     self[1].set_dicauto(self._set_cs4_dic)
     self[2].set_transauto(self._set_cs2_trans)
     self[2].set_dicauto(self._set_cs2_dic)
     self[3].set_transauto(self._set_cs2_trans)
     self[3].set_dicauto(self._set_cla_dic)
Esempio n. 14
0
 def _from_char(self, char):
     l = char.len_bit()
     if l <= 32:
         # disable all elements after bit l
         self.disable_from(l)
     elif l > 32:
         # enables some spare bits at the end
         self[-1]._bl = l-32
     Envelope._from_char(self, char)
Esempio n. 15
0
 def __init__(self, *args, **kw):
     if 'IE' in kw:
         if isinstance(kw['IE'], (Element, CSN1Obj)):
             self._IE_stat = kw['IE']
         elif self._SAFE_STAT:
             raise(PycrateErr('IE [__init__]: IE type is {0}, expecting Element'\
                   .format(type(kw['IE']).__name__)))
         del kw['IE']
     Envelope.__init__(self, *args, **kw)
     if self[-1]._name == 'V':
         self._V = self[-1]
Esempio n. 16
0
 def __init__(self, *args, **kwargs):
     Envelope.__init__(self, *args, **kwargs)
     # manage single / hopping channel conditional fields
     self[4].set_transauto(lambda: True
                           if self[3].get_val() == 1 else False)
     self[5].set_transauto(lambda: True
                           if self[3].get_val() == 1 else False)
     self[6].set_transauto(lambda: True
                           if self[3].get_val() == 0 else False)
     self[7].set_transauto(lambda: True
                           if self[3].get_val() == 0 else False)
Esempio n. 17
0
class ChanDesc3(Envelope):
    _GEN = (Uint('TSC', bl=3), Uint('HopChan', bl=1, dic=ChanDescHop_dict),
            Alt(GEN={
                0:
                Envelope('ChanSingle',
                         GEN=(Uint('spare', bl=2,
                                   rep=REPR_HEX), Uint('ARFCN', bl=10))),
                1:
                Envelope('ChanHopping',
                         GEN=(Uint('MAIO', bl=6), Uint('HSN', bl=6)))
            },
                sel=lambda self: self.get_env()[1].get_val()))
Esempio n. 18
0
 def __init__(self, *args, **kw):
     if 'val' in kw:
         val = kw['val']
         del kw['val']
     else:
         val = None
     if 'sec' in kw:
         # used within the NAS LTE EMM stack of corenet
         sec = kw['sec']
         del kw['sec']
     else:
         sec = None
     Envelope.__init__(self, *args, **kw)
     self._sec = sec
     # build a list of (tag length, tag value) for the optional part
     # configure IE set by **kw as non-transparent and set their value
     self._opts, self._rest = [], None
     if val is None:
         # go faster by just looking for optional IE
         for ie in self._content:
             if isinstance(ie,
                           (Type1TV, Type2, Type3TV, Type4TLV, Type6TLVE)):
                 # optional IE
                 T = ie[0]
                 self._opts.append((T.get_bl(), T(), ie))
             elif isinstance(ie, RestOctets):
                 # rest octets
                 self._rest = ie
     else:
         for ie in self._content:
             if isinstance(
                     ie,
                 (Type1V, Type3V, Type4LV, Type6LVE)) and ie._name in val:
                 # setting value for non-optional IE
                 ie.set_val({'V': val[ie._name]})
             elif isinstance(ie, (Type1TV, Type3TV, Type4TLV, Type6TLVE)):
                 # optional IE
                 T = ie[0]
                 self._opts.append((T.get_bl(), T(), ie))
                 if ie._name in val:
                     ie._trans = False
                     ie.set_val({'V': val[ie._name]})
             elif isinstance(ie, Type2):
                 # optional Tag-only IE
                 self._opts.append((8, ie[0](), ie))
                 if ie._name in val:
                     ie._trans = False
             elif isinstance(ie, RestOctets):
                 self._rest = ie
             elif ie._name in val:
                 ie.set_val(val[ie._name])
Esempio n. 19
0
class GroupChanDesc(Envelope):
    _GEN = (Uint('ChanType', bl=5, dic=ChanDescType_dict), Uint('TN', bl=3),
            Uint('TSC', bl=3), Uint('HopChan', bl=1, dic=ChanDescHop_dict),
            Alt(GEN={
                0:
                Envelope('ChanSingle',
                         GEN=(Uint('spare', bl=2,
                                   rep=REPR_HEX), Uint('ARFCN', bl=10))),
                1:
                Envelope('ChanHopping',
                         GEN=(Uint('MAIO', bl=6), Uint('HSN', bl=6)))
            },
                sel=lambda self: self.get_env()[3].get_val()),
            BitMap('MobileAllocChan'))
Esempio n. 20
0
class BARange(Envelope):
    _GEN = (Uint8('Num'),
            Array('Ranges',
                  GEN=Envelope('Range',
                               GEN=(Uint('RANGE_LOWER', bl=10),
                                    Uint('RANGE_HIGHER',
                                         bl=10)))), Buf('spare', rep=REPR_HEX))
Esempio n. 21
0
 def __init__(self, *args, **kwargs):
     # enable to pass IPv4 addr in human-readable format
     if 'val' in kwargs:
         if 'src' in kwargs['val'] and len(kwargs['val']['src']) != 16:
             try:
                 kwargs['val']['src'] = inet_pton(AF_INET6, kwargs['val']['src'])
             except:
                 pass
         if 'dst' in kwargs['val'] and len(kwargs['val']['dst']) != 16:
             try:
                 kwargs['val']['dst'] = inet_pton(AF_INET6, kwargs['val']['dst'])
             except:
                 pass
     Envelope.__init__(self, *args, **kwargs)
     if 'val' not in kwargs or 'plen' not in kwargs['val']:
         self[3].set_valauto(self._set_plen_val)
     if 'val' not in kwargs or 'next' not in kwargs['val']:
         self[4].set_valauto(self._set_next_val)
Esempio n. 22
0
 def encode(self, type, **kwargs):
     """sets the 5GS mobile identity with given type
     
     The given types correspond to the following classes:
     FGSIDTYPE_NO (0)     -> FGSIDNone
     FGSIDTYPE_SUPI (1)   -> FGSIDSUPI
     FGSIDTYPE_GUTI (2)   -> FGSIDGUTI
     FGSIDTYPE_IMEI (3)   -> FGSIDDigit
     FGSIDTYPE_TMSI (4)   -> FGSIDTMSI
     FGSIDTYPE_IMEISV (5) -> FGSIDDigit
     FGSIDTYPE_MAC (6)    -> FGSIDMAC
     7 (undefined)        -> FGSIDUnk
     """
     if not isinstance(type, integer_types) or not 0 <= type <= 7:
         raise(PycrateErr('invalid 5GS identity type: %r' % type))
     # set the appropriate content
     self._set_content(type)
     # pass the value to encode
     Envelope.set_val(self, kwargs)
Esempio n. 23
0
 def __init__(self, *args, **kwargs):
     # enable to pass IPv4 addr in human-readable format
     if 'val' in kwargs:
         if 'src' in kwargs['val'] and len(kwargs['val']['src']) > 4:
             try:
                 kwargs['val']['src'] = inet_aton(kwargs['val']['src'])
             except:
                 pass
         if 'dst' in kwargs['val'] and len(kwargs['val']['dst']) > 4:
             try:
                 kwargs['val']['dst'] = inet_aton(kwargs['val']['dst'])
             except:
                 pass
     Envelope.__init__(self, *args, **kwargs)
     self[1].set_valauto(self._set_hdrwlen_val)
     if 'val' not in kwargs or 'len' not in kwargs['val']:
         self[7].set_valauto(self._set_len_val)
     if 'val' not in kwargs or 'proto' not in kwargs['val']:
         self[14].set_valauto(self._set_prot_val)
     self[15].set_valauto(self.checksum)
     self[18].set_blauto(self._set_opt_bl)
Esempio n. 24
0
 def _from_char(self, char):
     # in case some optional IE are set (with transparency enabled)
     # they are decoded as much as the char buffer allows it
     # 1) decode mandatory part
     Envelope._from_char(self, char)
     # 2) decode optional part
     opts = self._opts[:]
     while char.len_bit() >= 8:
         T4, T8, dec = char.to_uint(4), char.to_uint(8), False
         for i, opt in enumerate(opts):
             # check the list of optional IEs in order
             if opt[1] in (T4, T8):
                 opt[2]._trans = False
                 opt[2]._from_char(char)
                 dec = True
                 del opts[i]
                 break
         if not dec:
             # unknown IEI
             char._cur += 8
             self._dec_unk_ie(T8, char)
Esempio n. 25
0
 def set_val(self, vals):
     ti, disp = None, True
     if isinstance(vals, integer_types):
         ti = vals
         disp = False
     elif isinstance(vals, dict) and 'TI' in vals:
         ti = vals['TI']
     if ti is not None:
         if 0 <= ti < 7:
             self[1].set_val(ti)
             self[3].set_trans(True)
             self[4].set_trans(True)
             self[4].set_val(None)
         elif ti < 128:
             # extended
             self[1].set_val(7)
             self[3].set_trans(False)
             self[4].set_trans(False)
             self[4].set_val(ti)
     if disp:
         Envelope.set_val(self, vals)
Esempio n. 26
0
 def __init__(self, *args, **kwargs):
     if 'val' in kwargs:
         # enable to pass IPv4 addr in human-readable format and convert them
         if 'src' in kwargs['val'] and len(kwargs['val']['src']) > 4:
             try:
                 kwargs['val']['src'] = inet_aton(kwargs['val']['src'])
             except Exception:
                 pass
         if 'dst' in kwargs['val'] and len(kwargs['val']['dst']) > 4:
             try:
                 kwargs['val']['dst'] = inet_aton(kwargs['val']['dst'])
             except Exception:
                 pass
     Envelope.__init__(self, *args, **kwargs)
     self['hdr_wlen'].set_valauto(lambda: 5 + (self['opt'].get_len()>>2))
     if 'val' not in kwargs or 'len' not in kwargs['val']:
         self['len'].set_valauto(lambda: self._len_val())
     if 'val' not in kwargs or 'proto' not in kwargs['val']:
         self['proto'].set_valauto(lambda: self._proto_val())
     self['hdr_cs'].set_valauto(lambda: checksum(self[:15].to_bytes() + b'\0\0' + self[16:].to_bytes()))
     self['opt'].set_blauto(lambda: max(0, (self['hdr_wlen'].get_val()-5)<<5))
Esempio n. 27
0
    def handle_ul(self, ipbuf):
        # check if we have an UDP/53 request
        ip_proto, (udpsrc, udpdst) = ord(ipbuf[9]), unpack('!HH', ipbuf[20:24])
        if ip_proto != 17:
            # not UDP
            return
        if udpdst != 53:
            # not DNS
            return

        # build the UDP / DNS response: invert src / dst UDP ports
        if self.UDP_CS:
            udp = UDP(val={'src': udpdst, 'dst': udpsrc}, hier=1)
        else:
            udp = UDP(val={'src': udpdst, 'dst': udpsrc, 'cs': 0}, hier=1)
        # DNS request: transaction id, flags, questions, queries
        dnsreq = ipbuf[28:]
        transac_id, questions, queries = dnsreq[0:2], \
                                         unpack('!H', dnsreq[4:6])[0], \
                                         dnsreq[12:]
        if questions > 1:
            # not supported
            self._log('WNG', '%i questions, unsupported' % questions)
        # DNS response: transaction id, flags, questions, answer RRs,
        # author RRs, add RRs, queries, answers, autor nameservers, add records
        if self.RAND:
            ip_resp = _urandom(4)
        else:
            ip_resp = inet_aton(self.IP_RESP)
        dnsresp = b''.join(
            (transac_id, b'\x81\x80\0\x01\0\x01\0\0\0\0', queries,
             b'\xc0\x0c\0\x01\0\x01\0\0\0\x20\0\x04', ip_resp))

        # build the IPv4 header: invert src / dst addr
        ipsrc, ipdst = inet_ntoa(ipbuf[12:16]), inet_ntoa(ipbuf[16:20])
        iphdr = IPv4(val={'src': ipdst, 'dst': ipsrc}, hier=0)
        #
        pkt = Envelope('p', GEN=(iphdr, udp, Buf('dns', val=dnsresp, hier=2)))
        # send back the DNS response
        self.GTPUd.transfer_to_int(pkt.to_bytes())
Esempio n. 28
0
 def __init__(self, *args, **kwargs):
     Envelope.__init__(self, *args, **kwargs)
     self[2].set_valauto(self._set_type_val)
Esempio n. 29
0
 def __init__(self, *args, **kwargs):
     Envelope.__init__(self, *args, **kwargs)
     if 'val' not in kwargs or 'off' not in kwargs['val']:
         self[4].set_valauto(self._set_off_val)
     self[16].set_valauto(self.checksum)
     self[18].set_blauto(self._set_opt_bl)
Esempio n. 30
0
 def __init__(self, *args, **kwargs):
     Envelope.__init__(self, *args, **kwargs)
     if 'val' not in kwargs or 'len' not in kwargs['val']:
         self[2].set_valauto(self._set_len_val)
     self[3].set_valauto(self.checksum)