xref: /plan9/sys/src/cmd/ip/snoopy/rtcp.c (revision e6dcbf51e935975016093545b6eab69976b6e257)
1 #include <u.h>
2 #include <libc.h>
3 #include <ip.h>
4 #include "dat.h"
5 #include "protos.h"
6 
7 typedef struct Hdr Hdr;
8 struct Hdr {
9 	uchar	hdr;		/* RTCP header */
10 	uchar	pt;		/* Packet type */
11 	uchar	len[2];		/* Report length */
12 	uchar	ssrc[4];	/* Synchronization source identifier */
13 	uchar	ntp[8];		/* NTP time stamp */
14 	uchar	rtp[4];		/* RTP time stamp */
15 	uchar	pktc[4];	/* Sender's packet count */
16 	uchar	octc[4];	/* Sender's octet count */
17 };
18 
19 typedef struct Report Report;
20 struct Report {
21 	uchar	ssrc[4];	/* SSRC identifier */
22 	uchar	lost[4];	/* Fraction + cumu lost */
23 	uchar	seqhi[4];	/* Highest seq number received */
24 	uchar	jitter[4];	/* Interarrival jitter */
25 	uchar	lsr[4];		/* Last SR */
26 	uchar	dlsr[4];	/* Delay since last SR */
27 };
28 
29 enum{
30 	RTCPLEN = 28,		/* Minimum size of an RTCP header */
31 	REPORTLEN = 24,
32 };
33 
34 static int
p_seprint(Msg * m)35 p_seprint(Msg *m)
36 {
37 	int rc, i, frac;
38 	float dlsr;
39 	Hdr*h;
40 	Report*r;
41 
42 	if(m->pe - m->ps < RTCPLEN)
43 		return -1;
44 
45 	h = (Hdr*)m->ps;
46 	if(m->pe - m->ps < (NetS(h->len) + 1) * 4)
47 		return -1;
48 
49 	rc = h->hdr & 0x1f;
50 	m->ps += RTCPLEN;
51 	m->p = seprint(m->p, m->e, "version=%d rc=%d tp=%d ssrc=%8ux "
52 		"ntp=%d.%.10ud rtp=%d pktc=%d octc=%d hlen=%d",
53 		(h->hdr >> 6) & 3, rc, h->pt, NetL(h->ssrc), NetL(h->ntp),
54 		(uint)NetL(&h->ntp[4]), NetL(h->rtp), NetL(h->pktc),
55 		NetL(h->octc), (NetS(h->len) + 1) * 4);
56 
57 	for(i = 0; i < rc; i++){
58 		r = (Report*)m->ps;
59 		m->ps += REPORTLEN;
60 
61 		frac = (int)((r->lost[0] * 100.) / 256.);
62 		r->lost[0] = 0;
63 		dlsr = NetL(r->dlsr) / 65536.;
64 
65 		m->p = seprint(m->p, m->e, "\n\trr(csrc=%8ux frac=%3d%% "
66 			"cumu=%10d seqhi=%10ud jitter=%10d lsr=%8ux dlsr=%f)",
67 			NetL(r->ssrc), frac, NetL(r->lost), NetL(r->seqhi),
68 			NetL(r->jitter), NetL(r->lsr), dlsr);
69 	}
70 	m->pr = nil;
71 	return 0;
72 }
73 
74 Proto rtcp = {
75 	"rtcp",
76 	nil,
77 	nil,
78 	p_seprint,
79 	nil,
80 	nil,
81 	nil,
82 	defaultframer,
83 };
84