Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions scapy/contrib/gtp.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
IPField, PacketListField, ShortField, StrFixedLenField, StrLenField, \
XBitField, XByteField, XIntField
from scapy.layers.inet import IP, UDP
from scapy.layers.inet6 import IP6Field
from scapy.layers.inet6 import IPv6, IP6Field
from scapy.layers.ppp import PPP
from scapy.modules.six.moves import range
from scapy.packet import bind_layers, Packet, Raw
from scapy.packet import bind_layers, bind_bottom_up, bind_top_down, \
Packet, Raw
from scapy.volatile import RandInt, RandIP, RandNum, RandString


Expand Down Expand Up @@ -254,6 +256,19 @@ class GTP_U_Header(GTPHeader):
# encapsulated in G-PDUs. A G-PDU is a packet including a GTP-U header and a T-PDU. The Path Protocol # noqa: E501
# defines the path and the GTP-U header defines the tunnel. Several tunnels may be multiplexed on a single path. # noqa: E501

def guess_payload_class(self, payload):
# Snooped from Wireshark
# https://github.com/boundary/wireshark/blob/07eade8124fd1d5386161591b52e177ee6ea849f/epan/dissectors/packet-gtp.c#L8195 # noqa: E501
if self.gtp_type == 255:
sub_proto = orb(payload[0])
if sub_proto >= 0x45 and sub_proto <= 0x4e:
return IP
elif (sub_proto & 0xf0) == 0x60:
return IPv6
else:
return PPP
return GTPHeader.guess_payload_class(self, payload)


# Some gtp_types have to be associated with a certain type of header
GTPforcedTypes = {
Expand Down Expand Up @@ -887,8 +902,9 @@ class GTPmorethan1500(Packet):


# Bind GTP-C
bind_layers(UDP, GTPHeader, dport=2123)
bind_layers(UDP, GTPHeader, sport=2123)
bind_bottom_up(UDP, GTPHeader, dport=2123)
bind_bottom_up(UDP, GTPHeader, sport=2123)
bind_layers(UDP, GTPHeader, dport=2123, sport=2123)
bind_layers(GTPHeader, GTPEchoRequest, gtp_type=1, S=1)
bind_layers(GTPHeader, GTPEchoResponse, gtp_type=2, S=1)
bind_layers(GTPHeader, GTPCreatePDPContextRequest, gtp_type=16)
Expand All @@ -903,7 +919,10 @@ class GTPmorethan1500(Packet):
bind_layers(GTPHeader, GTP_PDCP_PDU_ExtensionHeader, next_ex=192, E=1)

# Bind GTP-U
bind_layers(UDP, GTP_U_Header, dport=2152)
bind_layers(UDP, GTP_U_Header, sport=2152)
bind_bottom_up(UDP, GTP_U_Header, dport=2152)
bind_bottom_up(UDP, GTP_U_Header, sport=2152)
bind_layers(UDP, GTP_U_Header, dport=2152, sport=2152)
bind_layers(GTP_U_Header, GTPErrorIndication, gtp_type=26, S=1)
bind_layers(GTP_U_Header, IP, gtp_type=255)
bind_top_down(GTP_U_Header, IP, gtp_type=255)
bind_top_down(GTP_U_Header, IPv6, gtp_type=255)
bind_top_down(GTP_U_Header, PPP, gtp_type=255)
15 changes: 15 additions & 0 deletions scapy/contrib/gtp.uts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@ assert a.E == a.S == a.PN == 0
a = GTPHeader(raw(GTP_U_Header()/GTPErrorIndication()))
assert isinstance(a, GTP_U_Header)

= GTP_U_Header sub layers

a = IPv6(raw(IPv6()/UDP()/GTP_U_Header()/IPv6()))
b = IPv6(raw(IPv6()/UDP()/GTP_U_Header()/IP()))
c = IP(raw(IP()/UDP()/GTP_U_Header()/IPv6()))
d = IP(raw(IP()/UDP()/GTP_U_Header()/IP()))

assert isinstance(a[GTP_U_Header].payload, IPv6)
assert isinstance(b[GTP_U_Header].payload, IP)
assert isinstance(c[GTP_U_Header].payload, IPv6)
assert isinstance(d[GTP_U_Header].payload, IP)

a = IP(raw(IP()/UDP()/GTP_U_Header()/PPP()))
assert isinstance(a[GTP_U_Header].payload, PPP)

= GTPCreatePDPContextRequest(), basic instantiation
gtp = IP(src="127.0.0.1")/UDP(dport=2123)/GTPHeader(teid=2807)/GTPCreatePDPContextRequest()
gtp.dport == 2123 and gtp.teid == 2807 and len(gtp.IE_list) == 5
Expand Down