diff --git a/scapy/contrib/gtp.py b/scapy/contrib/gtp.py index 2913c575b8c..168c4d10869 100644 --- a/scapy/contrib/gtp.py +++ b/scapy/contrib/gtp.py @@ -33,6 +33,7 @@ FlagsField, IPField, IntField, + MultipleTypeField, PacketListField, ShortField, StrFixedLenField, @@ -657,12 +658,24 @@ class IE_ProtocolConfigurationOptions(IE_TLV): class IE_GSNAddress(IE_TLV): name = "GSN Address" + deprecated_fields = { + "ipv4_address": ("address", "2.8.1"), + "ipv6_address": ("address", "2.8.1"), + } fields_desc = [ByteEnumField("ietype", 133, IEType), ShortField("length", None), - ConditionalField(IPField("ipv4_address", RandIP()), - lambda pkt: pkt.length == 4), - ConditionalField(IP6Field("ipv6_address", '::1'), - lambda pkt: pkt.length == 16)] + MultipleTypeField( + [ + (IP6Field("address", "::1"), + (lambda pkt: pkt.length == 16, + lambda pkt, val: pkt.length == 16 or ( + pkt.length is None and ":" in str(val)))), + (IPField("address", RandIP()), + (lambda pkt: pkt.length == 4, + lambda pkt, val: pkt.length in (4, None))), + ], + StrFixedLenField("address", None, + length_from=lambda pkt: pkt.length))] class IE_MSInternationalNumber(IE_TLV): @@ -890,13 +903,24 @@ class IE_EvolvedAllocationRetentionPriority(IE_TLV): class IE_CharginGatewayAddress(IE_TLV): name = "Charging Gateway Address" + deprecated_fields = { + "ipv4_address": ("address", "2.8.1"), + "ipv6_address": ("address", "2.8.1"), + } fields_desc = [ByteEnumField("ietype", 251, IEType), - ShortField("length", 4), - ConditionalField(IPField("ipv4_address", "127.0.0.1"), - lambda - pkt: pkt.length == 4), - ConditionalField(IP6Field("ipv6_address", "::1"), lambda - pkt: pkt.length == 16)] + ShortField("length", None), + MultipleTypeField( + [ + (IP6Field("address", "::1"), + (lambda pkt: pkt.length == 16, + lambda pkt, val: pkt.length == 16 or ( + pkt.length is None and ":" in str(val)))), + (IPField("address", "127.0.0.1"), + (lambda pkt: pkt.length == 4, + lambda pkt, val: pkt.length in (4, None))), + ], + StrFixedLenField("address", None, + length_from=lambda pkt: pkt.length))] class IE_PrivateExtension(IE_TLV): @@ -986,8 +1010,8 @@ def answers(self, other): class GTPCreatePDPContextRequest(Packet): # 3GPP TS 29.060 V9.1.0 (2009-12) name = "GTP Create PDP Context Request" - fields_desc = [PacketListField("IE_list", [IE_TEIDI(), IE_NSAPI(), IE_GSNAddress(length=4, ipv4_address=RandIP()), # noqa: E501 - IE_GSNAddress(length=4, ipv4_address=RandIP()), # noqa: E501 + fields_desc = [PacketListField("IE_list", [IE_TEIDI(), IE_NSAPI(), IE_GSNAddress(length=4, address=RandIP()), # noqa: E501 + IE_GSNAddress(length=4, address=RandIP()), # noqa: E501 IE_NotImplementedTLV(ietype=135, length=15, data=RandString(15))], # noqa: E501 IE_Dispatcher)] @@ -1064,7 +1088,7 @@ class GTPPDUNotificationRequest(Packet): IE_TEICP(TEICI=RandInt()), IE_EndUserAddress(PDPTypeNumber=0x21), # noqa: E501 IE_AccessPointName(), - IE_GSNAddress(ipv4_address="127.0.0.1"), # noqa: E501 + IE_GSNAddress(address="127.0.0.1"), # noqa: E501 ], IE_Dispatcher)] diff --git a/test/contrib/gtp.uts b/test/contrib/gtp.uts index 7461b7e3f02..d594449b40f 100644 --- a/test/contrib/gtp.uts +++ b/test/contrib/gtp.uts @@ -262,36 +262,57 @@ ie = IE_ProtocolConfigurationOptions( ie.ietype == 132 and ie.Protocol_Configuration == b'\x80\xc0#\x06\x01\x01\x00\x06\x00\x00\x80!\x10\x01\x01\x00\x10\x81\x06\x00\x00\x00\x00\x83\x06\x00\x00\x00\x00' = IE_GSNAddress(), simple build/dissect IPv4 -r = raw(IE_GSNAddress(length=4, ipv4_address='10.42.0.1')) +r = raw(IE_GSNAddress(length=4, address='10.42.0.1')) assert r == b'\x85\x00\x04\x0a\x2a\x00\x01' ie = IE_GSNAddress(r) -ie.ietype == 133 and ie.ipv4_address == '10.42.0.1' +ie.ietype == 133 and ie.address == '10.42.0.1' = IE_GSNAddress(), simple build/dissect IPv6 -r = raw(IE_GSNAddress(length=16, ipv6_address='fd01:1::1')) +r = raw(IE_GSNAddress(length=16, address='fd01:1::1')) assert r == b'\x85\x00\x10\xfd\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01' ie = IE_GSNAddress(r) -ie.ietype == 133 and ie.ipv6_address == 'fd01:1::1' +ie.ietype == 133 and ie.address == 'fd01:1::1' = IE_GSNAddress(), dissect IPv4 h = "3333333333332222222222228100838408004588005400000000fd1182850a2a00010a2a0002084b084b00406b463213003031146413c18000000180109181ba027fcf701a8c8500040a2a00018500040a2a000187000f0213921f7396d1fe7482ffff004a00f7a71e0a" gtp = Ether(hex_bytes(h)) ie = gtp.IE_list[3] -ie.ietype == 133 and ie.ipv4_address == '10.42.0.1' +ie.ietype == 133 and ie.address == '10.42.0.1' = IE_GSNAddress(), dissect IPv6 h = "33333333333322222222222286dd60000000002c1140fd010001000000000000000000000001fd01000100000000000000000000000208680868002ce2e9321a001c000000000000000010000004d2850010fd010001000000000000000000000001" gtp = Ether(hex_bytes(h)) ie = gtp.IE_list[1] -ie.ietype == 133 and ie.ipv6_address == 'fd01:1::1' +ie.ietype == 133 and ie.address == 'fd01:1::1' = IE_GSNAddress(), basic instantiation IPv4 -ie = IE_GSNAddress(length=4, ipv4_address='10.42.0.1') -ie.ietype == 133 and ie.ipv4_address == '10.42.0.1' +ie = IE_GSNAddress(length=4, address='10.42.0.1') +ie.ietype == 133 and ie.address == '10.42.0.1' = IE_GSNAddress(), basic instantiation IPv6 -ie = IE_GSNAddress(length=16, ipv6_address='fd01:1::1') -ie.ietype == 133 and ie.ipv6_address == 'fd01:1::1' +ie = IE_GSNAddress(length=16, address='fd01:1::1') +ie.ietype == 133 and ie.address == 'fd01:1::1' + += IE_GSNAddress(), build without length +ie = IE_GSNAddress(address='10.42.0.1') +assert raw(ie) == hex_bytes("850004" "0a2a0001") +ie = IE_GSNAddress(raw(ie)) +assert ie.length == 4 and ie.address == '10.42.0.1' +ie = IE_GSNAddress(address='fd01:1::1') +assert raw(ie) == hex_bytes("850010" "fd010001000000000000000000000001") +ie = IE_GSNAddress(raw(ie)) +assert ie.length == 16 and ie.address == 'fd01:1::1' +assert all(len(raw(ie)) == 7 for ie in GTPUpdatePDPContextRequest().IE_list + if isinstance(ie, IE_GSNAddress)) + += IE_GSNAddress(), deprecated ipv4_address and ipv6_address +import warnings +with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + assert raw(IE_GSNAddress(ipv4_address='10.42.0.1')) == hex_bytes("850004" "0a2a0001") + ie = IE_GSNAddress(ipv6_address='fd01:1::1') + assert raw(ie) == hex_bytes("850010" "fd010001000000000000000000000001") + assert ie.ipv6_address == 'fd01:1::1' = IE_MSInternationalNumber(), dissect h = "333333333333222222222222810083840800458800c300000000fc1184e50a2a00010a2a00024a4d084b00af41993210009f79504a3e048e00000202081132547600000332f42004d27b0ffc10a692773d1158da9e2214051a0a00800002f1218300070661616161616184001d80c02306010100060000802110010100108106000000008306000000008500040a2a00018500040a2a00018600079111111111111187000d0213621f73967373741affff0094000120970001029800080032f42004d204d299000240009a0008111111111111000081182fb2" @@ -397,9 +418,20 @@ ie.ietype == 191 and ie.PCI == 1 = IE_CharginGatewayAddress(), basic instantiation ie = IE_CharginGatewayAddress() -assert ie.ietype == 251 and ie.ipv4_address == '127.0.0.1' +assert ie.ietype == 251 and ie.address == '127.0.0.1' +assert raw(ie) == hex_bytes("fb0004" "7f000001") ie = IE_CharginGatewayAddress(length=16) -assert ie.ietype == 251 and ie.ipv6_address == '::1' +assert ie.ietype == 251 and ie.address == '::1' +ie = IE_CharginGatewayAddress(address='2001:db8::2') +assert raw(ie) == hex_bytes("fb0010" "20010db8000000000000000000000002") + += IE_CharginGatewayAddress(), build/dissect with length +r = raw(IE_CharginGatewayAddress(length=4, address='10.42.0.2')) +assert r == hex_bytes("fb0004" "0a2a0002") +assert IE_CharginGatewayAddress(r).address == '10.42.0.2' +r = raw(IE_CharginGatewayAddress(length=16, address='fd01:1::2')) +assert r == hex_bytes("fb0010" "fd010001000000000000000000000002") +assert IE_CharginGatewayAddress(r).address == 'fd01:1::2' = IE_PrivateExtension(), basic instantiation ie = IE_PrivateExtension(extention_value='hello')