简体   繁体   English

在cpp中使用libpcap打印rtp标头信息

[英]print rtp header information using libpcap in cpp

I am parsing the pcap file using libpcap. 我正在使用libpcap解析pcap文件。

I want to print rtp&rtcp payload type(96 for H264/0 for PCMU) (and timestamp also) so that I can distinguish whether it is audio/video. 我想打印rtp&rtcp有效负载类型(对于PCMU,H264 / 0为96)(以及时间戳),以便我可以区分它是音频/视频。

I can able to print those rtp/rtcp packet sequence numbers correctly but not palyload type. 我可以正确打印那些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;

Ex:getting payload type is 12288 and 0. But I have to get 96 and 0(as in wireshark). 例如:得到的有效载荷类型是12288和0。但是我必须得到96和0(如wireshark中)。

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

Ex:getting timestamp information is like 49892(5 digit decimal number) but I have to get values like 3269770717. 例如:获取时间戳信息就像49892(5位十进制数字),但我必须获取像3269770717这样的值。

The ntohs() function converts the unsigned short integer from network byte order to host byte order. ntohs()函数将无符号的短整数从网络字节顺序转换为主机字节顺序。 Note that it's byte order , so, for one-byte payload you don't need this conversion. 请注意,这是字节顺序 ,因此,对于一字节的有效负载,您不需要此转换。

For timestamp you should use ntohl() instead, since you are working with 32-bit value. 对于时间戳,您应该使用ntohl() ,因为您使用的是32位值。

Update I think this will be more natural than using fields: 更新我认为这比使用字段更自然:

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;

Well, you wrote the bitfield in big endian order, but I guess you use a little endian machine (Intel). 好吧,您以大字节序编写了位域,但我猜您使用的是小字节序机器(英特尔)。 And you should use uint16_t instaed of your unsigned int. 并且您应该使用unsigned int的uint16_t instaed。 You have only 16 bits, after all. 毕竟,您只有16位。

Its all about endianness. 其全部关于字节序。 So your struct should be according to endianness. 因此,您的结构应根据字节序排列。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM