diff --git a/scapy/contrib/gtp.py b/scapy/contrib/gtp.py
index 92f7d9f93d04146fe3cd8f4618107a8a4e21d394..a4354091540c9b378a40f2fa01a380170fafa8dc 100644
--- a/scapy/contrib/gtp.py
+++ b/scapy/contrib/gtp.py
@@ -41,6 +41,8 @@ GTPmessageType = {   1: "echo_request",
                     21: "delete_pdp_context_res",
                     26: "error_indication",
                     27: "pdu_notification_req",
+                    31: "supported_extension_headers_notification",
+                   254: "end_marker",
                    255: "g_pdu" }
 
 IEType = {   1: "Cause",
@@ -177,20 +179,27 @@ class TBCDByteField(StrFixedLenField):
 
 TBCD_TO_ASCII = "0123456789*#abc"
 
-class GTP_UDPPort_ExtensionHeader(Packet):
-    fields_desc=[ ShortField("length", 0x40),
-                  BitField("udp_port", None, 48),
+class GTP_ExtensionHeader(Packet):
+    @classmethod
+    def dispatch_hook(cls, _pkt=None, *args, **kargs):
+        if _pkt == None:
+            return GTP_UDPPort_ExtensionHeader
+        return cls
+
+class GTP_UDPPort_ExtensionHeader(GTP_ExtensionHeader):
+    fields_desc=[ ByteField("length", 0x40),
+                  ShortField("udp_port", None),
                   ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ]
 
-class GTP_PDCP_PDU_ExtensionHeader(Packet):
-    fields_desc=[ ShortField("length", 0x01),
-                  ByteField("pdcp_pdu", None),
-                  ByteField("pdcp_pdu", None),
+class GTP_PDCP_PDU_ExtensionHeader(GTP_ExtensionHeader):
+    fields_desc=[ ByteField("length", 0x01),
+                  ShortField("pdcp_pdu", None),
                   ByteEnumField("next_ex", 0, ExtensionHeadersTypes), ]
+    
 
 class GTPHeader(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
-    name = "GTP Header"
+    name = "GTP-C Header"
     fields_desc=[ BitField("version", 1, 3),
                   BitField("PT", 1, 1),
                   BitField("reserved", 0, 1),
@@ -221,17 +230,39 @@ 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:
+                import gtp_v2
+                return gtp_v2.GTPHeader
         if _pkt and len(_pkt) >= 8:
-            if struct.unpack("!B", _pkt[1:2])[0] == 255:
-                return GTP_U_Header
+            _gtp_type = struct.unpack("!B", _pkt[1:2])[0]
+            return GTPforcedTypes.get(_gtp_type, GTPHeader)
         return cls
 
+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.
+
+# Some gtp_types have to be associated with a certain type of header
+GTPforcedTypes = {
+    16: GTPHeader,
+    17: GTPHeader,
+    18: GTPHeader,
+    19: GTPHeader,
+    20: GTPHeader,
+    21: GTPHeader,
+    26: GTP_U_Header,
+    27: GTPHeader,
+    254: GTP_U_Header,
+    255: GTP_U_Header
+    }
+
 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),
-                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),]
 
     def hashret(self):
         return struct.pack("H", self.seq)
@@ -658,6 +689,11 @@ class IE_PrivateExtension(IE_Base):
                    StrLenField("extention_value", "",
                                length_from=lambda x: x.length)]
 
+class IE_ExtensionHeaderList(IE_Base):
+    name = "Extension Header List"
+    fields_desc = [ByteEnumField("ietype", 141, IEType),
+                   FieldLenField("length", None, length_of="extension_headers"),
+                   FieldListField("extension_headers", [64, 192], ByteField("", 0))]
 
 class IE_NotImplementedTLV(Packet):
     name = "IE not implemented"
@@ -688,6 +724,7 @@ ietypecls = {1: IE_Cause,
              133: IE_GSNAddress,
              134: IE_MSInternationalNumber,
              135: IE_QoS,
+             141: IE_ExtensionHeaderList,
              148: IE_CommonFlags,
              149: IE_APNRestriction,
              151: IE_RATType,
@@ -718,10 +755,7 @@ def IE_Dispatcher(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),
-                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
-                    PacketListField("IE_list", [], IE_Dispatcher) ]
+    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
 
     def hashret(self):
         return struct.pack("H", self.seq)
@@ -733,10 +767,7 @@ class GTPEchoResponse(Packet):
 class GTPCreatePDPContextRequest(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP Create PDP Context Request"
-    fields_desc = [ ShortField("seq", RandShort()),
-                    ByteField("npdu", 0),
-                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
-                    PacketListField("IE_list", [ IE_TEIDI(), IE_NSAPI(), IE_GSNAddress(),
+    fields_desc = [ PacketListField("IE_list", [ IE_TEIDI(), IE_NSAPI(), IE_GSNAddress(),
                                                  IE_GSNAddress(),
                                                  IE_NotImplementedTLV(ietype=135, length=15,data=RandString(15)) ],
                                     IE_Dispatcher) ]
@@ -746,10 +777,7 @@ class GTPCreatePDPContextRequest(Packet):
 class GTPCreatePDPContextResponse(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP Create PDP Context Response"
-    fields_desc = [ ShortField("seq", RandShort()),
-                    ByteField("npdu", 0),
-                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
-                    PacketListField("IE_list", [], IE_Dispatcher) ]
+    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
 
     def hashret(self):
         return struct.pack("H", self.seq)
@@ -761,10 +789,7 @@ class GTPCreatePDPContextResponse(Packet):
 class GTPUpdatePDPContextRequest(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP Update PDP Context Request"
-    fields_desc = [ShortField("seq", RandShort()),
-                   ByteField("npdu", 0),
-                   ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
-                   PacketListField("IE_list", [
+    fields_desc = [PacketListField("IE_list", [
                        IE_Cause(),
                        IE_Recovery(),
                        IE_TEIDI(),
@@ -793,10 +818,7 @@ class GTPUpdatePDPContextRequest(Packet):
 class GTPUpdatePDPContextResponse(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP Update PDP Context Response"
-    fields_desc = [ShortField("seq", RandShort()),
-                   ByteField("npdu", 0),
-                   ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
-                   PacketListField("IE_list", None, IE_Dispatcher)]
+    fields_desc = [PacketListField("IE_list", None, IE_Dispatcher)]
 
     def hashret(self):
         return struct.pack("H", self.seq)
@@ -805,49 +827,37 @@ class GTPUpdatePDPContextResponse(Packet):
 class GTPErrorIndication(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP Error Indication"
-    fields_desc = [ XBitField("seq", 0, 16),
-                    ByteField("npdu", 0),
-                    ByteField("next_ex",0),
-                    PacketListField("IE_list", [], IE_Dispatcher) ]
+    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
 
 class GTPDeletePDPContextRequest(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP Delete PDP Context Request"
-    fields_desc = [ XBitField("seq", 0, 16),
-                    ByteField("npdu", 0),
-                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
-                    PacketListField("IE_list", [], IE_Dispatcher) ]
+    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
 
 class GTPDeletePDPContextResponse(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP Delete PDP Context Response"
-    fields_desc = [ XBitField("seq", 0, 16),
-                    ByteField("npdu", 0),
-                    ByteField("next_ex",0),
-                    PacketListField("IE_list", [], IE_Dispatcher) ]
+    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
 
 class GTPPDUNotificationRequest(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP PDU Notification Request"
-    fields_desc = [ XBitField("seq", 0, 16),
-                    ByteField("npdu", 0),
-                    ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
-                    PacketListField("IE_list", [ IE_IMSI(),
+    fields_desc = [ 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(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.
-    pass
+class GTPSupportedExtensionHeadersNotification(Packet):
+    name = "GTP Supported Extension Headers Notification"
+    fields_desc = [ PacketListField("IE_list", [ IE_ExtensionHeaderList(),
+                        ], IE_Dispatcher) ]
 
+class GTPErrorIndication(Packet):
+    name = "GTP Error Indication"
+    fields_desc = [ PacketListField("IE_list", [], IE_Dispatcher) ]
+    
 class GTPmorethan1500(Packet):
     # 3GPP TS 29.060 V9.1.0 (2009-12)
     name = "GTP More than 1500"
@@ -857,8 +867,8 @@ class GTPmorethan1500(Packet):
 # Bind GTP-C
 bind_layers(UDP, GTPHeader, dport = 2123)
 bind_layers(UDP, GTPHeader, sport = 2123)
-bind_layers(GTPHeader, GTPEchoRequest, gtp_type=1)
-bind_layers(GTPHeader, GTPEchoResponse, gtp_type=2)
+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)
 bind_layers(GTPHeader, GTPCreatePDPContextResponse, gtp_type=17)
 bind_layers(GTPHeader, GTPUpdatePDPContextRequest, gtp_type=18)
@@ -866,12 +876,14 @@ 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_layers(GTPHeader, GTPSupportedExtensionHeadersNotification, gtp_type=31, S=1)
+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)
 bind_layers(UDP, GTP_U_Header, sport = 2152)
+bind_layers(GTP_U_Header, GTPErrorIndication, gtp_type=26, S=1)
 bind_layers(GTP_U_Header, IP, gtp_type = 255)
 
 if __name__ == "__main__":
diff --git a/scapy/contrib/gtp.uts b/scapy/contrib/gtp.uts
index 89f9411764151b0c62a7070fbc9006aabd69acdd..b7c6032bce4cf453d28a073a7e8bee434c4e00d2 100644
--- a/scapy/contrib/gtp.uts
+++ b/scapy/contrib/gtp.uts
@@ -11,6 +11,11 @@ a = GTPHeader()
 assert a.version == 1
 assert a.E == a.S == a.PN == 0
 
+= GTP_U_Header detection
+
+a = GTPHeader(str(GTP_U_Header()/GTPErrorIndication()))
+assert isinstance(a, GTP_U_Header)
+
 = 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
@@ -294,4 +299,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'
\ No newline at end of file
+ie.ietype == 255 and ie.extention_value == 'hello'