在cpp中使用libpcap打印RTP头信息

print rtp header information using libpcap in cpp

本文关键字:打印 RTP 信息 libpcap cpp      更新时间:2023-10-16

我正在使用libpcap解析pcap文件。

我想打印rtcpamp;rtcp有效载荷类型(96用于H264/0用于PCMU)(和时间戳也),以便我可以区分它是否是音频/视频。

我可以正确打印那些rtp/rtcp数据包序列号,但不能打印有效负载类型。

typedef struct {
   unsigned int version:2;   /* protocol version */
   unsigned int p:1;         /* padding flag */
   unsigned int x:1;         /* header extension flag */
   unsigned int cc:4;        /* CSRC count */
   unsigned int m:1;         /* marker bit */
   unsigned int pt:7;        /* payload type */
       u_int16 seq;              /* sequence number */
       u_int32 ts;               /* timestamp */
       u_int32 ssrc;             /* synchronization source */
       u_int32 csrc[1];          /* optional CSRC list */
   } rtp_hdr_t;
rtp_hdr_t *rtphdr=(rtp_hdr_t *)(packet + sizeof(struct ether_header) +sizeof(struct ip_header) + sizeof(struct udp_header));
cout<< ntohs(rtphdr->pt) << endl;

示例:获取负载类型为12288和0。但我必须得到96和0(如wireshark)。

cout << ntohs(rtphdr->ts) << endl;

示例:获取时间戳信息类似于49892(5位十进制数)但我必须得到像3269770717这样的值

ntohs()函数的作用是:将网络字节序中的无符号短整数转换为主机字节序。注意,它是字节顺序,因此,对于一个字节的负载,您不需要进行这种转换。

对于时间戳,您应该使用ntohl(),因为您正在使用32位值。

我认为这将比使用字段更自然:

typedef struct {
   u_int8 version_p_x_cc;
   u_int8 m_pt;
   u_int16 seq; 
   ....
}
// payload type:
cout<< rtphdr->m_pt & 0x7f << endl;
// marker bit
cout<< (rtphdr->m_pt >> 7) & 0x01  << endl;

好吧,你写的位域是大端序,但我猜你用的是小端序机器(Intel)。你应该使用uint16_t而不是unsigned int。毕竟你只有16位。

都是关于端序的。所以你的结构应该是按端序排列的。

    struct rtpHeader {
#if __BYTE_ORDER == __BIG_ENDIAN
        //For big endian
        unsigned char version:2;       // Version, currently 2
        unsigned char padding:1;       // Padding bit
        unsigned char extension:1;     // Extension bit
        unsigned char cc:4;            // CSRC count
        unsigned char marker:1;        // Marker bit
        unsigned char payload:7;       // Payload type
#else
        //For little endian
        unsigned char cc:4;            // CSRC count
        unsigned char extension:1;     // Extension bit
        unsigned char padding:1;       // Padding bit
        unsigned char version:2;       // Version, currently 2
        unsigned char payload:7;       // Payload type
        unsigned char marker:1;        // Marker bit
#endif
        u_int16_t sequence;        // sequence number
        u_int32_t timestamp;       //  timestamp
        u_int32_t sources[1];      // contributing sources
};