使用cpp中的libpcap打印rtp头信息

时间:2011-10-22 07:39:34

标签: c++ rtp libpcap

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

我想打印rtp& rtcp有效载荷类型(对于PCMU为H264 / 0为96)(以及时间戳),以便我可以区分它是否是音频/视频。

我可以正确打印这些rtp / rtcp数据包序列号,但不能打包palyload类型。

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这样的值。

3 个答案:

答案 0 :(得分:1)

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;

答案 1 :(得分:0)

嗯,你用big endian命令编写了bitfield,但我想你使用的是一个小端机器(Intel)。你应该使用你的unsigned int的uint16_t instaed。毕竟,你只有16位。

答案 2 :(得分:0)

关于字节序的一切。所以你的结构应该根据字节顺序。

    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
};