[Live-devel] bug in RTCPInstance::processIncomingReport (RTCP.cpp)

Frederik De Ruyck frederik.deruyck at vsk.be
Wed Nov 16 03:17:25 PST 2016


Hi,

I figured out that the RTCP packet was not the first packet (*pkt) in 
the buffer meaning that we may have a compound RTCP packet with 
individual subpackets.

I've copied the entire 1456 bytes of fInBuf and now I can simulate the 
issue offline, the test code you can find in attachment.

Copy the code to main.cpp, build and link with livemedia.so to test.

regards,

Frederik De Ruyck


Op 15/11/2016 om 15:53 schreef Frederik De Ruyck:
> Hi Ross,
>
> unfortunately I could not find any packet that allowed me to reproduce 
> the issue (feeding hard coded data to processIncomingReport with info 
> I'd collected from memory right before the crash).
>
> What looks like a quick fix to me is the following:
>
> there is a code line in RTCP.cpp::processIncomingReport which checks 
> if the remaining "packetSize" is smaller than the next chunk (defined 
> by "length") =>  if (length > packetSize) break;
>
> If so, the loop exits and so the call to processIncomingReport.
>
> It seems to me that this check was to prevent faulty processing or 
> input, though I believe in my case this is insufficient.
>
> If "packetSize" is able to drop below zero (effectively making it a 
> very big number as it is unsigned) then "length" always has a 
> corrupted value because it is derived from "pkt" which is invalid 
> since "packetSize" is < 0.
>
> Because "packetSize" is then over four billion (it dropped below 
> zero), length is very likely to be smaller, allowing the code to 
> continue execution and to go rampage reading from random memory.
>
> The check would have been ok if packetSize would be of a signed type, 
> allowing it to be smaller than zero.
>
> My suggestion is to replace "#define ADVANCE(n) pkt += (n); packetSize 
> -= (n);" with "#define ADVANCE(n) if (! okPkt(pkt, totPacketSize, n)) 
> break; pkt += (n); packetSize -= (n);"
>
> and to add "okPkt":
>
> bool RTCPInstance::okPkt(const unsigned char* const pkt, const 
> unsigned totPacketSize, const int n) const
> {
>     const u_int8_t* const nextPkt = pkt + n;
>
>     if ( nextPkt < fInBuf || nextPkt >= (fInBuf + maxRTCPPacketSize) )
>     {
>         printf("index ptr out of array bounds at incoming RTCP packet");
>         return false;
>     }
>     else if ( nextPkt >= (fInBuf + totPacketSize) )
>     {
>         printf("index ptr out of packet bounds at incoming RTCP packet");
>         return false;
>     }
>     return true;
> }
>
> Combining a memory range check with pointer arithmetic is a lot safer 
> than relying on expected input.
>
> I'll send through more info about what triggers this if I find any.
>
> Regards,
>
> Frederik De Ruyck
>
> Op 14/11/2016 om 09:54 schreef Frederik De Ruyck:
>> Hi,
>>
>> Last week I've experienced a crash at:
>>
>> void RTCPInstance::processIncomingReport(unsigned packetSize
>>       , struct sockaddr_in const& fromAddressAndPort
>>       , int tcpSocketNum
>>       , unsigned char tcpStreamChannelId)
>>
>> at line:
>>
>> rtcpHdr = ntohl(*(u_int32_t*)pkt);
>>
>> I've upgraded to the last version of Live555 (06-11-2016) to confirm 
>> that the issue is still present.
>>
>> I've had this crash three times with version 07-08-2016 and now today 
>> a fourth time with latest 06-11-2016.
>>
>> I've debugged the code and the crash is of type segfault because the 
>> memory dereferenced at address pkt is likely outside the 
>> application's memory space.
>>
>> This is caused because packetSize is decremented beyond 0, the value 
>> of "packetSize" at the time of the crash is 4294068404, it is of 
>> unsigned type so it overflows to a huge number when it drops below 0.
>>
>> It is the macro ADVANCE(length) that causes the pointer "pkt" to 
>> refer to an address that is beyond the scope of "fInBuf_ptr".
>>
>> I will now try to copy the incoming packet contents out of my 
>> debugger memory editor and see if I can create a test case with that.
>>
>> Regards,
>>
>> Frederik De Ruyck
>>
>>
>>
>> This email has been scanned by BullGuard antivirus protection.
>> For more info visit www.bullguard.com
>>
>>
>>
>> _______________________________________________
>> live-devel mailing list
>> live-devel at lists.live555.com
>> http://lists.live555.com/mailman/listinfo/live-devel
>>
>>
>
>
>
> This email has been scanned by BullGuard antivirus protection.
> For more info visit www.bullguard.com
>
>
>
> _______________________________________________
> live-devel mailing list
> live-devel at lists.live555.com
> http://lists.live555.com/mailman/listinfo/live-devel
>
>




This email has been scanned by BullGuard antivirus protection.
For more info visit www.bullguard.com

-------------- next part --------------
/*
build info:
make sure liveMedia, BasicUsageEnvironment, UsageEnvironment, groupsock and their include directories are available in your INCLUDEPATH
link to your livemedia.so
use c++14
*/

#include <cstdint>
#include "/usr/include/netinet/in.h"
#include "/usr/include/i386-linux-gnu/bits/sockaddr.h"
#include "RTCP.hh"
#include "RTPSink.hh"
#include "Boolean.hh"
#include "rtcp_from_spec.h"
#include "RTPSource.hh"

RTPSink* fSink = NULL;
RTPSource* fSource = NULL;
TaskFunc* fSRHandlerTask = NULL;
void* fSRHandlerClientData = NULL;
TaskFunc* fByeHandlerTask = NULL;
Boolean fByeHandleActiveParticipantsOnly = 234;
RTCPAppHandlerFunc* fAppHandlerTask = NULL;
void* fAppHandlerClientData = NULL;
void* fByeHandlerClientData = NULL;
unsigned const maxRTCPPacketSize = 1456;

u_int8_t fInBuf[maxRTCPPacketSize] = \
{ (u_int8_t) 0x80, (u_int8_t) 0xc8, (u_int8_t) 0x00, (u_int8_t) 0x06
, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x22, (u_int8_t) 0x13
, (u_int8_t) 0xdb, (u_int8_t) 0xd6, (u_int8_t) 0x9b, (u_int8_t) 0x70
, (u_int8_t) 0x97, (u_int8_t) 0x0a, (u_int8_t) 0x3d, (u_int8_t) 0x70
, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x04, (u_int8_t) 0x2c
, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x01
, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x02, (u_int8_t) 0xb9
, (u_int8_t) 0x81, (u_int8_t) 0xca, (u_int8_t) 0x00, (u_int8_t) 0x06
, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x22, (u_int8_t) 0x13
, (u_int8_t) 0x01, (u_int8_t) 0x0e, (u_int8_t) 0x51, (u_int8_t) 0x54
, (u_int8_t) 0x53, (u_int8_t) 0x53, (u_int8_t) 0x31, (u_int8_t) 0x34
, (u_int8_t) 0x37, (u_int8_t) 0x39, (u_int8_t) 0x32, (u_int8_t) 0x38
, (u_int8_t) 0x36, (u_int8_t) 0x30, (u_int8_t) 0x30, (u_int8_t) 0x30
, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x00
, (u_int8_t) 0x81, (u_int8_t) 0xcc, (u_int8_t) 0x00, (u_int8_t) 0x06
, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x22, (u_int8_t) 0x13
, (u_int8_t) 0x71, (u_int8_t) 0x74, (u_int8_t) 0x73, (u_int8_t) 0x69
, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x00
, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x02
, (u_int8_t) 0x61, (u_int8_t) 0x74, (u_int8_t) 0x00, (u_int8_t) 0x04
, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x00, (u_int8_t) 0x14
, (u_int8_t) 0x07, (u_int8_t) 0xe3, (u_int8_t) 0xba, (u_int8_t) 0x6f
, (u_int8_t) 0xb3, (u_int8_t) 0xa2, (u_int8_t) 0x47, (u_int8_t) 0x36
, (u_int8_t) 0xad, (u_int8_t) 0x1d, (u_int8_t) 0xaa, (u_int8_t) 0xb0
, (u_int8_t) 0xf6, (u_int8_t) 0x91, (u_int8_t) 0xba, (u_int8_t) 0x6e
, (u_int8_t) 0x13, (u_int8_t) 0x20, (u_int8_t) 0x03, (u_int8_t) 0xa9
, (u_int8_t) 0x6f, (u_int8_t) 0x10, (u_int8_t) 0x77, (u_int8_t) 0x11
, (u_int8_t) 0xe2, (u_int8_t) 0x84, (u_int8_t) 0xec, (u_int8_t) 0x9c
, (u_int8_t) 0x0e, (u_int8_t) 0x59, (u_int8_t) 0x1d, (u_int8_t) 0x46
, (u_int8_t) 0x73, (u_int8_t) 0xde, (u_int8_t) 0x24, (u_int8_t) 0x09
, (u_int8_t) 0x13, (u_int8_t) 0x73, (u_int8_t) 0x2e, (u_int8_t) 0xd3
, (u_int8_t) 0xca, (u_int8_t) 0xf0, (u_int8_t) 0xe6, (u_int8_t) 0xa0
, (u_int8_t) 0x57, (u_int8_t) 0x9d, (u_int8_t) 0x9d, (u_int8_t) 0xb0
, (u_int8_t) 0x58, (u_int8_t) 0xa8, (u_int8_t) 0x78, (u_int8_t) 0x31
, (u_int8_t) 0x39, (u_int8_t) 0x76, (u_int8_t) 0x24, (u_int8_t) 0x04
, (u_int8_t) 0x7f, (u_int8_t) 0x22, (u_int8_t) 0xc7, (u_int8_t) 0x35
, (u_int8_t) 0xbe, (u_int8_t) 0xe6, (u_int8_t) 0xeb, (u_int8_t) 0x77
, (u_int8_t) 0xa0, (u_int8_t) 0xc6, (u_int8_t) 0x4e, (u_int8_t) 0xe2
, (u_int8_t) 0x02, (u_int8_t) 0x6c, (u_int8_t) 0xde, (u_int8_t) 0x3a
, (u_int8_t) 0x24, (u_int8_t) 0xfa, (u_int8_t) 0x2a, (u_int8_t) 0x4b
, (u_int8_t) 0x41, (u_int8_t) 0x62, (u_int8_t) 0x6f, (u_int8_t) 0xa0
, (u_int8_t) 0x8b, (u_int8_t) 0x9c, (u_int8_t) 0x81, (u_int8_t) 0x1f
, (u_int8_t) 0x02, (u_int8_t) 0xa5, (u_int8_t) 0x5e, (u_int8_t) 0x2d
, (u_int8_t) 0xf8, (u_int8_t) 0x39, (u_int8_t) 0xfe, (u_int8_t) 0x3e
, (u_int8_t) 0x81, (u_int8_t) 0x4f, (u_int8_t) 0xab, (u_int8_t) 0xf7
, (u_int8_t) 0x9a, (u_int8_t) 0x36, (u_int8_t) 0xca, (u_int8_t) 0xb6
, (u_int8_t) 0x39, (u_int8_t) 0x51, (u_int8_t) 0x52, (u_int8_t) 0x12
, (u_int8_t) 0x95, (u_int8_t) 0x17, (u_int8_t) 0x97, (u_int8_t) 0xa6
, (u_int8_t) 0xa9, (u_int8_t) 0xeb, (u_int8_t) 0x39, (u_int8_t) 0x7d
, (u_int8_t) 0x84, (u_int8_t) 0xde, (u_int8_t) 0x5d, (u_int8_t) 0xda
, (u_int8_t) 0xc3, (u_int8_t) 0xa1, (u_int8_t) 0x8c, (u_int8_t) 0x02
, (u_int8_t) 0xaf, (u_int8_t) 0xe3, (u_int8_t) 0xa4, (u_int8_t) 0xa4
, (u_int8_t) 0x68, (u_int8_t) 0xa5, (u_int8_t) 0x01, (u_int8_t) 0x22
, (u_int8_t) 0xd0, (u_int8_t) 0x1f, (u_int8_t) 0xdd, (u_int8_t) 0xd2
, (u_int8_t) 0xda, (u_int8_t) 0x7d, (u_int8_t) 0xcf, (u_int8_t) 0xf3
, (u_int8_t) 0xb7, (u_int8_t) 0x3f, (u_int8_t) 0x6b, (u_int8_t) 0xa0
, (u_int8_t) 0x0c, (u_int8_t) 0x09, (u_int8_t) 0xfe, (u_int8_t) 0x6b
, (u_int8_t) 0x23, (u_int8_t) 0x98, (u_int8_t) 0xc6, (u_int8_t) 0x79
, (u_int8_t) 0x1d, (u_int8_t) 0x96, (u_int8_t) 0x66, (u_int8_t) 0xcf
, (u_int8_t) 0xff, (u_int8_t) 0x9a, (u_int8_t) 0x95, (u_int8_t) 0x89
, (u_int8_t) 0xe5, (u_int8_t) 0x96, (u_int8_t) 0xa2, (u_int8_t) 0x1d
, (u_int8_t) 0x78, (u_int8_t) 0x5a, (u_int8_t) 0x4a, (u_int8_t) 0x54
, (u_int8_t) 0x0d, (u_int8_t) 0x27, (u_int8_t) 0xf1, (u_int8_t) 0x65
, (u_int8_t) 0xac, (u_int8_t) 0xf2, (u_int8_t) 0x6d, (u_int8_t) 0xc0
, (u_int8_t) 0x53, (u_int8_t) 0x14, (u_int8_t) 0xa1, (u_int8_t) 0x4a
, (u_int8_t) 0x8b, (u_int8_t) 0xb5, (u_int8_t) 0x2a, (u_int8_t) 0x8a
, (u_int8_t) 0x96, (u_int8_t) 0xf2, (u_int8_t) 0xaf, (u_int8_t) 0xf8
, (u_int8_t) 0x2f, (u_int8_t) 0x8c, (u_int8_t) 0xae, (u_int8_t) 0x89
, (u_int8_t) 0x4f, (u_int8_t) 0xd3, (u_int8_t) 0x03, (u_int8_t) 0xe6
, (u_int8_t) 0x80, (u_int8_t) 0x15, (u_int8_t) 0x49, (u_int8_t) 0xec
, (u_int8_t) 0x28, (u_int8_t) 0xb1, (u_int8_t) 0xac, (u_int8_t) 0xf9
, (u_int8_t) 0x9b, (u_int8_t) 0x3f, (u_int8_t) 0x35, (u_int8_t) 0xf4
, (u_int8_t) 0x91, (u_int8_t) 0x86, (u_int8_t) 0xee, (u_int8_t) 0x6a
, (u_int8_t) 0x87, (u_int8_t) 0xa9, (u_int8_t) 0xeb, (u_int8_t) 0x60
, (u_int8_t) 0x32, (u_int8_t) 0xae, (u_int8_t) 0xd6, (u_int8_t) 0xde
, (u_int8_t) 0xb8, (u_int8_t) 0xb3, (u_int8_t) 0xd0, (u_int8_t) 0x1b
, (u_int8_t) 0x20, (u_int8_t) 0x40, (u_int8_t) 0xf2, (u_int8_t) 0x47
, (u_int8_t) 0x1c, (u_int8_t) 0xc0, (u_int8_t) 0xf8, (u_int8_t) 0xbd
, (u_int8_t) 0x85, (u_int8_t) 0xe8, (u_int8_t) 0xc2, (u_int8_t) 0xef
, (u_int8_t) 0x26, (u_int8_t) 0xcd, (u_int8_t) 0xde, (u_int8_t) 0xb4
, (u_int8_t) 0x4c, (u_int8_t) 0x72, (u_int8_t) 0x90, (u_int8_t) 0xdd
, (u_int8_t) 0xb8, (u_int8_t) 0x57, (u_int8_t) 0x8a, (u_int8_t) 0xcf
, (u_int8_t) 0xe0, (u_int8_t) 0x22, (u_int8_t) 0x4a, (u_int8_t) 0x5c
, (u_int8_t) 0xc4, (u_int8_t) 0x00, (u_int8_t) 0x62, (u_int8_t) 0xc5
, (u_int8_t) 0x77, (u_int8_t) 0xce, (u_int8_t) 0xb0, (u_int8_t) 0x2e
, (u_int8_t) 0x03, (u_int8_t) 0x34, (u_int8_t) 0xd9, (u_int8_t) 0x3f
, (u_int8_t) 0xbd, (u_int8_t) 0xc1, (u_int8_t) 0x09, (u_int8_t) 0x0d
, (u_int8_t) 0x44, (u_int8_t) 0x84, (u_int8_t) 0xcb, (u_int8_t) 0xb1
, (u_int8_t) 0x39, (u_int8_t) 0x45, (u_int8_t) 0x9b, (u_int8_t) 0x6f
, (u_int8_t) 0x0e, (u_int8_t) 0x8b, (u_int8_t) 0xce, (u_int8_t) 0x67
, (u_int8_t) 0x57, (u_int8_t) 0x5c, (u_int8_t) 0x0d, (u_int8_t) 0xc3
, (u_int8_t) 0x00, (u_int8_t) 0x85, (u_int8_t) 0x00, (u_int8_t) 0x5a
, (u_int8_t) 0x2a, (u_int8_t) 0x42, (u_int8_t) 0x43, (u_int8_t) 0x13
, (u_int8_t) 0xd7, (u_int8_t) 0xff, (u_int8_t) 0xa8, (u_int8_t) 0xd7
, (u_int8_t) 0x0b, (u_int8_t) 0xc1, (u_int8_t) 0x63, (u_int8_t) 0xf2
, (u_int8_t) 0x0d, (u_int8_t) 0x2b, (u_int8_t) 0x0b, (u_int8_t) 0x0f
, (u_int8_t) 0xe7, (u_int8_t) 0x79, (u_int8_t) 0x37, (u_int8_t) 0x89
, (u_int8_t) 0xaf, (u_int8_t) 0x68, (u_int8_t) 0xaa, (u_int8_t) 0x95
, (u_int8_t) 0xd9, (u_int8_t) 0xae, (u_int8_t) 0x59, (u_int8_t) 0x3e
, (u_int8_t) 0xe2, (u_int8_t) 0xe7, (u_int8_t) 0x33, (u_int8_t) 0xef
, (u_int8_t) 0x0a, (u_int8_t) 0x26, (u_int8_t) 0x69, (u_int8_t) 0xd5
, (u_int8_t) 0x0f, (u_int8_t) 0x55, (u_int8_t) 0x39, (u_int8_t) 0x12
, (u_int8_t) 0x61, (u_int8_t) 0x26, (u_int8_t) 0xbc, (u_int8_t) 0xd5
, (u_int8_t) 0x1c, (u_int8_t) 0x2f, (u_int8_t) 0xfd, (u_int8_t) 0x8e
, (u_int8_t) 0x55, (u_int8_t) 0xee, (u_int8_t) 0xb0, (u_int8_t) 0x4e
, (u_int8_t) 0x0d, (u_int8_t) 0x69, (u_int8_t) 0x43, (u_int8_t) 0x1a
, (u_int8_t) 0x5a, (u_int8_t) 0xad, (u_int8_t) 0x49, (u_int8_t) 0x92
, (u_int8_t) 0xdd, (u_int8_t) 0xa3, (u_int8_t) 0x0e, (u_int8_t) 0x20
, (u_int8_t) 0x68, (u_int8_t) 0xef, (u_int8_t) 0x0f, (u_int8_t) 0x55
, (u_int8_t) 0x93, (u_int8_t) 0xab, (u_int8_t) 0x1c, (u_int8_t) 0xe9
, (u_int8_t) 0x3a, (u_int8_t) 0xe9, (u_int8_t) 0x8b, (u_int8_t) 0xcb
, (u_int8_t) 0x0d, (u_int8_t) 0x6d, (u_int8_t) 0x43, (u_int8_t) 0x83
, (u_int8_t) 0x70, (u_int8_t) 0xb3, (u_int8_t) 0x0c, (u_int8_t) 0x17
, (u_int8_t) 0x6f, (u_int8_t) 0xcf, (u_int8_t) 0x8a, (u_int8_t) 0x67
, (u_int8_t) 0x04, (u_int8_t) 0x2f, (u_int8_t) 0x3c, (u_int8_t) 0x6d
, (u_int8_t) 0xc3, (u_int8_t) 0x3b, (u_int8_t) 0x4f, (u_int8_t) 0x46
, (u_int8_t) 0x50, (u_int8_t) 0x56, (u_int8_t) 0x37, (u_int8_t) 0x19
, (u_int8_t) 0x9d, (u_int8_t) 0x63, (u_int8_t) 0x35, (u_int8_t) 0xe6
, (u_int8_t) 0x9d, (u_int8_t) 0xc7, (u_int8_t) 0xac, (u_int8_t) 0xb3
, (u_int8_t) 0x12, (u_int8_t) 0x7d, (u_int8_t) 0xe0, (u_int8_t) 0xd4
, (u_int8_t) 0x97, (u_int8_t) 0xf3, (u_int8_t) 0x74, (u_int8_t) 0x7b
, (u_int8_t) 0xe2, (u_int8_t) 0xbc, (u_int8_t) 0xe5, (u_int8_t) 0xe8
, (u_int8_t) 0x81, (u_int8_t) 0x90, (u_int8_t) 0x52, (u_int8_t) 0x48
, (u_int8_t) 0x00, (u_int8_t) 0x67, (u_int8_t) 0x24, (u_int8_t) 0x15
, (u_int8_t) 0xdc, (u_int8_t) 0x4d, (u_int8_t) 0x43, (u_int8_t) 0x32
, (u_int8_t) 0x9b, (u_int8_t) 0x83, (u_int8_t) 0xd6, (u_int8_t) 0x3f
, (u_int8_t) 0x37, (u_int8_t) 0x9c, (u_int8_t) 0x33, (u_int8_t) 0x1c
, (u_int8_t) 0xbf, (u_int8_t) 0x3d, (u_int8_t) 0x24, (u_int8_t) 0xd9
, (u_int8_t) 0x3a, (u_int8_t) 0x2d, (u_int8_t) 0xa4, (u_int8_t) 0x0a
, (u_int8_t) 0xef, (u_int8_t) 0x47, (u_int8_t) 0x80, (u_int8_t) 0xfe
, (u_int8_t) 0x95, (u_int8_t) 0x5c, (u_int8_t) 0xfd, (u_int8_t) 0x6e
, (u_int8_t) 0x3e, (u_int8_t) 0xa0, (u_int8_t) 0x28, (u_int8_t) 0x8b
, (u_int8_t) 0x5f, (u_int8_t) 0xfc, (u_int8_t) 0x67, (u_int8_t) 0x0a
, (u_int8_t) 0x97, (u_int8_t) 0x67, (u_int8_t) 0xbd, (u_int8_t) 0x0f
, (u_int8_t) 0x43, (u_int8_t) 0xd0, (u_int8_t) 0x01, (u_int8_t) 0x55
, (u_int8_t) 0xca, (u_int8_t) 0xd3, (u_int8_t) 0x39, (u_int8_t) 0x74
, (u_int8_t) 0x2c, (u_int8_t) 0xae, (u_int8_t) 0x20, (u_int8_t) 0xa0
, (u_int8_t) 0x6b, (u_int8_t) 0x98, (u_int8_t) 0x7e, (u_int8_t) 0x4e
, (u_int8_t) 0x11, (u_int8_t) 0xb1, (u_int8_t) 0xa1, (u_int8_t) 0xb3
, (u_int8_t) 0x26, (u_int8_t) 0x26, (u_int8_t) 0xb7, (u_int8_t) 0x9e
, (u_int8_t) 0xd1, (u_int8_t) 0x67, (u_int8_t) 0x40, (u_int8_t) 0x07
, (u_int8_t) 0x80, (u_int8_t) 0x3c, (u_int8_t) 0x06, (u_int8_t) 0xd9
, (u_int8_t) 0x0b, (u_int8_t) 0x87, (u_int8_t) 0x7a, (u_int8_t) 0xad
, (u_int8_t) 0x2b, (u_int8_t) 0xf5, (u_int8_t) 0xf6, (u_int8_t) 0x26
, (u_int8_t) 0x74, (u_int8_t) 0xc1, (u_int8_t) 0x74, (u_int8_t) 0x74
, (u_int8_t) 0x75, (u_int8_t) 0x6b, (u_int8_t) 0xfa, (u_int8_t) 0x8c
, (u_int8_t) 0x47, (u_int8_t) 0xb1, (u_int8_t) 0x91, (u_int8_t) 0x1d
, (u_int8_t) 0x7a, (u_int8_t) 0x15, (u_int8_t) 0x3d, (u_int8_t) 0xac
, (u_int8_t) 0x87, (u_int8_t) 0x85, (u_int8_t) 0x84, (u_int8_t) 0x39
, (u_int8_t) 0x14, (u_int8_t) 0x69, (u_int8_t) 0x43, (u_int8_t) 0xb6
, (u_int8_t) 0x00, (u_int8_t) 0xaa, (u_int8_t) 0x50, (u_int8_t) 0xf3
, (u_int8_t) 0x37, (u_int8_t) 0x58, (u_int8_t) 0xb3, (u_int8_t) 0xb3
, (u_int8_t) 0x5a, (u_int8_t) 0x3f, (u_int8_t) 0x1b, (u_int8_t) 0x63
, (u_int8_t) 0x39, (u_int8_t) 0x66, (u_int8_t) 0x39, (u_int8_t) 0x0b
, (u_int8_t) 0xb0, (u_int8_t) 0xad, (u_int8_t) 0xdd, (u_int8_t) 0xdf
, (u_int8_t) 0x50, (u_int8_t) 0x7e, (u_int8_t) 0xe4, (u_int8_t) 0xe7
, (u_int8_t) 0xb8, (u_int8_t) 0xc0, (u_int8_t) 0xb9, (u_int8_t) 0x5d
, (u_int8_t) 0x1a, (u_int8_t) 0x47, (u_int8_t) 0xf9, (u_int8_t) 0x6c
, (u_int8_t) 0x03, (u_int8_t) 0x85, (u_int8_t) 0x52, (u_int8_t) 0xdd
, (u_int8_t) 0x02, (u_int8_t) 0xde, (u_int8_t) 0xc7, (u_int8_t) 0x64
, (u_int8_t) 0x2a, (u_int8_t) 0x1b, (u_int8_t) 0x9b, (u_int8_t) 0x39
, (u_int8_t) 0x33, (u_int8_t) 0xe7, (u_int8_t) 0xe1, (u_int8_t) 0x60
, (u_int8_t) 0x58, (u_int8_t) 0xf2, (u_int8_t) 0xd0, (u_int8_t) 0xbd
, (u_int8_t) 0x54, (u_int8_t) 0x9b, (u_int8_t) 0x29, (u_int8_t) 0x18
, (u_int8_t) 0x7c, (u_int8_t) 0x06, (u_int8_t) 0xff, (u_int8_t) 0x66
, (u_int8_t) 0xaa, (u_int8_t) 0xaf, (u_int8_t) 0xb1, (u_int8_t) 0x58
, (u_int8_t) 0x20, (u_int8_t) 0x79, (u_int8_t) 0xb8, (u_int8_t) 0x82
, (u_int8_t) 0x01, (u_int8_t) 0x7d, (u_int8_t) 0xb8, (u_int8_t) 0xe7
, (u_int8_t) 0x7e, (u_int8_t) 0xf3, (u_int8_t) 0x4e, (u_int8_t) 0x39
, (u_int8_t) 0x32, (u_int8_t) 0xde, (u_int8_t) 0x2d, (u_int8_t) 0x50
, (u_int8_t) 0xab, (u_int8_t) 0x30, (u_int8_t) 0x83, (u_int8_t) 0x50
, (u_int8_t) 0x57, (u_int8_t) 0xa3, (u_int8_t) 0x5a, (u_int8_t) 0xe7
, (u_int8_t) 0xcd, (u_int8_t) 0x80, (u_int8_t) 0xa1, (u_int8_t) 0xcf
, (u_int8_t) 0x6c, (u_int8_t) 0x37, (u_int8_t) 0x94, (u_int8_t) 0x84
, (u_int8_t) 0x10, (u_int8_t) 0xff, (u_int8_t) 0x84, (u_int8_t) 0x6f
, (u_int8_t) 0xd0, (u_int8_t) 0x11, (u_int8_t) 0x78, (u_int8_t) 0xf1
, (u_int8_t) 0xde, (u_int8_t) 0x08, (u_int8_t) 0x4c, (u_int8_t) 0x5a
, (u_int8_t) 0xc9, (u_int8_t) 0x2b, (u_int8_t) 0x2c, (u_int8_t) 0x62
, (u_int8_t) 0x53, (u_int8_t) 0x32, (u_int8_t) 0x04, (u_int8_t) 0x30
, (u_int8_t) 0x69, (u_int8_t) 0xbd, (u_int8_t) 0x09, (u_int8_t) 0xa1
, (u_int8_t) 0x42, (u_int8_t) 0x66, (u_int8_t) 0xea, (u_int8_t) 0x33
, (u_int8_t) 0xeb, (u_int8_t) 0x47, (u_int8_t) 0xdf, (u_int8_t) 0xd1
, (u_int8_t) 0x64, (u_int8_t) 0xfb, (u_int8_t) 0x88, (u_int8_t) 0x73
, (u_int8_t) 0x26, (u_int8_t) 0xc1, (u_int8_t) 0x50, (u_int8_t) 0x90
, (u_int8_t) 0xd2, (u_int8_t) 0x0c, (u_int8_t) 0xb8, (u_int8_t) 0x16
, (u_int8_t) 0x51, (u_int8_t) 0xae, (u_int8_t) 0xa4, (u_int8_t) 0xac
, (u_int8_t) 0x69, (u_int8_t) 0xc8, (u_int8_t) 0xad, (u_int8_t) 0xca
, (u_int8_t) 0x13, (u_int8_t) 0x5b, (u_int8_t) 0xd1, (u_int8_t) 0x84
, (u_int8_t) 0xd4, (u_int8_t) 0xbc, (u_int8_t) 0x1e, (u_int8_t) 0x94
, (u_int8_t) 0x0d, (u_int8_t) 0x9a, (u_int8_t) 0x58, (u_int8_t) 0xb3
, (u_int8_t) 0xa0, (u_int8_t) 0xaa, (u_int8_t) 0xcc, (u_int8_t) 0x9d
, (u_int8_t) 0x55, (u_int8_t) 0x38, (u_int8_t) 0xe7, (u_int8_t) 0x3d
, (u_int8_t) 0x69, (u_int8_t) 0xa4, (u_int8_t) 0x00, (u_int8_t) 0x2f
, (u_int8_t) 0x51, (u_int8_t) 0x04, (u_int8_t) 0xed, (u_int8_t) 0xef
, (u_int8_t) 0x46, (u_int8_t) 0x09, (u_int8_t) 0x36, (u_int8_t) 0xd4
, (u_int8_t) 0xb5, (u_int8_t) 0x95, (u_int8_t) 0x2e, (u_int8_t) 0x6a
, (u_int8_t) 0x67, (u_int8_t) 0x82, (u_int8_t) 0x6e, (u_int8_t) 0xcb
, (u_int8_t) 0x99, (u_int8_t) 0x51, (u_int8_t) 0x89, (u_int8_t) 0x9a
, (u_int8_t) 0xe2, (u_int8_t) 0x2b, (u_int8_t) 0x25, (u_int8_t) 0x42
, (u_int8_t) 0x98, (u_int8_t) 0xf0, (u_int8_t) 0xaa, (u_int8_t) 0x72
, (u_int8_t) 0x78, (u_int8_t) 0xc6, (u_int8_t) 0x1a, (u_int8_t) 0x48
, (u_int8_t) 0xb3, (u_int8_t) 0x51, (u_int8_t) 0x56, (u_int8_t) 0x3e
, (u_int8_t) 0x1e, (u_int8_t) 0xf7, (u_int8_t) 0x06, (u_int8_t) 0xad
, (u_int8_t) 0xfd, (u_int8_t) 0xa6, (u_int8_t) 0x02, (u_int8_t) 0x6f
, (u_int8_t) 0x2a, (u_int8_t) 0x26, (u_int8_t) 0x6f, (u_int8_t) 0xcb
, (u_int8_t) 0xa4, (u_int8_t) 0x19, (u_int8_t) 0x7e, (u_int8_t) 0x26
, (u_int8_t) 0xc8, (u_int8_t) 0x0b, (u_int8_t) 0x44, (u_int8_t) 0x7a
, (u_int8_t) 0xdc, (u_int8_t) 0x88, (u_int8_t) 0x03, (u_int8_t) 0xc5
, (u_int8_t) 0x0e, (u_int8_t) 0x5c, (u_int8_t) 0xf0, (u_int8_t) 0xaf
, (u_int8_t) 0xed, (u_int8_t) 0x02, (u_int8_t) 0x1a, (u_int8_t) 0x5b
, (u_int8_t) 0x7a, (u_int8_t) 0x89, (u_int8_t) 0x96, (u_int8_t) 0x59
, (u_int8_t) 0x0b, (u_int8_t) 0xee, (u_int8_t) 0xee, (u_int8_t) 0x69
, (u_int8_t) 0x8d, (u_int8_t) 0xcc, (u_int8_t) 0x3e, (u_int8_t) 0x20
, (u_int8_t) 0x51, (u_int8_t) 0x97, (u_int8_t) 0x17, (u_int8_t) 0xa3
, (u_int8_t) 0x88, (u_int8_t) 0x6e, (u_int8_t) 0xba, (u_int8_t) 0xcf
, (u_int8_t) 0x65, (u_int8_t) 0x83, (u_int8_t) 0x76, (u_int8_t) 0xb1
, (u_int8_t) 0xff, (u_int8_t) 0xc0, (u_int8_t) 0xb4, (u_int8_t) 0x3b
, (u_int8_t) 0x20, (u_int8_t) 0xe5, (u_int8_t) 0xfc, (u_int8_t) 0x62
, (u_int8_t) 0x96, (u_int8_t) 0x20, (u_int8_t) 0xad, (u_int8_t) 0xbe
, (u_int8_t) 0x09, (u_int8_t) 0xe2, (u_int8_t) 0xd0, (u_int8_t) 0x90
, (u_int8_t) 0xa5, (u_int8_t) 0x47, (u_int8_t) 0x00, (u_int8_t) 0x98
, (u_int8_t) 0xef, (u_int8_t) 0x2a, (u_int8_t) 0xc1, (u_int8_t) 0xca
, (u_int8_t) 0x65, (u_int8_t) 0xb9, (u_int8_t) 0xd9, (u_int8_t) 0x38
, (u_int8_t) 0x9a, (u_int8_t) 0x88, (u_int8_t) 0x09, (u_int8_t) 0x6d
, (u_int8_t) 0xd4, (u_int8_t) 0x64, (u_int8_t) 0xc3, (u_int8_t) 0x0b
, (u_int8_t) 0xf1, (u_int8_t) 0x6d, (u_int8_t) 0x52, (u_int8_t) 0x61
, (u_int8_t) 0xb1, (u_int8_t) 0xdc, (u_int8_t) 0xb4, (u_int8_t) 0x46
, (u_int8_t) 0x97, (u_int8_t) 0x80, (u_int8_t) 0xb6, (u_int8_t) 0xbf
, (u_int8_t) 0x15, (u_int8_t) 0x33, (u_int8_t) 0x26, (u_int8_t) 0x2c
, (u_int8_t) 0xd5, (u_int8_t) 0x1c, (u_int8_t) 0xc8, (u_int8_t) 0x21
, (u_int8_t) 0x0c, (u_int8_t) 0xbf, (u_int8_t) 0xb8, (u_int8_t) 0xdf
, (u_int8_t) 0xb3, (u_int8_t) 0xbd, (u_int8_t) 0xa9, (u_int8_t) 0x20
, (u_int8_t) 0xd6, (u_int8_t) 0x69, (u_int8_t) 0x07, (u_int8_t) 0x0f
, (u_int8_t) 0x3e, (u_int8_t) 0x06, (u_int8_t) 0x3d, (u_int8_t) 0x5c
, (u_int8_t) 0x43, (u_int8_t) 0xc5, (u_int8_t) 0xc4, (u_int8_t) 0xae
, (u_int8_t) 0x10, (u_int8_t) 0xe0, (u_int8_t) 0xf2, (u_int8_t) 0x71
, (u_int8_t) 0x26, (u_int8_t) 0x48, (u_int8_t) 0x47, (u_int8_t) 0x79
, (u_int8_t) 0x03, (u_int8_t) 0x2e, (u_int8_t) 0x87, (u_int8_t) 0xbd
, (u_int8_t) 0x93, (u_int8_t) 0x63, (u_int8_t) 0xa9, (u_int8_t) 0x9f
, (u_int8_t) 0x9c, (u_int8_t) 0xf6, (u_int8_t) 0x6a, (u_int8_t) 0xee
, (u_int8_t) 0x48, (u_int8_t) 0xa7, (u_int8_t) 0x31, (u_int8_t) 0x03
, (u_int8_t) 0xbf, (u_int8_t) 0x84, (u_int8_t) 0x9e, (u_int8_t) 0xf7
, (u_int8_t) 0x02, (u_int8_t) 0x06, (u_int8_t) 0x84, (u_int8_t) 0x0f
, (u_int8_t) 0x01, (u_int8_t) 0x87, (u_int8_t) 0x10, (u_int8_t) 0x55
, (u_int8_t) 0x07, (u_int8_t) 0xd0, (u_int8_t) 0xa1, (u_int8_t) 0x69
, (u_int8_t) 0xfd, (u_int8_t) 0x79, (u_int8_t) 0xe7, (u_int8_t) 0x8a
, (u_int8_t) 0x0c, (u_int8_t) 0xb3, (u_int8_t) 0x45, (u_int8_t) 0xb0
, (u_int8_t) 0x78, (u_int8_t) 0xa1, (u_int8_t) 0xea, (u_int8_t) 0x48
, (u_int8_t) 0x98, (u_int8_t) 0x7a, (u_int8_t) 0x9c, (u_int8_t) 0xc8
, (u_int8_t) 0x5f, (u_int8_t) 0xbd, (u_int8_t) 0x89, (u_int8_t) 0x1e
, (u_int8_t) 0x0a, (u_int8_t) 0xda, (u_int8_t) 0xf5, (u_int8_t) 0x28
, (u_int8_t) 0xff, (u_int8_t) 0x7e, (u_int8_t) 0x8c, (u_int8_t) 0x31
, (u_int8_t) 0x79, (u_int8_t) 0xae, (u_int8_t) 0x03, (u_int8_t) 0xb0
, (u_int8_t) 0x1d, (u_int8_t) 0x35, (u_int8_t) 0x58, (u_int8_t) 0xc6
, (u_int8_t) 0x74, (u_int8_t) 0x98, (u_int8_t) 0x40, (u_int8_t) 0x17
, (u_int8_t) 0x2f, (u_int8_t) 0xdb, (u_int8_t) 0x44, (u_int8_t) 0x25
, (u_int8_t) 0x5b, (u_int8_t) 0x6f, (u_int8_t) 0x74, (u_int8_t) 0x5d
, (u_int8_t) 0xc7, (u_int8_t) 0xd9, (u_int8_t) 0xaf, (u_int8_t) 0x5b
, (u_int8_t) 0x46, (u_int8_t) 0x12, (u_int8_t) 0x38, (u_int8_t) 0x8f
, (u_int8_t) 0x85, (u_int8_t) 0x1e, (u_int8_t) 0x88, (u_int8_t) 0xfa
, (u_int8_t) 0x83, (u_int8_t) 0xef, (u_int8_t) 0x20, (u_int8_t) 0x76
, (u_int8_t) 0x07, (u_int8_t) 0x81, (u_int8_t) 0x9e, (u_int8_t) 0x21
, (u_int8_t) 0xb1, (u_int8_t) 0x94, (u_int8_t) 0xab, (u_int8_t) 0xd0
, (u_int8_t) 0x49, (u_int8_t) 0x7c, (u_int8_t) 0x59, (u_int8_t) 0x54
, (u_int8_t) 0xa5, (u_int8_t) 0xda, (u_int8_t) 0xcc, (u_int8_t) 0x71
, (u_int8_t) 0x23, (u_int8_t) 0x00, (u_int8_t) 0xa3, (u_int8_t) 0x6a
, (u_int8_t) 0xe6, (u_int8_t) 0xf9, (u_int8_t) 0xd6, (u_int8_t) 0x7c
, (u_int8_t) 0xc0, (u_int8_t) 0xb9, (u_int8_t) 0x22, (u_int8_t) 0x44
, (u_int8_t) 0xf1, (u_int8_t) 0xf2, (u_int8_t) 0x95, (u_int8_t) 0x3a
, (u_int8_t) 0xd1, (u_int8_t) 0x49, (u_int8_t) 0xc6, (u_int8_t) 0x32
, (u_int8_t) 0xfd, (u_int8_t) 0xef, (u_int8_t) 0xa7, (u_int8_t) 0x50
, (u_int8_t) 0xfc, (u_int8_t) 0x42, (u_int8_t) 0x95, (u_int8_t) 0xd3
, (u_int8_t) 0xe5, (u_int8_t) 0x60, (u_int8_t) 0x17, (u_int8_t) 0x74
, (u_int8_t) 0x30, (u_int8_t) 0x50, (u_int8_t) 0x80, (u_int8_t) 0x59
, (u_int8_t) 0x55, (u_int8_t) 0x64, (u_int8_t) 0xf8, (u_int8_t) 0x98
, (u_int8_t) 0x61, (u_int8_t) 0xda, (u_int8_t) 0x56, (u_int8_t) 0xa6
, (u_int8_t) 0x86, (u_int8_t) 0x58, (u_int8_t) 0xe4, (u_int8_t) 0xfb
, (u_int8_t) 0x3d, (u_int8_t) 0x45, (u_int8_t) 0x42, (u_int8_t) 0x57
, (u_int8_t) 0xb2, (u_int8_t) 0xfa, (u_int8_t) 0x83, (u_int8_t) 0xe4
, (u_int8_t) 0x92, (u_int8_t) 0x45, (u_int8_t) 0x67, (u_int8_t) 0xa0
, (u_int8_t) 0x63, (u_int8_t) 0x3b, (u_int8_t) 0xe4, (u_int8_t) 0x58
, (u_int8_t) 0x16, (u_int8_t) 0xf1, (u_int8_t) 0x7c, (u_int8_t) 0x0f
, (u_int8_t) 0xf7, (u_int8_t) 0xce, (u_int8_t) 0x21, (u_int8_t) 0x81
, (u_int8_t) 0x8f, (u_int8_t) 0x3a, (u_int8_t) 0x38, (u_int8_t) 0x2e
, (u_int8_t) 0xe1, (u_int8_t) 0x52, (u_int8_t) 0x0d, (u_int8_t) 0xbc
, (u_int8_t) 0x58, (u_int8_t) 0xb0, (u_int8_t) 0xee, (u_int8_t) 0xf9
, (u_int8_t) 0x08, (u_int8_t) 0x94, (u_int8_t) 0x4c, (u_int8_t) 0x0d
, (u_int8_t) 0x86, (u_int8_t) 0xac, (u_int8_t) 0x00, (u_int8_t) 0xfe
, (u_int8_t) 0xee, (u_int8_t) 0x65, (u_int8_t) 0x3e, (u_int8_t) 0xe8
, (u_int8_t) 0xf7, (u_int8_t) 0x2e, (u_int8_t) 0x11, (u_int8_t) 0x4d
, (u_int8_t) 0x83, (u_int8_t) 0xe1, (u_int8_t) 0x7c, (u_int8_t) 0xd3
, (u_int8_t) 0x5b, (u_int8_t) 0x39, (u_int8_t) 0x25, (u_int8_t) 0x22
, (u_int8_t) 0xe9, (u_int8_t) 0xf5, (u_int8_t) 0xe1, (u_int8_t) 0x08
, (u_int8_t) 0x14, (u_int8_t) 0x64, (u_int8_t) 0xfd, (u_int8_t) 0xef
, (u_int8_t) 0x12, (u_int8_t) 0x61, (u_int8_t) 0xf6, (u_int8_t) 0x7b
, (u_int8_t) 0xfd, (u_int8_t) 0x07, (u_int8_t) 0x64, (u_int8_t) 0xa0
, (u_int8_t) 0xb4, (u_int8_t) 0xe6, (u_int8_t) 0xa1, (u_int8_t) 0x7d
, (u_int8_t) 0xcd, (u_int8_t) 0xd3, (u_int8_t) 0x6c, (u_int8_t) 0x50
, (u_int8_t) 0xff, (u_int8_t) 0x73, (u_int8_t) 0x71, (u_int8_t) 0x21
, (u_int8_t) 0x22, (u_int8_t) 0xb0, (u_int8_t) 0x19, (u_int8_t) 0x51
, (u_int8_t) 0x31, (u_int8_t) 0xad, (u_int8_t) 0xd9, (u_int8_t) 0xe5
, (u_int8_t) 0xb4, (u_int8_t) 0x6a, (u_int8_t) 0x3b, (u_int8_t) 0x3d
, (u_int8_t) 0xdf, (u_int8_t) 0xcf, (u_int8_t) 0x94, (u_int8_t) 0xe7
, (u_int8_t) 0x27, (u_int8_t) 0x49, (u_int8_t) 0xb2, (u_int8_t) 0xd0
, (u_int8_t) 0x06, (u_int8_t) 0x71, (u_int8_t) 0x7c, (u_int8_t) 0xee
, (u_int8_t) 0x1b, (u_int8_t) 0xec, (u_int8_t) 0x9a, (u_int8_t) 0xc9
, (u_int8_t) 0xec, (u_int8_t) 0x26, (u_int8_t) 0x6b, (u_int8_t) 0x37
, (u_int8_t) 0x6e, (u_int8_t) 0x26, (u_int8_t) 0x2c, (u_int8_t) 0xed
, (u_int8_t) 0x4d, (u_int8_t) 0x31, (u_int8_t) 0x67, (u_int8_t) 0x20
, (u_int8_t) 0xcd, (u_int8_t) 0x04, (u_int8_t) 0x9b, (u_int8_t) 0xbc
, (u_int8_t) 0x68, (u_int8_t) 0x13, (u_int8_t) 0x9b, (u_int8_t) 0x95
, (u_int8_t) 0x62, (u_int8_t) 0xb6, (u_int8_t) 0xf8, (u_int8_t) 0x22
, (u_int8_t) 0xe2, (u_int8_t) 0x50, (u_int8_t) 0xa7, (u_int8_t) 0x20
, (u_int8_t) 0xf3, (u_int8_t) 0x8f, (u_int8_t) 0x5d, (u_int8_t) 0x7e
, (u_int8_t) 0xbe, (u_int8_t) 0xdd, (u_int8_t) 0x32, (u_int8_t) 0x4a
, (u_int8_t) 0x5a, (u_int8_t) 0x2d, (u_int8_t) 0xdd, (u_int8_t) 0x13
, (u_int8_t) 0xce, (u_int8_t) 0x0f, (u_int8_t) 0xea, (u_int8_t) 0xcc
, (u_int8_t) 0xf8, (u_int8_t) 0xf4, (u_int8_t) 0xbc, (u_int8_t) 0xe0
, (u_int8_t) 0x53, (u_int8_t) 0x14, (u_int8_t) 0xda, (u_int8_t) 0xdc
, (u_int8_t) 0x40, (u_int8_t) 0x6b, (u_int8_t) 0xeb, (u_int8_t) 0x6b
, (u_int8_t) 0xf2, (u_int8_t) 0x3f, (u_int8_t) 0x7b, (u_int8_t) 0x96
, (u_int8_t) 0xc3, (u_int8_t) 0x2b, (u_int8_t) 0x11, (u_int8_t) 0xd9
, (u_int8_t) 0x7d, (u_int8_t) 0x8c, (u_int8_t) 0x88, (u_int8_t) 0x9b
, (u_int8_t) 0x0c, (u_int8_t) 0xd3, (u_int8_t) 0x16, (u_int8_t) 0x3e
, (u_int8_t) 0x9c, (u_int8_t) 0x80, (u_int8_t) 0xf7, (u_int8_t) 0xa5
, (u_int8_t) 0x09, (u_int8_t) 0xad, (u_int8_t) 0xc5, (u_int8_t) 0x88
, (u_int8_t) 0x11, (u_int8_t) 0x5e, (u_int8_t) 0x06, (u_int8_t) 0x6c
, (u_int8_t) 0x6f, (u_int8_t) 0xdd, (u_int8_t) 0xeb, (u_int8_t) 0xe3
, (u_int8_t) 0x4e, (u_int8_t) 0x8a, (u_int8_t) 0xe2, (u_int8_t) 0x42
, (u_int8_t) 0x14, (u_int8_t) 0xf0, (u_int8_t) 0x6d, (u_int8_t) 0xa3
, (u_int8_t) 0x95, (u_int8_t) 0x63, (u_int8_t) 0xd5, (u_int8_t) 0x2f
, (u_int8_t) 0x3e, (u_int8_t) 0x20, (u_int8_t) 0x1b, (u_int8_t) 0x00
, (u_int8_t) 0xff, (u_int8_t) 0x9b, (u_int8_t) 0x67, (u_int8_t) 0xe6
, (u_int8_t) 0x1b, (u_int8_t) 0x27, (u_int8_t) 0x0f, (u_int8_t) 0x9f
, (u_int8_t) 0x34, (u_int8_t) 0xcf, (u_int8_t) 0x56, (u_int8_t) 0xb3
, (u_int8_t) 0x92, (u_int8_t) 0x0a, (u_int8_t) 0x5e, (u_int8_t) 0xc9
, (u_int8_t) 0x71, (u_int8_t) 0xc7, (u_int8_t) 0x8d, (u_int8_t) 0x18
, (u_int8_t) 0x3b, (u_int8_t) 0x39, (u_int8_t) 0x66, (u_int8_t) 0xc1
, (u_int8_t) 0x5e, (u_int8_t) 0x10, (u_int8_t) 0x91, (u_int8_t) 0x7d
, (u_int8_t) 0xff, (u_int8_t) 0x28, (u_int8_t) 0xf1, (u_int8_t) 0x39
, (u_int8_t) 0xaf, (u_int8_t) 0x15, (u_int8_t) 0x1c, (u_int8_t) 0xed
, (u_int8_t) 0x8b, (u_int8_t) 0x8b, (u_int8_t) 0x27, (u_int8_t) 0x31
, (u_int8_t) 0xdf, (u_int8_t) 0x89, (u_int8_t) 0x5c, (u_int8_t) 0x3a
, (u_int8_t) 0x0d, (u_int8_t) 0xc8, (u_int8_t) 0x26, (u_int8_t) 0x21
, (u_int8_t) 0x2f, (u_int8_t) 0xd6, (u_int8_t) 0xfd, (u_int8_t) 0x0b
, (u_int8_t) 0x6a, (u_int8_t) 0x6e, (u_int8_t) 0x3a, (u_int8_t) 0x0f
, (u_int8_t) 0x8b, (u_int8_t) 0x90, (u_int8_t) 0xb3, (u_int8_t) 0x96
, (u_int8_t) 0x4a, (u_int8_t) 0xa7, (u_int8_t) 0xcd, (u_int8_t) 0x90
, (u_int8_t) 0xff, (u_int8_t) 0xcb, (u_int8_t) 0x0d, (u_int8_t) 0x44
, (u_int8_t) 0x92, (u_int8_t) 0xb9, (u_int8_t) 0xf2, (u_int8_t) 0xe0
, (u_int8_t) 0x96, (u_int8_t) 0x7e, (u_int8_t) 0x22, (u_int8_t) 0xa9
, (u_int8_t) 0x08, (u_int8_t) 0x6e, (u_int8_t) 0x0c, (u_int8_t) 0xc7
, (u_int8_t) 0x5c, (u_int8_t) 0x68, (u_int8_t) 0x73, (u_int8_t) 0xb5
, (u_int8_t) 0x98, (u_int8_t) 0x91, (u_int8_t) 0xe4, (u_int8_t) 0xc3
, (u_int8_t) 0x2b, (u_int8_t) 0x34, (u_int8_t) 0x54, (u_int8_t) 0x98
, (u_int8_t) 0xe2, (u_int8_t) 0xee, (u_int8_t) 0xf0, (u_int8_t) 0xa7
, (u_int8_t) 0xbf, (u_int8_t) 0x87, (u_int8_t) 0x1a, (u_int8_t) 0x86
, (u_int8_t) 0xd9, (u_int8_t) 0xbb, (u_int8_t) 0x5b, (u_int8_t) 0xbc
, (u_int8_t) 0x36, (u_int8_t) 0x9b, (u_int8_t) 0x8d, (u_int8_t) 0x40
, (u_int8_t) 0xe2, (u_int8_t) 0xc3, (u_int8_t) 0x6b, (u_int8_t) 0x4d
, (u_int8_t) 0x92, (u_int8_t) 0x17, (u_int8_t) 0x0b, (u_int8_t) 0x40
, (u_int8_t) 0x2b, (u_int8_t) 0x15, (u_int8_t) 0x25, (u_int8_t) 0xc1
, (u_int8_t) 0x9b, (u_int8_t) 0xef, (u_int8_t) 0x21, (u_int8_t) 0x73
, (u_int8_t) 0xb7, (u_int8_t) 0x8f, (u_int8_t) 0x61, (u_int8_t) 0x6e };

bool okPkt(const unsigned char* const pkt, const unsigned totPacketSize, const int n)
{
    const u_int8_t* const nextPkt = pkt + n;

    if ( nextPkt < fInBuf || nextPkt >= (fInBuf + maxRTCPPacketSize) )
    {
        printf("index ptr out of array bounds at incoming RTCP packet\n");
        return false;
    }
    else if ( nextPkt >= (fInBuf + totPacketSize) )
    {
        printf("index ptr out of packet bounds at incoming RTCP packet\n");
        return false;
    }
    return true;
}

#define ADVANCE(n) if (! okPkt(pkt, totPacketSize, n)) break; pkt += (n); packetSize -= (n);

void onReceive(int typeOfPacket, int totPacketSize, u_int32_t ssrc) { printf("onReceive is never called"); }

void noteArrivingRR(struct sockaddr_in const& fromAddressAndPort, int tcpSocketNum, unsigned char tcpStreamChannelId) { printf("noteArrivingRR is never called"); }

void processIncomingReport(unsigned packetSize, struct sockaddr_in const& fromAddressAndPort, int tcpSocketNum, unsigned char tcpStreamChannelId)
{
    do {
        Boolean callByeHandler = False;
        unsigned char* pkt = fInBuf;

        static unsigned const IP_UDP_HDR_SIZE = 28;
        int totPacketSize = IP_UDP_HDR_SIZE + packetSize;

        // Check the RTCP packet for validity:
        // It must at least contain a header (4 bytes), and this header
        // must be version=2, with no padding bit, and a payload type of
        // SR (200), RR (201), or APP (204):
        if (packetSize < 4) break;

        u_int8_t a[4] = { 0x38, 0x1a, 0x25, 0xae };
        unsigned test = ntohl(*(u_int32_t*)a); //941237678

        unsigned rtcpHdr = ntohl(*(u_int32_t*)pkt); //941237678
        if ((rtcpHdr & 0xE0FE0000) != (0x80000000 | (RTCP_PT_SR<<16)) &&
                (rtcpHdr & 0xE0FF0000) != (0x80000000 | (RTCP_PT_APP<<16))) {
            break;
        }

        // Process each of the individual RTCP 'subpackets' in (what may be)
        // a compound RTCP packet.
        int typeOfPacket = PACKET_UNKNOWN_TYPE;
        unsigned reportSenderSSRC = 0;
        Boolean packetOK = False;
        while (1) {
            u_int8_t rc = (rtcpHdr>>24)&0x1F;
            u_int8_t pt = (rtcpHdr>>16)&0xFF;
            unsigned length = 4*(rtcpHdr&0xFFFF); // doesn't count hdr
            ADVANCE(4); // skip over the header
            if (length > packetSize) break;

            // Assume that each RTCP subpacket begins with a 4-byte SSRC:
            if (length < 4) break; length -= 4;
            reportSenderSSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4);

            if (reportSenderSSRC == 0x00000001 && pt == RTCP_PT_RR) {
                // Chrome (and Opera) WebRTC receivers have a bug that causes them to always send
                // SSRC 1 in their "RR"s.  To work around this (to help us distinguish between different
                // receivers), we use a fake SSRC in this case consisting of the IP address, XORed with
                // the port number:
                reportSenderSSRC = fromAddressAndPort.sin_addr.s_addr^fromAddressAndPort.sin_port;
            }

            Boolean subPacketOK = False;
            switch (pt) {
            case RTCP_PT_SR: {
                if (length < 20) break; length -= 20;

                // Extract the NTP timestamp, and note this:
                unsigned NTPmsw = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                unsigned NTPlsw = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                unsigned rtpTimestamp = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                if (fSource != NULL) {
                    RTPReceptionStatsDB& receptionStats
                            = fSource->receptionStatsDB();
                    receptionStats.noteIncomingSR(reportSenderSSRC,
                                                  NTPmsw, NTPlsw, rtpTimestamp);
                }
                ADVANCE(8); // skip over packet count, octet count

                // If a 'SR handler' was set, call it now:
                if (fSRHandlerTask != NULL) (*fSRHandlerTask)(fSRHandlerClientData);

                // The rest of the SR is handled like a RR (so, no "break;" here)
            }
            case RTCP_PT_RR: {
                unsigned reportBlocksSize = rc*(6*4);
                if (length < reportBlocksSize) break;
                length -= reportBlocksSize;

                if (fSink != NULL) {
                    // Use this information to update stats about our transmissions:
                    RTPTransmissionStatsDB& transmissionStats = fSink->transmissionStatsDB();
                    for (unsigned i = 0; i < rc; ++i) {
                        unsigned senderSSRC = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                        // We care only about reports about our own transmission, not others'
                        if (senderSSRC == fSink->SSRC()) {
                            unsigned lossStats = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                            unsigned highestReceived = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                            unsigned jitter = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                            unsigned timeLastSR = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                            unsigned timeSinceLastSR = ntohl(*(u_int32_t*)pkt); ADVANCE(4);
                            transmissionStats.noteIncomingRR(reportSenderSSRC, fromAddressAndPort,
                                                             lossStats,
                                                             highestReceived, jitter,
                                                             timeLastSR, timeSinceLastSR);
                        } else {
                            ADVANCE(4*5);
                        }
                    }
                } else {
                    ADVANCE(reportBlocksSize);
                }

                if (pt == RTCP_PT_RR) { // i.e., we didn't fall through from 'SR'
                    noteArrivingRR(fromAddressAndPort, tcpSocketNum, tcpStreamChannelId);
                }

                subPacketOK = True;
                typeOfPacket = PACKET_RTCP_REPORT;
                break;
            }
            case RTCP_PT_BYE: {
                // If a 'BYE handler' was set, arrange for it to be called at the end of this routine.
                // (Note: We don't call it immediately, in case it happens to cause "this" to be deleted.)
                if (fByeHandlerTask != NULL
                        && (!fByeHandleActiveParticipantsOnly
                            || (fSource != NULL
                                && fSource->receptionStatsDB().lookup(reportSenderSSRC) != NULL)
                            || (fSink != NULL
                                && fSink->transmissionStatsDB().lookup(reportSenderSSRC) != NULL))) {
                    callByeHandler = True;
                }

                // We should really check for & handle >1 SSRCs being present #####

                subPacketOK = True;
                typeOfPacket = PACKET_BYE;
                break;
            }
            case RTCP_PT_APP: {
                u_int8_t& subtype = rc; // In "APP" packets, the "rc" field gets used as "subtype"
                if (length < 4) {
                    break;
                }
                u_int32_t nameBytes = (pkt[0]<<24)|(pkt[1]<<16)|(pkt[2]<<8)|(pkt[3]);
                ADVANCE(4); // skip over "name", to the 'application-dependent data'

                // If an 'APP' packet handler was set, call it now:
                if (fAppHandlerTask != NULL) {
                    (*fAppHandlerTask)(fAppHandlerClientData, subtype, nameBytes, pkt, length);
                }
                subPacketOK = True;
                typeOfPacket = PACKET_RTCP_APP;
                break;
            }
                // Other RTCP packet types that we don't yet handle:
            case RTCP_PT_SDES: {
                subPacketOK = True;
                break;
            }
            case RTCP_PT_RTPFB: {
                subPacketOK = True;
                break;
            }
            case RTCP_PT_PSFB: {
                subPacketOK = True;
                break;
            }
            case RTCP_PT_XR: {
                subPacketOK = True;
                break;
            }
            case RTCP_PT_AVB: {
                subPacketOK = True;
                break;
            }
            case RTCP_PT_RSI: {
                subPacketOK = True;
                break;
            }
            case RTCP_PT_TOKEN: {
                subPacketOK = True;
                break;
            }
            case RTCP_PT_IDMS: {
                subPacketOK = True;
                break;
            }
            default: {
                subPacketOK = True;
                break;
            }
            }
            if (!subPacketOK) break;

            // need to check for (& handle) SSRC collision! #####

            // Skip over any remaining bytes in this subpacket:
            ADVANCE(length);

            // Check whether another RTCP 'subpacket' follows:
            if (packetSize == 0) {
                packetOK = True;
                break;
            } else if (packetSize < 4) {
                break;
            }
            rtcpHdr = ntohl(*(u_int32_t*)pkt);
            if ((rtcpHdr & 0xC0000000) != 0x80000000) {
                break;
            }
        }

        if (!packetOK) {
            break;
        } else {
        }

        onReceive(typeOfPacket, totPacketSize, reportSenderSSRC);

        // Finally, if we need to call a "BYE" handler, do so now (in case it causes "this" to get deleted):
        if (callByeHandler && fByeHandlerTask != NULL/*sanity check*/) {
            TaskFunc* byeHandler = fByeHandlerTask;
            fByeHandlerTask = NULL; // because we call the handler only once, by default
            (*byeHandler)(fByeHandlerClientData);
        }
    } while (0);
}

int main(int argc, char *argv[])
{
    struct sockaddr_in fromAddress;

    in_addr a;
    a.s_addr = 3322587328;

    fromAddress.sin_addr = a;
    fromAddress.sin_family = 2;
    fromAddress.sin_port = 15131;

    for (int i = 0; i < 8; ++i)
        fromAddress.sin_zero[i] = 0;

    processIncomingReport(84, fromAddress, -1, (unsigned char)183);

    return 0;
}


More information about the live-devel mailing list