/* 接收者/发送者计数是最后5位   */#define RTCP_COUNT(octet)   ((octet) & 0x1F)
#define RTCP_PT_MIN  192/* Supplemental H.261 specific RTCP packet types according to Section C.3.5 */#define RTCP_FIR     192#define RTCP_NACK    193#define RTCP_SMPTETC 194#define RTCP_IJ      195/* RTCP packet types according to Section A.11.1 *//* And https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml */#define RTCP_SR      200#define RTCP_RR      201#define RTCP_SDES    202#define RTCP_BYE     203#define RTCP_APP     204#define RTCP_RTPFB   205#define RTCP_PSFB    206#define RTCP_XR      207#define RTCP_AVB     208#define RTCP_RSI     209#define RTCP_TOKEN   210
#define RTCP_PT_MAX  210
static const char mon_names[12][4] = {	"Jan",	"Feb",	"Mar",	"Apr",	"May",	"Jun",	"Jul",	"Aug",	"Sep",	"Oct",	"Nov",	"Dec"};
/** data structure to hold time values with nanosecond resolution*/typedef struct {	time_t	secs;	int	nsecs;} nstime_t;
/* * 1900-01-01 00:00:00 (proleptic?) UTC. * Used by a number of time formats. */#define EPOCH_DELTA_1900_01_01_00_00_00_UTC 2208988800U
/* * NTP_BASETIME is in fact epoch - ntp_start_time; ntp_start_time * is January 1, 2036, 00:00:00 UTC. */#define NTP_BASETIME EPOCH_DELTA_1900_01_01_00_00_00_UTC#define NTP_FLOAT_DENOM 4294967296.0#define NTP_TS_SIZE 100
/* 解剖长度字段。附加到此字段的文字表示转换为的实际字节数 (即 (原始值 + 1) * 4) */static int dissect_rtcp_length_field(u_char *rtcp_info, int offset){
    uint16_t  raw_length = ntohs(*(uint16_t*)(rtcp_info + offset));    printf("(%u bytes)\n", (raw_length+1)*4);    offset += 2;    return offset;}static int dissect_rtcp_rr(u_char *rtcp_info, int offset,int count, int packet_length ){    int counter = 0;    uint8_t  rr_flt = 0;    int    rr_offset = offset;	    counter = 1;    while ( counter <= count ) {        uint32_t lsr = 0, dlsr = 0;
        /* Create a new subtree for a length of 24 bytes */
        /* SSRC_n source identifier, 32 bits */
        offset += 4;
        /* Fraction lost, 8bits */        rr_flt = rtcp_info[offset];
        offset++;
        /* Cumulative number of packets lost, 24 bits */        offset += 3;
        /* Sequence number cycles */
        offset += 2;        /* highest sequence number received */
        offset += 2;
        /* Interarrival jitter */
        offset += 4;
        /* Last SR timestamp */        lsr = ntohl(*(uint32_t*)(rtcp_info + offset));		printf("Last SR timestamp: 0x%x\n",lsr);        offset += 4;
        /* Delay since last SR timestamp */        dlsr = ntohl(*(uint32_t*)(rtcp_info + offset));
        printf("(%d milliseconds)\n",(int)(((double)dlsr/(double)65536) * 1000.0));        offset += 4;
        counter++;    }
    return offset;}
const char *tvb_ntp_fmt_ts_sec(u_char *rtcp_info, int offset){	uint32_t tempstmp = 0;	time_t temptime = 0;	struct tm *bd;	char *buff = NULL;		tempstmp = ntohl(*(uint32_t*)(rtcp_info + offset));	if (tempstmp == 0){		return "NULL";	}
	/* We need a temporary variable here so the unsigned math	* works correctly (for years > 2036 according to RFC 2030	* chapter 3).	*/	temptime = (time_t)(tempstmp - NTP_BASETIME);	bd = gmtime(&temptime);	if (!bd){		return "Not representable";	}
	buff = (char *)malloc(NTP_TS_SIZE);	snprintf(buff, NTP_TS_SIZE,		"%s %2d, %d %02d:%02d:%02d UTC",		mon_names[bd->tm_mon],		bd->tm_mday,		bd->tm_year + 1900,		bd->tm_hour,		bd->tm_min,		bd->tm_sec);	return buff;}
static int dissect_rtcp_sr(u_char *rtcp_info, int offset,int count, int packet_length){
    uint32_t     ts_msw = 0, ts_lsw = 0;    int         sr_offset = offset;
    /* NTP timestamp */    ts_msw = ntohl(*(uint32_t*)(rtcp_info + offset));	printf("ts_msw: 0x%x\n",ts_msw);    ts_lsw = ntohl(*(uint32_t*)(rtcp_info + offset + 4));	printf("ts_lsw: 0x%x\n",ts_lsw);
	//printf("offset: 0x%x 0x%x 0x%x 0x%x\n",rtcp_info[offset],rtcp_info[offset + 1],rtcp_info[offset + 2],rtcp_info[offset + 3]);	printf("MSW: %s\n",tvb_ntp_fmt_ts_sec(rtcp_info,offset));    offset += 8;
    /* RTP timestamp, 32 bits */	    offset += 4;    /* Sender's packet count, 32 bits */
    offset += 4;    /* Sender's octet count, 32 bits */
    offset += 4;
    /* The rest of the packet is equal to the RR packet */    if ( count != 0 )        offset = dissect_rtcp_rr(rtcp_info, offset, count, packet_length-(offset-sr_offset));    else    {        /* If length remaining, assume profile-specific extension bytes */        if ((offset-sr_offset) < packet_length)        {
            offset = sr_offset + packet_length;        }    }
    return offset;}
static int dissect_rtcp_sdes(u_char *rtcp_info, int offset, int count){    int           chunk = 0;
    int           start_offset = 0;    int           items_start_offset = 0;    uint32_t       ssrc = 0;    unsigned int  item_len = 0;    unsigned int  sdes_type = 0;    unsigned int  prefix_len = 0;
    chunk = 1;    while ( chunk <= count ) 	{		/* Create a subtree for this chunk; we don't yet know		   the length. */		start_offset = offset;
		ssrc = ntohl(*(uint32_t*)(rtcp_info + offset));		printf("Chunk %u, SSRC/CSRC 0x%X\n", chunk, ssrc);
		/* SSRC_n source identifier, 32 bits */		offset += 4;
		/* Create a subtree for the SDES items; we don't yet know		   the length */
		/*		 * Not every message is ended with "null" bytes, so check for		 * end of frame as well.		 */		 		  /* ID, 8 bits */		sdes_type = rtcp_info[offset];		printf("Type: %d\n",sdes_type);		if (sdes_type == 0)			break;		offset++;		/* Item length, 8 bits */		item_len = rtcp_info[offset];		printf("Length: %d\n",item_len);		offset++;				char *pszText = (char*)malloc(item_len);		if (pszText != 0)		{			memcpy(pszText, rtcp_info + offset,item_len);			pszText[item_len] = '\0';			printf("Text = %s\n",pszText);		}	
		chunk++;    }
    return offset;}
static void dissect_rtcp(u_char *rtcp_info,int packet_type, int offset,int PayloadLen){	unsigned int  temp_byte = 0;	int  elem_count = 0;	int  packet_length = 0;	int  total_packet_length = 0;	int loop = 2;	bool flag_rtcp = false;
		/*检查是否为有效类型*/		if ( ( packet_type < RTCP_PT_MIN ) || ( packet_type >  RTCP_PT_MAX ) )			exit(-1);
		/*		 * 获取完整的RTCP数据包的长度		 */		 		packet_length = (ntohs(*(uint16_t*)(rtcp_info + offset + 1)) + 1) * 4 ;		//printf("packet_length: %d\n",packet_length);
				temp_byte = rtcp_info[offset-1];		elem_count = RTCP_COUNT( temp_byte );/* Source count, 5 bits */		printf("Reception report count: %d\n",elem_count);  
		switch ( packet_type ) 		{						case RTCP_SR:			case RTCP_RR:				/*					Real-time Transport Control Protocol (Receiver Report)					10.. .... = Version: RFC 1889 Version (2)					..0. .... = Padding: False					...0 0001 = Reception report count: 1					Packet type: Receiver Report (201)					Length: 7 (32 bytes)					Sender SSRC: 0xb584b03e (3045371966)					Source 1				*/
				/* Packet type, 8 bits */				offset++;				/* Packet length in 32 bit words MINUS one, 16 bits */				offset = dissect_rtcp_length_field(rtcp_info, offset);				/* Sender Synchronization source, 32 bits */				offset += 4;
				if ( packet_type == RTCP_SR )				{					offset = dissect_rtcp_sr(rtcp_info, offset, elem_count, packet_length-8 );					printf("dissect_rtcp_sr\n");				}				else				{						offset = dissect_rtcp_rr(rtcp_info, offset, elem_count, packet_length-8 );											}								//uint16_t second_packet_type = ntohs(*(uint16_t*)(rtcp_info + offset));
				//printf("111offset: 0x%x 0x%x 0x%x 0x%x\n",rtcp_info[offset],rtcp_info[offset + 1],rtcp_info[offset + 2],rtcp_info[offset + 3]);								if (rtcp_info[offset + 1] == RTCP_SDES)				{										/* Source count, 5 bits */					offset++;					/* Packet type, 8 bits */					offset++;					/* Packet length in 32 bit words MINUS one, 16 bits */					offset = dissect_rtcp_length_field(rtcp_info, offset);					offset = dissect_rtcp_sdes(rtcp_info,offset,elem_count);
				}
			break;
			default:				/*				 * To prevent endless loops in case of an unknown message type				 * increase offset. Some time the while will end :-)				 */				offset++;				break;
		}		}
static bool dissect_rtcp_heur(u_char *rtcp_info,int PayloadLen){    unsigned int offset = 0;    unsigned int first_byte = 0;    unsigned int packet_type = 0;
    /* 查看第一个字节 */    first_byte = rtcp_info[offset];
    /* 版本位是否设置为2*/	//printf("version: %d\n",((first_byte & 0xC0) >> 6));    if (((first_byte & 0xC0) >> 6) != 2)    {        return false;    }
    /* 看包类型 */	offset += 1;    packet_type = rtcp_info[offset];	//printf("packet_type: %d\n",packet_type);    /* 复合数据包中的第一个数据包应该是发送方或接收者报告 */    if (!((packet_type == RTCP_SR)  || (packet_type == RTCP_RR) ||          (packet_type == RTCP_BYE) || (packet_type == RTCP_APP) ||          (packet_type == RTCP_PSFB)))    {        return false;    }
    /*总长度必须是4个字节的倍数*/	//printf("PayloadLen: %d\n",PayloadLen);    if (PayloadLen % 4)    {        return false;    }
    /* OK, dissect as RTCP */    dissect_rtcp(rtcp_info,packet_type,offset,PayloadLen);    return true;}
static void confirm_rtcp_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));	if (pIp->ip_p == IPPROTO_UDP) 	{		printf("\n");				int iPayloadLen = iIpTotalLen - (pIp->ip_hl<<2) - 8;		printf("UDP Payload Len %d\n", iPayloadLen);				u_char *pDnsHdr = (u_char*)(pUdpHdr+1);		dissect_rtcp_heur(pDnsHdr,iPayloadLen);			}	}
评论