【发布时间】:2020-02-25 15:28:22
【问题描述】:
我正在尝试解析 RTP 数据包,这就是我在程序中所做的:
uint8_t *pkt = xsk_umem__get_data(xsk->umem->buffer, addr);
struct ethhdr *eth = (struct ethhdr*) pkt;
const uint16_t packetIPVersion = ntohs(eth->h_proto);
if(packetIPVersion == ETH_P_IPV6) {
printf("IPv6!\n");
} else if(packetIPVersion == ETH_P_IP) {
struct iphdr *iph = (struct iphdr*)(pkt + sizeof(struct ethhdr));
if(iph->protocol == IPPROTO_UDP) {
const uint16_t iph_sz_in_bytes = iph->ihl * 4;
const uint16_t iph_tot_lngth = ntohs(iph->tot_len);
printf("IP-Header size: %d\n", iph_sz_in_bytes);
printf("IP-Length: %d\n", iph_tot_lngth);
struct udphdr *udh = (struct udphdr*)(pkt + sizeof(struct ethhdr) + iph_sz_in_bytes);
printf("UDP-len: %d\n", ntohs(udh->len));
printf("UDP-SRC Port: %d\n", ntohs(udh->source));
printf("UDP-DEST PORT: %d\n", ntohs(udh->dest));
uint64_t *rtp_hdr = (uint64_t*)(pkt + sizeof(struct ethhdr) + iph_sz_in_bytes + sizeof(struct udphdr));
uint16_t *rtp_vrsn_nmbr = &rtp_hdr[0];
uint16_t *rtp_sqnz_nmbr = &rtp_hdr[2];
uint32_t *rtp_tmstmp = &rtp_hdr[4];
printf("RTP-VRSN-NMBR: 0x%02X\n", ntohs(*rtp_vrsn_nmbr));
printf("RTP-SQNZ-NMBR: 0x%02X\n", ntohs(*rtp_sqnz_nmbr));
printf("RTP-TMSTMP: 0x%04X\n", ntohs(*rtp_tmstmp));
}
}
这是输出:
IP-Header size: 20
IP-Length: 1428
UDP-len: 1408
UDP-SRC Port: xxxx
UDP-DEST PORT: xxxx
RTP-VRSN-NMBR: 0x8062
RTP-SQNZ-NMBR: 0x211
RTP-TMSTMP: 0xA169
IP-Header size: 20
IP-Length: 1428
UDP-len: 1408
UDP-SRC Port: xxxx
UDP-DEST PORT: xxxx
RTP-VRSN-NMBR: 0x8062
RTP-SQNZ-NMBR: 0x211
RTP-TMSTMP: 0x357A
IP-Header size: 20
IP-Length: 1428
UDP-len: 1408
UDP-SRC Port: xxxx
UDP-DEST PORT: xxxx
RTP-VRSN-NMBR: 0x8062
RTP-SQNZ-NMBR: 0x211
RTP-TMSTMP: 0x63C4
如您所见,RTP 版本号保持不变。
IP-Header 的大小和长度对我来说很好,还有 UDP-Length 和端口。
我错过了什么吗?
【问题讨论】:
-
看起来您违反了strict aliasing 规则,
%d不是打印uint16_t的正确格式说明符。您查看了打包数据以查看 RTP 版本号是否为真的变了吗? -
嗯,我关心的数据用
%02X打印,正确的数据用%d打印...
标签: c linux networking rtp