ccRTP 2.1.2
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rtppkt.cpp
Go to the documentation of this file.
1 // Copyright (C) 1999-2005 Open Source Telecom Corporation.
2 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
3 // Copyright (C) 2015 Cherokees of Idaho.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 //
19 // As a special exception, you may use this file as part of a free software
20 // library without restriction. Specifically, if other files instantiate
21 // templates or use macros or inline functions from this file, or you compile
22 // this file and link it with other files to produce an executable, this
23 // file does not by itself cause the resulting executable to be covered by
24 // the GNU General Public License. This exception does not however
25 // invalidate any other reasons why the executable file might be covered by
26 // the GNU General Public License.
27 //
28 // This exception applies only to the code released under the name GNU
29 // ccRTP. If you copy code from other releases into a copy of GNU
30 // ccRTP, as the General Public License permits, the exception does
31 // not apply to the code that you add in this way. To avoid misleading
32 // anyone as to the status of such modified files, you must delete
33 // this exception notice from them.
34 //
35 // If you write modifications of your own for GNU ccRTP, it is your choice
36 // whether to permit this exception to apply to your modifications.
37 // If you do not wish that, delete this exception notice.
38 //
39 
46 #include "private.h"
47 #include <ccrtp/rtppkt.h>
48 #include <ccrtp/CryptoContext.h>
49 
50 NAMESPACE_COMMONCPP
51 
52 // Default to 8Khz when no value is specified.
53 const uint32 PayloadFormat::defaultRTPClockRate = 8000;
54 
55 //uint32 PayloadFormat::staticRates[lastStaticPayloadType]
57  // audio types:
58  8000, // 0 - sptPCMU
59  0, // 1 - reserved
60  8000, // 2 - sptG726_32
61  8000, // 3 - sptGSM
62  8000, // 4 - sptG723
63  8000, // 5 - sptDVI4_8000
64  16000, // 6 - sptDVI4_16000
65  8000, // 7 - sptLPC
66  8000, // 8 - sptPCMA
67  8000, // 9 - sptG722
68  44100, // 10 - sptL16_DUAL
69  44100, // 11 - sptL16_MONO
70  8000, // 12 - sptQCELP
71  0, // 13 - reserved
72  90000, // 14 - sptMPA
73  8000, // 15 - sptG728
74  11015, // 16 - sptDVI4_11025
75  22050, // 17 - sptDVI4_22050
76  8000 // 18 - sptG729
77 /* 0, // reserved
78  0, // unassigned
79  0, // unassigned
80  0, // unassigned
81  0 // unassigned
82 */
83  // All video types have 90000 hz RTP clock rate.
84  // If sometime in the future a static video payload type is
85  // defined with a different RTP clock rate (quite
86  // unprobable). This table and/or the StaticPayloadType
87  // constructor must be changed.
88 };
89 
91 {
92  setPayloadType( (type <= lastStaticPayloadType)? type : 0);
93  if ( type <= sptG729 ) {
94  // audio static type
96  } else {
97  // video static type
98  setRTPClockRate(90000);
99  }
100 }
101 
103 {
105  setRTPClockRate(rate);
106 }
107 
108 // constructor commonly used for incoming packets
109 RTPPacket::RTPPacket(const unsigned char* const block, size_t len, bool duplicate) :
110 total((uint32)len), duplicated(duplicate)
111 {
112  const RTPFixedHeader* const header =
113  reinterpret_cast<const RTPFixedHeader*>(block);
114  hdrSize = sizeof(RTPFixedHeader) + (header->cc << 2);
115  if ( header->extension ){
116  RTPHeaderExt *ext = (RTPHeaderExt *)(block + hdrSize);
117  hdrSize += sizeof(uint32) + (ntohs(ext->length) * 4);
118  }
119  if ( header->padding )
120  len -= block[len - 1];
121  payloadSize = (uint32)(len - hdrSize);
122 
123  if ( duplicate ) {
124  buffer = new unsigned char[len];
125  setbuffer(block,len,0);
126  } else {
127  buffer = const_cast<unsigned char*>(block);
128  }
129 }
130 
131 // constructor commonly used for outgoing packets
132 RTPPacket::RTPPacket(size_t hdrlen, size_t plen, uint8 paddinglen, CryptoContext* pcc ) :
133 payloadSize((uint32)plen), buffer(NULL), hdrSize((uint32)hdrlen),
134 duplicated(false)
135 {
136  total = (uint32)(hdrlen + payloadSize);
137  // compute if there must be padding
138  uint8 padding = 0;
139  if ( 0 != paddinglen ) {
140  padding = paddinglen - (total % paddinglen);
141  total += padding;
142  }
143  srtpLength = 0;
144  srtpDataOffset = 0;
145  if (pcc != NULL) {
146  // compute additional memory for SRTP data
147  srtpLength = pcc->getTagLength() + pcc->getMkiLength();
148  srtpDataOffset = total; // SRTP data go behind header plus payload plus padding
149  }
150 
151  // now we know the actual total length of the packet, get some memory
152  // but take SRTP data into account. Don't change total because some RTP
153  // functions rely on the fact that total is the overall size (without
154  // the SRTP data)
155  buffer = new unsigned char[total + srtpLength];
156  *(reinterpret_cast<uint32*>(getHeader())) = 0;
158  if ( 0 != padding ) {
159  memset(buffer + total - padding,0,padding - 1);
160  buffer[total - 1] = padding;
161  getHeader()->padding = 1;
162  } else {
163  getHeader()->padding = 0;
164  }
165 }
166 
168 {
169 #ifdef CCXX_EXCEPTIONS
170  try {
171 #endif
172  delete [] buffer;
173 #ifdef CCXX_EXCEPTIONS
174  } catch (...) { };
175 #endif
176 }
177 
179 {
180  // If payloadsize was computed without padding set then re-compute
181  // payloadSize after the padding bit was set and set padding flag
182  // in RTP header - option for SRTP
183  if (padding) {
184  size_t len = 0;
185  getHeader()->padding = 1;
186  len -= buffer[payloadSize - 1];
187  payloadSize = (uint32)(payloadSize - len);
188  }
189 }
190 
191 OutgoingRTPPkt::OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
192 const unsigned char* const hdrext, uint32 hdrextlen,
193 const unsigned char* const data, size_t datalen,
194 uint8 paddinglen, CryptoContext* pcc) :
195 RTPPacket((getSizeOfFixedHeader() + sizeof(uint32) * numcsrc + hdrextlen),datalen,paddinglen, pcc)
196 {
197  uint32 pointer = (uint32)getSizeOfFixedHeader();
198  // add CSCR identifiers (putting them in network order).
199  setCSRCArray(csrcs,numcsrc);
200  pointer += numcsrc * sizeof(uint32);
201 
202  // add header extension.
203  setbuffer(hdrext,hdrextlen,pointer);
204  setExtension(hdrextlen > 0);
205  pointer += hdrextlen;
206 
207  // add data.
208  setbuffer(data,datalen,pointer);
209 }
210 
211 OutgoingRTPPkt::OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
212 const unsigned char* data, size_t datalen, uint8 paddinglen, CryptoContext* pcc) :
213 RTPPacket((getSizeOfFixedHeader() + sizeof(uint32) *numcsrc),datalen, paddinglen, pcc)
214 {
215  uint32 pointer = (uint32)getSizeOfFixedHeader();
216  // add CSCR identifiers (putting them in network order).
217  setCSRCArray(csrcs,numcsrc);
218  pointer += numcsrc * sizeof(uint32);
219 
220  // not needed, as the RTPPacket constructor sets by default
221  // the whole fixed header to 0.
222  // getHeader()->extension = 0;
223 
224  // add data.
225  setbuffer(data,datalen,pointer);
226 }
227 
228 OutgoingRTPPkt::OutgoingRTPPkt(const unsigned char* data, size_t datalen,
229 uint8 paddinglen, CryptoContext* pcc) :
230 RTPPacket(getSizeOfFixedHeader(),datalen,paddinglen, pcc)
231 {
232  // not needed, as the RTPPacket constructor sets by default
233  // the whole fixed header to 0.
234  //getHeader()->cc = 0;
235  //getHeader()->extension = 0;
236 
237  setbuffer(data,datalen,getSizeOfFixedHeader());
238 }
239 
240 void OutgoingRTPPkt::setCSRCArray(const uint32* const csrcs, uint16 numcsrc)
241 {
242  setbuffer(csrcs, numcsrc * sizeof(uint32),getSizeOfFixedHeader());
243  uint32* csrc = const_cast<uint32*>(getCSRCs());
244  for ( int i = 0; i < numcsrc; i++ )
245  csrc[i] = htonl(csrc[i]);
246  getHeader()->cc = numcsrc;
247 }
248 
249 void OutgoingRTPPkt::protect(uint32 ssrc, CryptoContext* pcc)
250 {
251  /* Encrypt the packet */
252  uint64 index = ((uint64)pcc->getRoc() << 16) | (uint64)getSeqNum();
253 
254  pcc->srtpEncrypt(this, index, ssrc);
255 
256  // NO MKI support yet - here we assume MKI is zero. To build in MKI
257  // take MKI length into account when storing the authentication tag.
258 
259  /* Compute MAC */
260  pcc->srtpAuthenticate(this, pcc->getRoc(),
261  const_cast<uint8*>(getRawPacket()+srtpDataOffset) );
262  /* Update the ROC if necessary */
263  if (getSeqNum() == 0xFFFF ) {
264  pcc->setRoc(pcc->getRoc() + 1);
265  }
266 }
267 
268 // These masks are valid regardless of endianness.
269 const uint16 IncomingRTPPkt::RTP_INVALID_PT_MASK = (0x7e);
270 const uint16 IncomingRTPPkt::RTP_INVALID_PT_VALUE = (0x48);
271 
272 IncomingRTPPkt::IncomingRTPPkt(const unsigned char* const block, size_t len) :
273 RTPPacket(block,len)
274 {
275  // first, perform validity check:
276  // 1) check protocol version
277  // 2) it is not an SR nor an RR
278  // 3) consistent length field value (taking CC value and P and
279  // X bits into account)
281  /*
282  ||
283  getPayloadSize() <= 0 ) {
284  */
285  headerValid = false;
286  return;
287  }
288  headerValid = true;
290  cachedSeqNum = ntohs(getHeader()->sequence);
291  cachedSSRC = ntohl(getHeader()->sources[0]);
292 }
293 
295 {
296  if (pcc == NULL) {
297  return true;
298  }
299 
300  /*
301  * This is the setting of the packet data when we come to this
302  * point:
303  *
304  * total: complete length of received data
305  * buffer: points to data as received from network
306  * hdrSize: length of header including header extension
307  * payloadSize: length of data excluding hdrSize and padding
308  *
309  * Because this is an SRTP packet we need to adjust some values here.
310  * The SRTP MKI and authentication data is always at the end of a
311  * packet. Thus compute the position of this data.
312  */
313 
314  uint32 srtpDataIndex = total - (pcc->getTagLength() + pcc->getMkiLength());
315 
316  // now adjust total because some RTP functions rely on the fact that
317  // total is the full length of data without SRTP data.
318  total -= pcc->getTagLength() + pcc->getMkiLength();
319 
320  // recompute payloadSize by subtracting SRTP data
321  payloadSize -= pcc->getTagLength() + pcc->getMkiLength();
322 
323  // unused??
324  // const uint8* mki = getRawPacket() + srtpDataIndex;
325  const uint8* tag = getRawPacket() + srtpDataIndex + pcc->getMkiLength();
326 
327  /* Replay control */
328  if (!pcc->checkReplay(cachedSeqNum)) {
329  return -2;
330  }
331  /* Guess the index */
332  uint64 guessedIndex = pcc->guessIndex(cachedSeqNum);
333 
334  uint32 guessedRoc = (uint32)(guessedIndex >> 16);
335  uint8* mac = new uint8[pcc->getTagLength()];
336 
337  pcc->srtpAuthenticate(this, guessedRoc, mac);
338  if (memcmp(tag, mac, pcc->getTagLength()) != 0) {
339  delete[] mac;
340  return -1;
341  }
342  delete[] mac;
343 
344  /* Decrypt the content */
345  pcc->srtpEncrypt( this, guessedIndex, cachedSSRC );
346 
347  /* Update the Crypto-context */
348  pcc->update(cachedSeqNum);
349 
350  return 1;
351 }
352 
353 END_NAMESPACE
354 
Fixed component of the variable-length header extension, appended to the fixed header, after the CSRC list, when X == 1.
Definition: rtppkt.h:460
uint32 total
total length, including header, payload and padding
Definition: rtppkt.h:376
size_t getSizeOfFixedHeader() const
Definition: rtppkt.h:286
A base class for both IncomingRTPPkt and OutgoingRTPPkt.
Definition: rtppkt.h:72
void srtpAuthenticate(RTPPacket *rtp, uint32 roc, uint8 *tag)
Compute the authentication tag.
int32 getMkiLength() const
Get the length of the MKI in bytes.
The implementation for a SRTP cryptographic context.
Definition: CryptoContext.h:82
void setRoc(uint32 r)
Set the Roll-Over-Counter.
const uint8 CCRTP_VERSION
RTP protocol version supported.
Definition: base.h:64
void reComputePayLength(bool padding)
Re-compute payload length.
Definition: rtppkt.cpp:178
PayloadType getPayloadType() const
Definition: rtppkt.h:135
uint32 getRawTimestamp() const
Obtain the absolute timestamp carried in the packet header.
Definition: rtppkt.h:348
const uint32 * getCSRCs() const
Get the 32-bit identifiers of the contributing sources for the packet as an array, of length getCSRCsCount().
Definition: rtppkt.h:212
StaticPayloadFormat(StaticPayloadType type)
Constructor.
Definition: rtppkt.cpp:90
unsigned char version
Version, currently 2.
Definition: rtppkt.h:417
uint32 getRoc() const
Get the Roll-Over-Counter.
static uint32 staticAudioTypesRates[lastStaticAudioPayloadType-firstStaticPayloadType+1]
RTP clock rate for static payload types.
Definition: formats.h:220
Declaration of ccRTP internal stuff.
static const uint32 defaultRTPClockRate
Definition: formats.h:181
int32 unprotect(CryptoContext *pcc)
Unprotect a received packet.
Definition: rtppkt.cpp:294
unsigned char * buffer
packet in memory
Definition: rtppkt.h:383
OutgoingRTPPkt(const uint32 *const csrcs, uint16 numcsrc, const unsigned char *const hdrext, uint32 hdrextlen, const unsigned char *const data, size_t datalen, uint8 paddinglen=0, CryptoContext *pcc=NULL)
Construct a new packet to be sent, containing several contributing source identifiers, header extensions and payload.
Definition: rtppkt.cpp:191
unsigned char extension
Extension bit.
Definition: rtppkt.h:415
static const uint16 RTP_INVALID_PT_VALUE
Definition: rtppkt.h:795
bool checkReplay(uint16 newSeqNumber)
Check for packet replay.
void srtpEncrypt(RTPPacket *rtp, uint64 index, uint32 ssrc)
Perform SRTP encryption.
uint32 srtpDataOffset
Offset into packet memory pointing to area for SRTP data.
Definition: rtppkt.h:366
IncomingRTPPkt(const unsigned char *block, size_t len)
Build an RTP packet object from a data buffer.
Definition: rtppkt.cpp:272
RTPFixedHeader * getHeader() const
Return low level structure for the header of the packet.
Definition: rtppkt.h:321
void setRTPClockRate(uint32 rate)
Set RTP clock rate.
Definition: formats.h:177
uint8 getProtocolVersion() const
Definition: rtppkt.h:156
uint32 cachedTimestamp
Packet timestamp in host order (includes initial shift).
Definition: rtppkt.h:358
uint16 getSeqNum() const
Definition: rtppkt.h:142
uint16 length
number of 32-bit words in the extension
Definition: rtppkt.h:463
static const uint16 RTP_INVALID_PT_MASK
Definition: rtppkt.h:794
unsigned char padding
Padding bit.
Definition: rtppkt.h:416
const unsigned char *const getRawPacket() const
Get the raw packet as it will be sent through the network.
Definition: rtppkt.h:268
uint32 cachedSSRC
SSRC 32-bit identifier in host order.
Definition: rtppkt.h:790
void endPacket()
Free memory allocated for the packet.
Definition: rtppkt.cpp:167
void setPayloadType(PayloadType pt)
Set payload type numeric identifier carried in RTP packets.
Definition: formats.h:169
void update(uint16 newSeqNumber)
Update the SRTP packet index.
int32 getTagLength() const
Get the length of the SRTP authentication tag in bytes.
RTP fixed header as it is send through the network.
Definition: rtppkt.h:402
bool headerValid
Header validity, checked at construction time.
Definition: rtppkt.h:788
ITU-T G.729. CS-ACELP audio.
Definition: formats.h:95
void setbuffer(const void *src, size_t len, size_t pos)
Definition: rtppkt.h:352
uint64 guessIndex(uint16 newSeqNumber)
Compute (guess) the new SRTP index based on the sequence number of a received RTP packet...
DynamicPayloadFormat(PayloadType type, uint32 rate)
Constructor.
Definition: rtppkt.cpp:102
void protect(uint32 ssrc, CryptoContext *pcc)
Called packet is setup.
Definition: rtppkt.cpp:249
void setCSRCArray(const uint32 *const csrcs, uint16 numcsrc)
Set the list of CSRC identifiers in an RTP packet, switching host to network order.
Definition: rtppkt.cpp:240
void setExtension(bool e)
Definition: rtppkt.h:325
RTPPacket(const unsigned char *const block, size_t len, bool duplicate=false)
Constructor, construct a packet object given the memory zone its content (header and payload) is stor...
Definition: rtppkt.cpp:109
uint32 hdrSize
size of the header, including contributing sources and extensions
Definition: rtppkt.h:385
unsigned char cc
For little endian boxes.
Definition: rtppkt.h:414
int32 srtpLength
Lebgth of additional SRTP data.
Definition: rtppkt.h:373
StaticPayloadType
RTP static payload types (default bindings) defined in the AVP profile.
Definition: formats.h:73
uint16 cachedSeqNum
Packet sequence number in host order.
Definition: rtppkt.h:356
RTP packets handling.
uint32 payloadSize
note: payload (not full packet) size.
Definition: rtppkt.h:379
uint8 PayloadType
RTP payload type numeric identifier.
Definition: formats.h:62