1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <strings.h>
5 #include <arpa/inet.h>
6 #include "rtp.h"
7 #include "rtpacket.h"
8
9 #ifndef TRUE
10 #define TRUE 1
11 #define FALSE 0
12 #endif
13
14 extern char callsign[], name[];
15
16 /*************** RTP_MAKE_SDES *************/
17
18 static unsigned char *ap;
addSDES(unsigned char item,char * text)19 static void addSDES(unsigned char item, char *text)
20 {
21 int l;
22 *ap++ = item;
23 *ap++ = l = strlen(text);
24 bcopy(text, ap, l);
25 ap += l;
26 }
27
rtp_make_sdes(pkt,ssrc_i,strict)28 int rtp_make_sdes(pkt, ssrc_i, strict)
29 char **pkt;
30 unsigned long ssrc_i;
31 int strict;
32 {
33 unsigned char zp[1500];
34 unsigned char *p = zp;
35 rtcp_t *rp;
36 char *sp, *ep;
37 char line[180];
38 int l, hl, i;
39 struct passwd *pw;
40 char s[256], ev[1024];
41
42 hl = 0;
43 if (strict) {
44 *p++ = RTP_VERSION << 6;
45 *p++ = RTCP_RR;
46 *p++ = 0;
47 *p++ = 1;
48 *((long *) p) = htonl(ssrc_i);
49 p += 4;
50 hl = 8;
51 }
52
53 rp = (rtcp_t *) p;
54
55 // #define RationalWorld
56 #ifdef RationalWorld
57 rp->common.version = RTP_VERSION;
58 rp->common.p = 0;
59 rp->common.count = 1;
60 rp->common.pt = RTCP_SDES;
61 #else
62 *((short *) p) = htons((RTP_VERSION << 14) | RTCP_SDES | (1 << 8));
63 #endif
64 rp->r.sdes.src = htonl(ssrc_i);
65
66 ap = (unsigned char *) rp->r.sdes.item;
67
68 /*****
69 At this point ap points to the beginning of the first SDES item
70 *******/
71
72 strcpy(line,"CALLSIGN");
73 addSDES(RTCP_SDES_CNAME, line);
74
75 sprintf(line,"%-15s%s", callsign, name);
76 addSDES(RTCP_SDES_NAME, line);
77
78 strcpy(line,"CALLSIGN");
79 addSDES(RTCP_SDES_EMAIL, line);
80
81 strcpy(line,"08:30");
82 addSDES(RTCP_SDES_PHONE, line);
83
84 *ap++ = RTCP_SDES_END;
85 *ap++ = 0;
86
87 l = ap - p;
88
89 rp->common.length = htons(((l + 3) / 4) - 1);
90 l = hl + ((ntohs(rp->common.length) + 1) * 4);
91
92 /* Okay, if the total length of this packet is not an odd
93 multiple of 4 bytes, we're going to put a pad at the
94 end of it. Why? Because we may encrypt the packet
95 later and that requires it be a multiple of 8 bytes,
96 and we don't want the encryption code to have to
97 know all about our weird composite packet structure.
98 Oh yes, there's no reason to do this if strict isn't
99 set, since we never encrypt packets sent to a Look
100 Who's Listening server.
101
102 Why an odd multiple of 4 bytes, I head you ask?
103 Because when we encrypt an RTCP packet, we're required
104 to prefix it with four random bytes to deter a known
105 plaintext attack, and since the total buffer we
106 encrypt, including the random bytes, has to be a
107 multiple of 8 bytes, the message needs to be an odd
108 multiple of 4. */
109
110 if (strict) {
111 int pl = (l & 4) ? l : l + 4;
112
113 if (pl > l) {
114 int pad = pl - l;
115
116 bzero(zp + l, pad); /* Clear pad area to zero */
117 zp[pl - 1] = pad; /* Put pad byte count at end of packet */
118 p[0] |= 0x20; /* Set the "P" bit in the header of the
119 SDES (last in message) packet */
120 /* If we've added an additional word to
121 the packet, adjust the length in the
122 SDES message, which must include the
123 pad */
124 rp->common.length = htons(ntohs(rp->common.length) + ((pad) / 4));
125 l = pl; /* Include pad in length of packet */
126 }
127 }
128
129 *pkt = (char *) malloc(l);
130 if (*pkt != NULL) {
131 bcopy(zp, *pkt, l);
132 return l;
133 }
134 return 0;
135 }
136
137 /************* RTP_MAKE_BYE ***************/
138
rtp_make_bye(p,ssrc_i,raison,strict)139 int rtp_make_bye(p, ssrc_i, raison, strict)
140 unsigned char *p;
141 unsigned long ssrc_i;
142 char *raison;
143 int strict;
144 {
145 rtcp_t *rp;
146 unsigned char *ap, *zp;
147 int l, hl;
148
149 /* If requested, prefix the packet with a null receiver
150 report. This is required by the RTP spec, but is not
151 required in packets sent only to the Look Who's Listening
152 server. */
153
154 zp = p;
155 hl = 0;
156 if (strict) {
157 *p++ = RTP_VERSION << 6;
158 *p++ = RTCP_RR;
159 *p++ = 0;
160 *p++ = 1;
161 *((long *) p) = htonl(ssrc_i);
162 p += 4;
163 hl = 8;
164 }
165
166 rp = (rtcp_t *) p;
167 #ifdef RationalWorld
168 rp->common.version = RTP_VERSION;
169 rp->common.p = 0;
170 rp->common.count = 1;
171 rp->common.pt = RTCP_BYE;
172 #else
173 *((short *) p) = htons((RTP_VERSION << 14) | RTCP_BYE | (1 << 8));
174 #endif
175 rp->r.bye.src[0] = htonl(ssrc_i);
176
177 ap = (unsigned char *) rp->r.sdes.item;
178
179 l = 0;
180 if (raison != NULL) {
181 l = strlen(raison);
182 if (l > 0) {
183 *ap++ = l;
184 bcopy(raison, ap, l);
185 ap += l;
186 }
187 }
188
189 while ((ap - p) & 3) {
190 *ap++ = 0;
191 }
192 l = ap - p;
193
194 rp->common.length = htons((l / 4) - 1);
195
196 l = hl + ((ntohs(rp->common.length) + 1) * 4);
197
198 /* If strict, pad the composite packet to an odd multiple of 4
199 bytes so that if we decide to encrypt it we don't have to worry
200 about padding at that point. */
201
202 if (strict) {
203 int pl = (l & 4) ? l : l + 4;
204
205 if (pl > l) {
206 int pad = pl - l;
207
208 bzero(zp + l, pad); /* Clear pad area to zero */
209 zp[pl - 1] = pad; /* Put pad byte count at end of packet */
210 p[0] |= 0x20; /* Set the "P" bit in the header of the
211 SDES (last in message) packet */
212 /* If we've added an additional word to
213 the packet, adjust the length in the
214 SDES message, which must include the
215 pad */
216 rp->common.length = htons(ntohs(rp->common.length) + ((pad) / 4));
217 l = pl; /* Include pad in length of packet */
218 }
219 }
220
221 return l;
222 }
223
224 /* PARSESDES -- Look for an SDES message in a possibly composite
225 RTCP packet and extract pointers to selected items
226 into the caller's structure. */
227
228 /***************************************************/
229
parseSDES(packet,r)230 int parseSDES(packet, r)
231 unsigned char *packet;
232 struct rtcp_sdes_request *r;
233 {
234 int i, success = FALSE;
235 unsigned char *p = packet;
236
237 /* Initialise all the results in the request packet to NULL. */
238
239 for (i = 0; i < r->nitems; i++) {
240 r->item[i].r_text = NULL;
241 }
242
243 /* Walk through the individual items in a possibly composite
244 packet until we locate an SDES. This allows us to accept
245 packets that comply with the RTP standard that all RTCP packets
246 begin with an SR or RR. */
247
248 while ((p[0] >> 6 & 3) == RTP_VERSION || (p[0] >> 6 & 3) == 1) {
249 if ((p[1] == RTCP_SDES) && ((p[0] & 0x1F) > 0)) {
250 unsigned char *cp = p + 8,
251 *lp = cp + (ntohs(*((short *) (p + 2))) + 1) * 4;
252 bcopy(p + 4, r->ssrc, 4);
253 while (cp < lp) {
254 unsigned char itype = *cp;
255
256 if (itype == RTCP_SDES_END) {
257 break;
258 }
259
260 /* Search for a match in the request and fill the
261 first unused matching item. We do it this way to
262 permit retrieval of multiple PRIV items in the same
263 packet. */
264
265 for (i = 0; i < r->nitems; i++) {
266 if (r->item[i].r_item == itype &&
267 r->item[i].r_text == NULL) {
268 r->item[i].r_text = (char *) cp;
269 success = TRUE;
270 break;
271 }
272 }
273 cp += cp[1] + 2;
274 }
275 break;
276 }
277 /* If not of interest to us, skip to next subpacket. */
278 p += (ntohs(*((short *) (p + 2))) + 1) * 4;
279 }
280 return success;
281 }
282
283 /*************************************/
284 /* COPYSDESITEM -- Copy an SDES item to a zero-terminated user
285 string. */
286
copySDESitem(s,d)287 void copySDESitem(s, d)
288 char *s, *d;
289 {
290 int len = s[1] & 0xFF;
291
292 bcopy(s + 2, d, len);
293 d[len] = 0;
294 }
295
296 /************************************/
297 /* ISRTCPBYEPACKET -- Test if this RTCP packet contains a BYE. */
298
isRTCPByepacket(p,len)299 int isRTCPByepacket(p, len)
300 unsigned char *p;
301 int len;
302 {
303 unsigned char *end;
304 int sawbye = FALSE;
305 /* Version incorrect ? */
306 if ((((p[0] >> 6) & 3) != RTP_VERSION && ((p[0] >> 6) & 3) != 1) ||
307 ((p[0] & 0x20) != 0) || /* Padding in first packet ? */
308 ((p[1] != RTCP_SR) && (p[1] != RTCP_RR))) { /* First item not SR or RR ? */
309 return FALSE;
310 }
311 end = p + len;
312
313 do {
314 if (p[1] == RTCP_BYE) {
315 sawbye = TRUE;
316 }
317 /* Advance to next subpacket */
318 p += (ntohs(*((short *) (p + 2))) + 1) * 4;
319 } while (p < end && (((p[0] >> 6) & 3) == RTP_VERSION));
320
321 return (sawbye);
322 }
323
324 /************************************/
325 /* ISRTCPSDESPACKET -- Test if this RTCP packet contains a BYE. */
326
isRTCPSdespacket(p,len)327 int isRTCPSdespacket(p, len)
328 unsigned char *p;
329 int len;
330 {
331 unsigned char *end;
332 int sawsdes = FALSE;
333 /* Version incorrect ? */
334 if ((((p[0] >> 6) & 3) != RTP_VERSION && ((p[0] >> 6) & 3) != 1) ||
335 ((p[0] & 0x20) != 0) || /* Padding in first packet ? */
336 ((p[1] != RTCP_SR) && (p[1] != RTCP_RR))) { /* First item not SR or RR ? */
337 return FALSE;
338 }
339 end = p + len;
340
341 do {
342 if (p[1] == RTCP_SDES) {
343 sawsdes = TRUE;
344 }
345 /* Advance to next subpacket */
346 p += (ntohs(*((short *) (p + 2))) + 1) * 4;
347 } while (p < end && (((p[0] >> 6) & 3) == RTP_VERSION));
348
349 return (sawsdes);
350 }
351
352