我正在使用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这样的值。
答案 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
};