laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/35279?usp=email )
Change subject: move {enc,dec}_addr_tlv functions from pySim.util to pySim.legacy.util ......................................................................
move {enc,dec}_addr_tlv functions from pySim.util to pySim.legacy.util
In the previous commit we've stopped using those functions from modern pySim-shell code. Hence, the only remaining user is the legacy tools, so we can move the code to the legacy module.
Change-Id: I6f18ccb36fc33bc204c01f9ece135676510e67ec --- M pySim/legacy/cards.py M pySim/legacy/utils.py M pySim/utils.py 3 files changed, 93 insertions(+), 81 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/79/35279/1
diff --git a/pySim/legacy/cards.py b/pySim/legacy/cards.py index 496ce78..9d1e2c1 100644 --- a/pySim/legacy/cards.py +++ b/pySim/legacy/cards.py @@ -8,11 +8,10 @@
from pySim.cards import SimCardBase, UiccCardBase from pySim.utils import dec_iccid, enc_iccid, dec_imsi, enc_imsi, dec_msisdn, enc_msisdn -from pySim.utils import dec_addr_tlv, enc_addr_tlv from pySim.utils import enc_plmn, get_addr_type from pySim.utils import is_hex, h2b, b2h, h2s, s2h, lpad, rpad from pySim.legacy.utils import enc_ePDGSelection, format_xplmn_w_act, format_xplmn, dec_st, enc_st -from pySim.legacy.utils import format_ePDGSelection +from pySim.legacy.utils import format_ePDGSelection, dec_addr_tlv, enc_addr_tlv from pySim.legacy.ts_51_011 import EF, DF from pySim.legacy.ts_31_102 import EF_USIM_ADF_map from pySim.legacy.ts_31_103 import EF_ISIM_ADF_map diff --git a/pySim/legacy/utils.py b/pySim/legacy/utils.py index 1b6b5d1..d79253b 100644 --- a/pySim/legacy/utils.py +++ b/pySim/legacy/utils.py @@ -210,3 +210,82 @@ res['epdg_priority'] = epdg_priority_str res['epdg_fqdn_format'] = epdg_fqdn_format_str == '00' and 'Operator Identifier FQDN' or 'Location based FQDN' return res + + +def dec_addr_tlv(hexstr): + """ + Decode hex string to get EF.P-CSCF Address or EF.ePDGId or EF.ePDGIdEm. + See 3GPP TS 31.102 version 13.4.0 Release 13, section 4.2.8, 4.2.102 and 4.2.104. + """ + + # Convert from hex str to int bytes list + addr_tlv_bytes = h2i(hexstr) + + # Get list of tuples containing parsed TLVs + tlvs = TLV_parser(addr_tlv_bytes) + + for tlv in tlvs: + # tlv = (T, L, [V]) + # T = Tag + # L = Length + # [V] = List of value + + # Invalid Tag value scenario + if tlv[0] != 0x80: + continue + + # Empty field - Zero length + if tlv[1] == 0: + continue + + # Uninitialized field + if all([v == 0xff for v in tlv[2]]): + continue + + # First byte in the value has the address type + addr_type = tlv[2][0] + # TODO: Support parsing of IPv6 + # Address Type: 0x00 (FQDN), 0x01 (IPv4), 0x02 (IPv6), other (Reserved) + if addr_type == 0x00: # FQDN + # Skip address tye byte i.e. first byte in value list + content = tlv[2][1:] + return (i2s(content), '00') + + elif addr_type == 0x01: # IPv4 + # Skip address tye byte i.e. first byte in value list + # Skip the unused byte in Octect 4 after address type byte as per 3GPP TS 31.102 + ipv4 = tlv[2][2:] + content = '.'.join(str(x) for x in ipv4) + return (content, '01') + else: + raise ValueError("Invalid address type") + + return (None, None) + + +def enc_addr_tlv(addr, addr_type='00'): + """ + Encode address TLV object used in EF.P-CSCF Address, EF.ePDGId and EF.ePDGIdEm. + See 3GPP TS 31.102 version 13.4.0 Release 13, section 4.2.8, 4.2.102 and 4.2.104. + + Default values: + - addr_type: 00 - FQDN format of Address + """ + + s = "" + + # TODO: Encoding of IPv6 address + if addr_type == '00': # FQDN + hex_str = s2h(addr) + s += '80' + ('%02x' % ((len(hex_str)//2)+1)) + '00' + hex_str + elif addr_type == '01': # IPv4 + ipv4_list = addr.split('.') + ipv4_str = "" + for i in ipv4_list: + ipv4_str += ('%02x' % (int(i))) + + # Unused bytes shall be set to 'ff'. i.e 4th Octet after Address Type is not used + # IPv4 Address is in octet 5 to octet 8 of the TLV data object + s += '80' + ('%02x' % ((len(ipv4_str)//2)+2)) + '01' + 'ff' + ipv4_str + + return s diff --git a/pySim/utils.py b/pySim/utils.py index 44800fb..3b9731d 100644 --- a/pySim/utils.py +++ b/pySim/utils.py @@ -751,85 +751,6 @@ return ret
-def dec_addr_tlv(hexstr): - """ - Decode hex string to get EF.P-CSCF Address or EF.ePDGId or EF.ePDGIdEm. - See 3GPP TS 31.102 version 13.4.0 Release 13, section 4.2.8, 4.2.102 and 4.2.104. - """ - - # Convert from hex str to int bytes list - addr_tlv_bytes = h2i(hexstr) - - # Get list of tuples containing parsed TLVs - tlvs = TLV_parser(addr_tlv_bytes) - - for tlv in tlvs: - # tlv = (T, L, [V]) - # T = Tag - # L = Length - # [V] = List of value - - # Invalid Tag value scenario - if tlv[0] != 0x80: - continue - - # Empty field - Zero length - if tlv[1] == 0: - continue - - # Uninitialized field - if all([v == 0xff for v in tlv[2]]): - continue - - # First byte in the value has the address type - addr_type = tlv[2][0] - # TODO: Support parsing of IPv6 - # Address Type: 0x00 (FQDN), 0x01 (IPv4), 0x02 (IPv6), other (Reserved) - if addr_type == 0x00: # FQDN - # Skip address tye byte i.e. first byte in value list - content = tlv[2][1:] - return (i2s(content), '00') - - elif addr_type == 0x01: # IPv4 - # Skip address tye byte i.e. first byte in value list - # Skip the unused byte in Octect 4 after address type byte as per 3GPP TS 31.102 - ipv4 = tlv[2][2:] - content = '.'.join(str(x) for x in ipv4) - return (content, '01') - else: - raise ValueError("Invalid address type") - - return (None, None) - - -def enc_addr_tlv(addr, addr_type='00'): - """ - Encode address TLV object used in EF.P-CSCF Address, EF.ePDGId and EF.ePDGIdEm. - See 3GPP TS 31.102 version 13.4.0 Release 13, section 4.2.8, 4.2.102 and 4.2.104. - - Default values: - - addr_type: 00 - FQDN format of Address - """ - - s = "" - - # TODO: Encoding of IPv6 address - if addr_type == '00': # FQDN - hex_str = s2h(addr) - s += '80' + ('%02x' % ((len(hex_str)//2)+1)) + '00' + hex_str - elif addr_type == '01': # IPv4 - ipv4_list = addr.split('.') - ipv4_str = "" - for i in ipv4_list: - ipv4_str += ('%02x' % (int(i))) - - # Unused bytes shall be set to 'ff'. i.e 4th Octet after Address Type is not used - # IPv4 Address is in octet 5 to octet 8 of the TLV data object - s += '80' + ('%02x' % ((len(ipv4_str)//2)+2)) + '01' + 'ff' + ipv4_str - - return s - - def is_hex(string: str, minlen: int = 2, maxlen: Optional[int] = None) -> bool: """ Check if a string is a valid hexstring