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)
def __init__(self): Layer.__init__(self) self.insert(1, Layer('WR', ReprName='Withdrawn Routes')) self.insert(3, Layer('TPA', ReprName='Total Path Attribute')) # handle "Withdrawn Routes" self.WRLen > self.WR self.WRLen.PtFunc = lambda wr: len(wr) # handle "Path Attributes" self.TPALen > self.TPA self.TPALen.PtFunc = lambda tpa: len(tpa) # finally handle net reachibility info self.NLRI.Len = (self.get_header, self.WRLen, self.TPALen) self.NLRI.LenFunc = lambda args: args[0]().len() - \ (23 + args[1]() + args[2]())
def parse(self, buf=''): self.__init__(self.CallName) self.map(buf) L = len(self) # # parse nested BER_TLV structures within the Value if self[0].PC(): # indefinite form indef = self[1]() == -1 # parsing further internal Value buf = str(self[2]) inner = [] marker = None while buf: tlv = BER_TLV() tlv.parse(buf) buf = buf[len(tlv):] if indef and (tlv[0]() == 0 and tlv[1]() == 0): marker = tlv marker.CallName = '_end_' break else: inner.append(tlv) if inner: self.remove(self[2]) V = Layer('V') V.extend(inner) self.append(V) if marker: self.append(marker) # returns the length parsed return L
def encode_set_of(self, obj): V = Layer('V') for val in obj._val: obj._cont._val = val obj._cont._encode() V.append(obj._cont._msg) # obj._cont._msg = None obj._msg = BER_TLV(obj.get_name()) obj._msg.set(V) self.handle_tag_enc(obj)
def encode_set(self, obj): V = Layer('V') for name in obj._cont: if name in obj._val: comp = obj._cont[name] comp._val = obj._val[name] comp._encode() V.append(comp._msg) comp._msg = None # obj._msg = BER_TLV(obj.get_name()) obj._msg.set(V) self.handle_tag_enc(obj)
def decode_bit_str_val(self, obj): tlv = self.handle_tag_dec(obj) # obj._val: (BE uint value, BE uint bit length) # map to a Layer including the pad_len initial octet v_str = str(tlv[2]) if len(v_str) > 1: pad_len = ord(v_str[0]) bit_len = 8 * (len(v_str) - 1) - pad_len V = Layer('V') V.append(Int('pad_len'), Type='uint8') V.append(Bit('val', BitLen=bit_len, Repr=self._REPR_BIT_STR)) if pad_len > 0: V.append(Bit('pad', BitLen=pad_len, Repr=self._REPR_BIT_STR)) V.map(v_str) tlv.set(V) # obj._val = (V[1](), bit_len) else: obj._val = (0, 0)
def __init__(self): Layer.__init__(self) self.append(Layer('Options')) self.OptLen > self.Options self.OptLen.PtFunc = lambda opt: len(opt)