0

I am trying to parse RTP-packets, this is what I do in my program:

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

And this is the output:

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

As you can see, the RTP version-number stays the same.

IP-Header size and length looks fine to me, as well as UDP-Length and ports.

Did I miss something?

binaryBigInt
  • 1,526
  • 2
  • 18
  • 44
  • looks like you're violating [strict aliasing](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) rules, `%d` is not the right format specifier to print `uint16_t`.. have you looked at the packed data to see if the RTP version number is actually changing? – yano Feb 25 '20 at 15:39
  • Well, the data I care about is printed with `%02X` and the data which is correct is printed with `%d`... – binaryBigInt Feb 25 '20 at 15:42

1 Answers1

0

The problem is, that I declared rtp_hdr as uint64_t* and therefore accessing &rtp_hdr[2] is not the 3rd byte but actually the 24th byte. Declaring uint8_t *rtp_hdr solves the problem.

binaryBigInt
  • 1,526
  • 2
  • 18
  • 44