diff --git a/scapy/contrib/gtp.py b/scapy/contrib/gtp.py
index bdcb28f05735d483b394096cdc29ffc0c029d06f..92f7d9f93d04146fe3cd8f4618107a8a4e21d394 100644
--- a/scapy/contrib/gtp.py
+++ b/scapy/contrib/gtp.py
@@ -41,7 +41,7 @@ GTPmessageType = {   1: "echo_request",
                     21: "delete_pdp_context_res",
                     26: "error_indication",
                     27: "pdu_notification_req",
-                   255: "gtp_u_header" }
+                   255: "g_pdu" }
 
 IEType = {   1: "Cause",
              2: "IMSI",
@@ -131,6 +131,17 @@ Selection_Mode = { 11111100: "MS or APN",
 TrueFalse_value = {254: "False",
                    255: "True"}
 
+# http://www.arib.or.jp/IMT-2000/V720Mar09/5_Appendix/Rel8/29/29281-800.pdf
+ExtensionHeadersTypes = {
+        0: "No more extension headers",
+        1: "Reserved",
+        2: "Reserved",
+        64: "UDP Port",
+        192: "PDCP PDU Number",
+        193: "Reserved",
+        194: "Reserved"
+    }
+
 
 class TBCDByteField(StrFixedLenField):
 
@@ -166,6 +177,16 @@ class TBCDByteField(StrFixedLenField):
 
 TBCD_TO_ASCII = "0123456789*#abc"
 
+class GTP_UDPPort_ExtensionHeader(Packet):
+    fields_desc=[ ShortField("length", 0x40),
+                  BitField("udp_port", None, 48),
+                  ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ]
+
+class GTP_PDCP_PDU_ExtensionHeader(Packet):
+    fields_desc=[ ShortField("length", 0x01),
+                  ByteField("pdcp_pdu", None),
+                  ByteField("pdcp_pdu", None),
+                  ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ]
 
 class GTPHeader(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
@@ -174,11 +195,14 @@ class GTPHeader(Packet):
                   BitField("PT", 1, 1),
                   BitField("reserved", 0, 1),
                   BitField("E", 0, 1),
-                  BitField("S", 1, 1),
+                  BitField("S", 0, 1),
                   BitField("PN", 0, 1),
                   ByteEnumField("gtp_type", None, GTPmessageType),
                   ShortField("length", None),
-                  IntField("teid", 0) ]
+                  IntField("teid", 0),
+                  ConditionalField(XBitField("seq", 0, 16), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
+                  ConditionalField(ByteField("npdu", 0), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
+                  ConditionalField(ByteEnumField("next_ex", 0, ExtensionHeadersTypes), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1), ]
 
     def post_build(self, p, pay):
         p += pay
@@ -197,19 +221,17 @@ class GTPHeader(Packet):
 
     @classmethod
     def dispatch_hook(cls, _pkt=None, *args, **kargs):
-        if _pkt and len(_pkt) >= 1:
-            if (struct.unpack("B", _pkt[0])[0] >> 5) & 0x7 == 2:
-                from . import gtp_v2
-                return gtp_v2.GTPHeader
-        return GTPHeader
-
+        if _pkt and len(_pkt) >= 8:
+            if struct.unpack("!B", _pkt[1:2])[0] == 255:
+                return GTP_U_Header
+        return cls
 
 class GTPEchoRequest(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP Echo Request"
     fields_desc = [ XBitField("seq", 0, 16),
                     ByteField("npdu", 0),
-                    ByteField("next_ex", 0),]
+                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),]
 
     def hashret(self):
         return struct.pack("H", self.seq)
@@ -681,27 +703,24 @@ ietypecls = {1: IE_Cause,
 
 
 def IE_Dispatcher(s):
-  """Choose the correct Information Element class."""
-
-  if len(s) < 1:
-    return Raw(s)
-
-  # Get the IE type
-  ietype = ord(s[0])
-  cls = ietypecls.get(ietype, Raw)
-
-  # if ietype greater than 128 are TLVs
-  if cls == Raw and ietype & 128 == 128:
-    cls = IE_NotImplementedTLV
-
-  return cls(s)
+    """Choose the correct Information Element class."""
+    if len(s) < 1:
+        return Raw(s)
+    # Get the IE type
+    ietype = ord(s[0])
+    cls = ietypecls.get(ietype, Raw)
+
+    # if ietype greater than 128 are TLVs
+    if cls == Raw and ietype & 128 == 128:
+        cls = IE_NotImplementedTLV
+    return cls(s)
 
 class GTPEchoResponse(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP Echo Response"
     fields_desc = [ XBitField("seq", 0, 16),
                     ByteField("npdu", 0),
-                    ByteField("next_ex", 0),
+                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
                     PacketListField("IE_list", [], IE_Dispatcher) ]
 
     def hashret(self):
@@ -716,7 +735,7 @@ class GTPCreatePDPContextRequest(Packet):
     name = "GTP Create PDP Context Request"
     fields_desc = [ ShortField("seq", RandShort()),
                     ByteField("npdu", 0),
-                    ByteField("next_ex", 0),
+                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
                     PacketListField("IE_list", [ IE_TEIDI(), IE_NSAPI(), IE_GSNAddress(),
                                                  IE_GSNAddress(),
                                                  IE_NotImplementedTLV(ietype=135, length=15,data=RandString(15)) ],
@@ -729,7 +748,7 @@ class GTPCreatePDPContextResponse(Packet):
     name = "GTP Create PDP Context Response"
     fields_desc = [ ShortField("seq", RandShort()),
                     ByteField("npdu", 0),
-                    ByteField("next_ex", 0),
+                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
                     PacketListField("IE_list", [], IE_Dispatcher) ]
 
     def hashret(self):
@@ -744,7 +763,7 @@ class GTPUpdatePDPContextRequest(Packet):
     name = "GTP Update PDP Context Request"
     fields_desc = [ShortField("seq", RandShort()),
                    ByteField("npdu", 0),
-                   ByteField("next_ex", 0),
+                   ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
                    PacketListField("IE_list", [
                        IE_Cause(),
                        IE_Recovery(),
@@ -776,7 +795,7 @@ class GTPUpdatePDPContextResponse(Packet):
     name = "GTP Update PDP Context Response"
     fields_desc = [ShortField("seq", RandShort()),
                    ByteField("npdu", 0),
-                   ByteField("next_ex", 0),
+                   ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
                    PacketListField("IE_list", None, IE_Dispatcher)]
 
     def hashret(self):
@@ -796,7 +815,7 @@ class GTPDeletePDPContextRequest(Packet):
     name = "GTP Delete PDP Context Request"
     fields_desc = [ XBitField("seq", 0, 16),
                     ByteField("npdu", 0),
-                    ByteField("next_ex", 0),
+                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
                     PacketListField("IE_list", [], IE_Dispatcher) ]
 
 class GTPDeletePDPContextResponse(Packet):
@@ -812,40 +831,22 @@ class GTPPDUNotificationRequest(Packet):
     name = "GTP PDU Notification Request"
     fields_desc = [ XBitField("seq", 0, 16),
                     ByteField("npdu", 0),
-                    ByteField("next_ex", 0),
+                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
                     PacketListField("IE_list", [ IE_IMSI(),
                         IE_TEICP(TEICI=RandInt()),
                         IE_EndUserAddress(PDPTypeNumber=0x21),
                         IE_AccessPointName(),
                         IE_GSNAddress(address="127.0.0.1"),
                         ], IE_Dispatcher) ]
+                    
 
-class GTP_U_Header(Packet):
+class GTP_U_Header(GTPHeader):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP-U Header"
     # GTP-U protocol is used to transmit T-PDUs between GSN pairs (or between an SGSN and an RNC in UMTS), 
     # encapsulated in G-PDUs. A G-PDU is a packet including a GTP-U header and a T-PDU. The Path Protocol 
-    # defines the path and the GTP-U header defines the tunnel. Several tunnels may be multiplexed on a single path. 
-    fields_desc = [ BitField("version", 1,3),
-                    BitField("PT", 1, 1),
-                    BitField("Reserved", 0, 1),
-                    BitField("E", 0,1),
-                    BitField("S", 0, 1),
-                    BitField("PN", 0, 1),
-                    ByteEnumField("gtp_type", None, GTPmessageType),
-                    BitField("length", None, 16),
-                    XBitField("TEID", 0, 32),
-                    ConditionalField(XBitField("seq", 0, 16), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
-                    ConditionalField(ByteField("npdu", 0), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
-                    ConditionalField(ByteField("next_ex", 0), lambda pkt:pkt.E==1 or pkt.S==1 or pkt.PN==1),
-            ]
-
-    def post_build(self, p, pay):
-        p += pay
-        if self.length is None:
-            l = len(p)-8
-            p = p[:2] + struct.pack("!H", l)+ p[4:]
-        return p
+    # defines the path and the GTP-U header defines the tunnel. Several tunnels may be multiplexed on a single path.
+    pass
 
 class GTPmorethan1500(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
@@ -865,6 +866,8 @@ bind_layers(GTPHeader, GTPUpdatePDPContextResponse, gtp_type=19)
 bind_layers(GTPHeader, GTPDeletePDPContextRequest, gtp_type=20)
 bind_layers(GTPHeader, GTPDeletePDPContextResponse, gtp_type=21)
 bind_layers(GTPHeader, GTPPDUNotificationRequest, gtp_type=27)
+bind_layers(GTPHeader, GTP_UDPPort_ExtensionHeader, next_ex = 64, E = 1)
+bind_layers(GTPHeader, GTP_PDCP_PDU_ExtensionHeader, next_ex = 192, E = 1)
 
 # Bind GTP-U
 bind_layers(UDP, GTP_U_Header, dport = 2152)
diff --git a/scapy/contrib/gtp.uts b/scapy/contrib/gtp.uts
index a23fd413c98b37a6a1105d8958ddefd586ad1e60..89f9411764151b0c62a7070fbc9006aabd69acdd 100644
--- a/scapy/contrib/gtp.uts
+++ b/scapy/contrib/gtp.uts
@@ -5,18 +5,26 @@
 
 + GTPv1
 
+= GTPHeader, basic instanciation
+
+a = GTPHeader()
+assert a.version == 1
+assert a.E == a.S == a.PN == 0
+
 = GTPCreatePDPContextRequest(), basic instanciation
 gtp = IP()/UDP(dport=2123)/GTPHeader(teid=2807)/GTPCreatePDPContextRequest()
 gtp.dport == 2123 and gtp.teid == 2807 and len(gtp.IE_list) == 5
 
 = GTPCreatePDPContextRequest(), basic dissection
 random.seed(0x2807)
-str(gtp) == b"E\x00\x00O\x00\x01\x00\x00@\x11|\x9b\x7f\x00\x00\x01\x7f\x00\x00\x01\x08K\x08K\x00;{N2\x10\x00+\x00\x00\n\xf7\xd2y\x00\x00\x10\xf8>\x14\x05\x14\t\x85\x00\x04\xa6A\xd8+\x85\x00\x04z\xafnt\x87\x00\x0fxKbPaePK9oq0pb5"
+str(gtp)
+assert _ == b"E\x00\x00K\x00\x01\x00\x00@\x11|\x9f\x7f\x00\x00\x01\x7f\x00\x00\x01\x08K\x08K\x007\xa6\xa70\x10\x00'\x00\x00\n\xf7\x10\xd6\xd2\xf6\xd8\x14\x0f\x85\x00\x04\x98\xfaz\xab\x85\x00\x04\x02`0A\x87\x00\x0fu8h9lxKbPaePK9o"
 
 = GTPV1UpdatePDPContextRequest(), dissect
 h = "3333333333332222222222228100a38408004588006800000000fd1134820a2a00010a2a00024aa5084b005408bb32120044ed99aea9386f0000100000530514058500040a2a00018500040a2a000187000c0213921f739680fe74f2ffff94000130970001019800080112f41004d204d29900024000b6000101"
 gtp = Ether(h.decode('hex'))
-gtp.gtp_type == 18
+assert gtp.gtp_type == 18
+assert gtp.next_ex == 0
 
 = GTPV1UpdatePDPContextResponse(), dissect
 h = "3333333333332222222222228100838408004588005400000000fd1182850a2a00010a2a0002084b084b00406b46321300305843da17f07300000180100000032c7f4a0f58108500040a2a00018500040a2a000187000f0213921f7396d1fe7482ffff004a00f7a71e0a"
@@ -286,4 +294,4 @@ ie.ietype == 251 and ie.ipv4_address == '127.0.0.1' and ie.ipv6_address == '::1'
 
 = IE_PrivateExtension(), basic instantiation
 ie = IE_PrivateExtension(extention_value='hello')
-ie.ietype == 255 and ie.extention_value == 'hello'
+ie.ietype == 255 and ie.extention_value == 'hello'
\ No newline at end of file