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