ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GPRS核心网-GTP-C协议解析

2021-04-18 22:01:04  阅读:368  来源: 互联网

标签:GPRS GTP length 核心网 GTPV2 IE gtpv2 define


GPRS隧道协议(GTP)是3GPP标准定义的隧道协议,用于在3G /4G/5G网络中承载通用分组无线服务(GPRS)。

GTP用于在服务网关(S-GW)和分组数据网络网关(P-GW)以及S-GW和移动性管理实体(MME)之间为用户设备建立GTP隧道。如图-EPC架构:

在这里插入图片描述

GTP包含哪些单独的协议?

GTP包括在UDP / IP上传输的控制平面(GTP-C),用户平面(GTP-U)和计费(从GTP-C派生的GTP)流量。

GTP-C-在核心GPRS网络中的S-GW和P-GW之间执行信令,以激活和停用用户会话,调整服务质量参数或更新从另一个S-GW到达的漫游用户的会话。GTP-C支持以IPv4格式传输控制数据包。它用于各种EPC(演进的分组核心)信令接口,例如S5,S8和S11。还承载各种类型的控制平面信令消息。GTP-C端口号是2123。

GTP-U-在核心GPRS网络内以及在无线访问网络(RAN)和核心网络之间传输用户数据。GTP-U支持IPv4和IPv6用户数据,但传输是IPv4。它跨多个信令接口(例如S1,S5和S8)封装和路由用户平面流量。GTP-U消息是用户平面消息或信令消息。GTP-U端口号是2152。

什么是MME

MME是移动管理实体,是一个用于信令控制的网元,主要做移动的管理,此外还需要做会话相关的控制处理。

MME主要的功能是:

1、NAS信令处理
2、 3GPP内不同节点之间的移动性管理
3、PGW和SGW选择
4、漫游控制

什么是PGW

PGW是PDN网关,所谓PDN就是公共数据网,可以理解成核心网后端的网络系统,PDN负责用户数据包与其他网络的处理。

PGW功能描述:

1、基于用户包过滤
2、IP地址分配
3、上下行传输层数据包标记
4、上下行的承载绑定、校验。

什么是SGW

SGW是服务网关,它是数据面的网元,所谓数据面可以理解成数据传输的通道,负责本地网络用户数据的处理部分。

SGW功能描述

1、(基站)eNodeB之间的切换的本地
2、数据包路由和转发
3、上下行传输层数据包标记
4、用户和QCI力度的统计,主要用于运营商间计费
5、基于用户、PDN和QCI力度的上下行的计费。

EPC网元之间的接口

上面已经描述了MME、SGW、PGW。接下来介绍EPC协议围绕这三个网元之间的接口讲解。分别是eNodeB和MME之间的(S1-MME),eNodeB和SGW之间的(S1-U),MME和SGW之间的(S11),SGW和PGW之间的协议(S5)

在这里插入图片描述
S1-MME接口承载的协议是S1-AP/SCTP/IP,S1-U承载的协议是GTPv1-U,S5接口承载的协议是GTPv2-C。

GTPv2消息格式

各个版本的差异主要是协议功能,即传输的内容的差异,新版本一般来说比旧版本承载更多的信息。

控制平面GTP使用可变长度的标头。 控制平面GTP报头长度应为4个八位位组的倍数。
下面是GTPv2-C标头的格式。

在这里插入图片描述

Create Session Request
在这里插入图片描述

Create Session Response

在这里插入图片描述

对协议分析还原而言,知道如何识别,再知道如何解析协议格式,那么,就可以去实现解析了。

GTP消息类型

作为移动网络的协议,GTP当然是由3GPP组织来定义的,GTP v2参考3GPP TS 29.274,GTP v1参考3GPP TS 29.060。

#define GTPV2_IE_RESERVED                 0
#define GTPV2_IE_IMSI                     1
#define GTPV2_IE_CAUSE                    2
#define GTPV2_REC_REST_CNT                3
/*Start SRVCC Messages*/
#define GTPV2_IE_STN_SR                  51
#define GTPV2_IE_SRC_TGT_TRANS_CON       52
#define GTPV2_IE_TGT_SRC_TRANS_CON       53
#define GTPV2_IE_MM_CON_EUTRAN_SRVCC     54
#define GTPV2_IE_MM_CON_UTRAN_SRVCC      55
#define GTPV2_IE_SRVCC_CAUSE             56
#define GTPV2_IE_TGT_RNC_ID              57
#define GTPV2_IE_TGT_GLOGAL_CELL_ID      58
#define GTPV2_IE_TEID_C                  59
#define GTPV2_IE_SV_FLAGS                60
#define GTPV2_IE_SAI                     61
#define GTPV2_IE_MM_CTX_FOR_CS_TO_PS_SRVCC 62
/* 61 - 70 for future sv interface use*/
/*End SRVCC Messages*/
#define GTPV2_APN                        71
#define GTPV2_AMBR                       72
#define GTPV2_EBI                        73
#define GTPV2_IP_ADDRESS                 74
#define GTPV2_MEI                        75
#define GTPV2_IE_MSISDN                  76
#define GTPV2_INDICATION                 77
#define GTPV2_PCO                        78
#define GTPV2_PAA                        79
#define GTPV2_BEARER_QOS                 80
#define GTPV2_IE_FLOW_QOS                81
#define GTPV2_IE_RAT_TYPE                82
#define GTPV2_IE_SERV_NET                83
#define GTPV2_IE_BEARER_TFT              84
#define GTPV2_IE_TAD                     85
#define GTPV2_IE_ULI                     86
#define GTPV2_IE_F_TEID                  87
#define GTPV2_IE_TMSI                    88
#define GTPV2_IE_GLOBAL_CNID             89
#define GTPV2_IE_S103PDF                 90
#define GTPV2_IE_S1UDF                   91
#define GTPV2_IE_DEL_VAL                 92
#define GTPV2_IE_BEARER_CTX              93
#define GTPV2_IE_CHAR_ID                 94
#define GTPV2_IE_CHAR_CHAR               95
#define GTPV2_IE_TRA_INFO                96
#define GTPV2_BEARER_FLAG                97
/* define GTPV2_IE_PAGING_CAUSE          98 (void) */
#define GTPV2_IE_PDN_TYPE                99
#define GTPV2_IE_PTI                    100
#define GTPV2_IE_DRX_PARAM              101
#define GTPV2_IE_UE_NET_CAPABILITY      102
#define GTPV2_IE_MM_CONTEXT_GSM_T       103
#define GTPV2_IE_MM_CONTEXT_UTMS_CQ     104
#define GTPV2_IE_MM_CONTEXT_GSM_CQ      105
#define GTPV2_IE_MM_CONTEXT_UTMS_Q      106
#define GTPV2_IE_MM_CONTEXT_EPS_QQ      107
#define GTPV2_IE_MM_CONTEXT_UTMS_QQ     108
#define GTPV2_IE_PDN_CONNECTION         109
#define GTPV2_IE_PDN_NUMBERS            110
#define GTPV2_IE_P_TMSI                 111
#define GTPV2_IE_P_TMSI_SIG             112
#define GTPV2_IE_HOP_COUNTER            113
#define GTPV2_IE_UE_TIME_ZONE           114
#define GTPV2_IE_TRACE_REFERENCE        115
#define GTPV2_IE_COMPLETE_REQUEST_MSG   116
#define GTPV2_IE_GUTI                   117
#define GTPV2_IE_F_CONTAINER            118
#define GTPV2_IE_F_CAUSE                119
#define GTPV2_IE_SEL_PLMN_ID            120
#define GTPV2_IE_TARGET_ID              121
/* GTPV2_IE_NSAPI                       122 */
#define GTPV2_IE_PKT_FLOW_ID            123
#define GTPV2_IE_RAB_CONTEXT            124
#define GTPV2_IE_S_RNC_PDCP_CTX_INFO    125
#define GTPV2_IE_UDP_S_PORT_NR          126
#define GTPV2_IE_APN_RESTRICTION        127
#define GTPV2_IE_SEL_MODE               128
#define GTPV2_IE_SOURCE_IDENT           129
#define GTPV2_IE_BEARER_CONTROL_MODE    130
#define GTPV2_IE_CNG_REP_ACT            131
#define GTPV2_IE_FQ_CSID                132
#define GTPV2_IE_CHANNEL_NEEDED         133
#define GTPV2_IE_EMLPP_PRI              134
#define GTPV2_IE_NODE_TYPE              135
#define GTPV2_IE_FQDN                   136
#define GTPV2_IE_TI                     137
#define GTPV2_IE_MBMS_SESSION_DURATION  138
#define GTPV2_IE_MBMS_SERVICE_AREA      139
#define GTPV2_IE_MBMS_SESSION_ID        140
#define GTPV2_IE_MBMS_FLOW_ID           141
#define GTPV2_IE_MBMS_IP_MC_DIST        142
#define GTPV2_IE_MBMS_DIST_ACK          143
#define GTPV2_IE_RFSP_INDEX             144
#define GTPV2_IE_UCI                    145
#define GTPV2_IE_CSG_INFO_REP_ACTION    146
#define GTPV2_IE_CSG_ID                 147
#define GTPV2_IE_CMI                    148
#define GTPV2_IE_SERVICE_INDICATOR      149
#define GTPV2_IE_DETACH_TYPE            150
#define GTPV2_IE_LDN                    151
#define GTPV2_IE_NODE_FEATURES          152
#define GTPV2_IE_MBMS_TIME_TO_DATA_XFER 153
#define GTPV2_IE_THROTTLING             154
#define GTPV2_IE_ARP                    155
#define GTPV2_IE_EPC_TIMER              156
#define GTPV2_IE_SIG_PRIO_IND           157
#define GTPV2_IE_TMGI                   158
#define GTPV2_IE_ADD_MM_CONT_FOR_SRVCC  159
#define GTPV2_IE_ADD_FLAGS_FOR_SRVCC    160
#define GTPV2_IE_MMBR                   161
#define GTPV2_IE_MDT_CONFIG             162
#define GTPV2_IE_APCO                   163
#define GTPV2_IE_ABS_MBMS_DATA_TF_TIME  164
#define GTPV2_IE_HENB_INFO_REPORT       165
#define GTPV2_IE_IP4CP                  166
#define GTPV2_IE_CHANGE_TO_REPORT_FLAGS 167
#define GTPV2_IE_ACTION_INDICATION      168
#define GTPV2_IE_TWAN_IDENTIFIER        169
#define GTPV2_IE_ULI_TIMESTAMP          170
#define GTPV2_IE_MBMS_FLAGS             171
#define GTPV2_IE_RAN_NAS_CAUSE          172
#define GTPV2_IE_CN_OP_SEL_ENT          173
#define GTPV2_IE_TRUST_WLAN_MODE_IND    174
#define GTPV2_IE_NODE_NUMBER            175
#define GTPV2_IE_NODE_IDENTIFIER        176
#define GTPV2_IE_PRES_REP_AREA_ACT      177
#define GTPV2_IE_PRES_REP_AREA_INF      178
#define GTPV2_IE_TWAN_ID_TS             179
#define GTPV2_IE_OVERLOAD_CONTROL_INF   180
#define GTPV2_IE_LOAD_CONTROL_INF       181
#define GTPV2_IE_METRIC                 182
#define GTPV2_IE_SEQ_NO                 183
#define GTPV2_IE_APN_AND_REL_CAP        184
#define GTPV2_IE_WLAN_OFFLOADABILITY_IND 185
#define GTPV2_IE_PAGING_AND_SERVICE_INF 186
#define GTPV2_IE_INTEGER_NUMBER         187
#define GTPV2_IE_MILLISECOND_TS         188
#define GTPV2_IE_MON_EVENT_INF          189
/*
190    ECGI List
191    Remote UE Context
192    Remote User ID
193    Remote UE IP information
*/
#define GTPV2_IE_CIOT_OPT_SUPPORT_IND       194
#define GTPV2_IE_SCEF_PDN_CONNECTION        195
#define GTPV2_IE_HEADER_COMP_CONF           196
#define GTPV2_IE_EXTENDED_PCO               197
#define GTPV2_IE_SERV_PLMN_RATE_CONTROL     198
#define GTPV2_IE_COUNTER                    199
#define GTPV2_IE_MAPPED_UE_USAGE_TYPE                200
#define GTPV2_IE_SECONDARY_RAT_USAGE_DATA_REPORT     201
#define GTPV2_IE_UP_FUNC_SEL_INDI_FLG                202
#define GTPV2_IE_MAX_PKT_LOSS_RTE                    203
#define GTPV2_IE_APN_RTE_CNTRL_STATUS                204
#define GTPV2_IE_EXT_TRS_INF                         205
#define GTPV2_IE_MON_EVENT_EXT_INF                   206
/*
203 to 253    Spare. For future use.
254    Special IE type for IE Type Extension
255    Private Extension
256 to 65535    Spare. For future use.

*/
/* 169 to 254 reserved for future use */
#define GTPV2_IE_PRIVATE_EXT            255

GTP-C协议解析实现

下面主要对GTPv2协议的IMSI、TEID、MSISDN、用户IP进行解析。

struct gtpv2_hdr_t {
    u_int8_t flags;   /* GTP header flags */
    u_int8_t msg_type; /* Message type */
    u_int16_t length; /* Length of header */
    long teid;    /* Tunnel End-point ID */
};


static void dissect_gtpv2_ie_common(u_char *gtpv2_info, int offset,int package_len, u_int8_t message_type)
{
	u_int8_t    type = 0, instance = 0;
    u_int16_t     length = 0;
    int         i = 0, remaining_length = 0, msg_length = 0;
    /*
     * Octets   8   7   6   5       4   3   2   1
     *  1       Type
     *  2-3     Length = n
     *  4       CR          Spare   Instance
     * 5-(n+4)  IE specific data
     */
    msg_length = package_len;
	
	while (offset < msg_length)
	{
        /* Get the type and length */
        remaining_length = msg_length - offset;
        if (remaining_length < 3) {
			printf("Not enough data left for IE and length, %i bytes\n", remaining_length);
            return;
        }
        type    = gtpv2_info[offset];
		printf("IE Type: %d\n",type);
        length  = ntohs(*(uint16_t *)(gtpv2_info + offset + 1));
		printf("IE Length: %d\n",length);
        remaining_length = remaining_length -4;
        if (remaining_length < length) {
            printf("Less data left than indicated by length %u, remaining length %i \n", length, remaining_length);
            /* Octet 1 */
            offset += 1;

            /*Octet 2 - 3 */
            return;
        }
        /* type */
        offset += 1;

        /*Length */
        offset += 2; 


		instance = gtpv2_info[offset]&0x0f;
		printf("instance: %d\n",instance);
		
		/*instance*/
        offset += 1; 

        /* TODO: call IE dissector here */
        if (type == GTPV2_IE_RESERVED) {
            /* Treat IE type zero specal as type zero is used to end the loop in the else branch */

        } 
		else 
		{

            /* Loop over the IE dissector list to se if we find an entry;
               the last entry will have ie_type=0 breaking the loop */
			   
			   switch(type)
			   {
				case GTPV2_IE_IMSI:
				{
					uint8_t *imsi = (uint8_t*)malloc(length+1);
					if (imsi == NULL)
					{
						return ;
					}							
					memcpy(imsi, gtpv2_info + offset,length);
					//imsi[length] = '\0';
						
					printf("IMSI: ");
					for(i=0; i < length; i++)
						printf("%.2x ",imsi[i]);

					printf("\n");
				}
				break;
				
				case GTPV2_IE_MSISDN:
				{
					
					uint8_t *msisdn = (uint8_t*)malloc(length+1);
					if (msisdn == NULL)
					{
						return ;
					}
					
					memcpy(msisdn, gtpv2_info + offset + 1,length);
					//msisdn[length] = '\0';
						
					printf("MSISDN: ");
					for(i=0; i < length; i++)
						printf("%.2x ",msisdn[i]);

					printf("\n");
					
				}
				break;
				
				case GTPV2_IE_F_TEID:
				{
					//user ip
					uint32_t user_ipv4;
					
					uint8_t *teid = (uint8_t*)malloc(length+1);
					if (teid == NULL)
					{
						return ;
					}
					
					memcpy(&user_ipv4, gtpv2_info + offset + 1 + 4,length);		
					
					printf("F-TEID IPv4: %s\n",int_ntoa(user_ipv4));
					
				}
				break;

				default:            

				break;		
		
				   
			   }

        }

        offset += length;
		
	}
	
	
}

static int dissect_gtpv2(u_char *gtpv2_info,int PayloadLen)
{
	struct gtpv2_hdr_t gtpv2_hdr;
	int         offset = 0;
	//gtpv2_hdr->teid = -1;
	u_int8_t  message_type, t_flag, p_flag, mp_flag, cause_aux;
	u_int8_t  version = 0;
	int package_len = PayloadLen;
	memset(&gtpv2_hdr, 0, sizeof(struct gtpv2_hdr_t));
	
	
	/* Setting the TEID to -1 to say that the TEID is not valid for this packet */

	
	version = gtpv2_info[0] >> 5;
	printf("version: %d\n",version);
	if (version != 2)
		return 0;
	
	p_flag  = (gtpv2_info[0] & 0x10) >> 4;
    t_flag  = (gtpv2_info[0] & 0x08) >> 3;
    mp_flag = (gtpv2_info[0] & 0x04) >> 2;
	//printf("p_flag: %d\n",p_flag);
	//printf("t_flag: %d\n",t_flag);
	//printf("mp_flag: %d\n",mp_flag);
	
	offset += 1;

    /* Octet 2 */
	message_type = gtpv2_info[offset];
    gtpv2_hdr.msg_type = message_type;
	printf("Message type: %d\n",gtpv2_hdr.msg_type);
    offset += 1;
    /* Octet 3 - 4 */
    gtpv2_hdr.length = ntohs(*(uint16_t*)(gtpv2_info + offset));
	printf("Message Length: %d\n",gtpv2_hdr.length);
	
	offset += 2;

    if (t_flag) 
	{
        /* Tunnel Endpoint Identifier 4 octets */
        gtpv2_hdr.teid = ntohl(*(long*)(gtpv2_info + offset));
		printf("Tunnel Endpoint Identifier: %ld\n",gtpv2_hdr.teid);
        offset += 4;
    }
	
	/* Sequence Number 3 octets */
    offset += 3;
	
	 /* Spare 1 octet or if the "MP" flag is set to "1",
     * then bits 8 to 5 of octet 12 shall indicate the message priority.
     */
    if (mp_flag) 
	{
        /* Bits 8 to 5 of octet 12 shall be encoded as the binary value of the Message Priority
         * and it may take any value between 0 and 15, where 0 corresponds to the highest priority
         * and 15 the lowest priority.
         */
        
    }
	else
	{
        
    }
    offset += 1;
	
	if (p_flag)
	{
        
    } 
	else 
	{
        dissect_gtpv2_ie_common(gtpv2_info,offset, package_len,message_type);
    }
	
}


static void confirm_gtpv2_packet(struct ip *pIp)
{
	int iIpTotalLen = ntohs(pIp->ip_len);
	int offset = 0;
	int nFragSeq = 0;
	struct udphdr* pUdpHdr = (struct udphdr*)((char*)pIp + (pIp->ip_hl<<2));
	/*判断是否是gtpv2协议,gtpv2端口是514*/
	if (pIp->ip_p == IPPROTO_UDP && (ntohs(pUdpHdr->dest) == GTPv2C_PORT) || (ntohs(pUdpHdr->source) == GTPv2C_PORT) ) 
	{
		printf("\n");
		//printf("info udp\n");
		
		int iPayloadLen = iIpTotalLen - (pIp->ip_hl<<2) - 8;
		//printf("UDP Payload Len %d\n", iPayloadLen);
		
		u_char *pGtpV2Hdr = (u_char*)(pUdpHdr+1);
		dissect_gtpv2(pGtpV2Hdr,iPayloadLen);
		
	}	
}

编译运行:

在这里插入图片描述

总结

在LTE中,GTP(GPRS隧道协议)隧道用于通过基于GTP的接口进行通信的两个节点之间,以将流量分离为不同的通信流。

通过TEID(隧道端点标识符),IP地址和UDP端口号在每个节点中标识GTP隧道。

GTP隧道的接收端在本地分配发送方必须使用的TEID值。GTPv2包括一个更新的控制平面,该控制平面使控制消息能够在MME,S-GW,PDN GW等之间传递。最后,对于具体协议的实现,请参考3gpp相关的资料。

参考:
TS 29.281
TS 29.060

欢迎关注微信公众号【程序猿编码】,欢迎添加本人微信号(17865354792),交个朋友,咱们一起学习进步!

标签:GPRS,GTP,length,核心网,GTPV2,IE,gtpv2,define
来源: https://blog.csdn.net/chen1415886044/article/details/115802966

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有