int32 IncomingRTPPkt::unprotect(CryptoContext* pcc) { if (pcc == NULL) { return true; } /* * This is the setting of the packet data when we come to this * point: * * total: complete length of received data * buffer: points to data as received from network * hdrSize: length of header including header extension * payloadSize: length of data excluding hdrSize and padding * * Because this is an SRTP packet we need to adjust some values here. * The SRTP MKI and authentication data is always at the end of a * packet. Thus compute the position of this data. */ uint32 srtpDataIndex = total - (pcc->getTagLength() + pcc->getMkiLength()); // now adjust total because some RTP functions rely on the fact that // total is the full length of data without SRTP data. total -= pcc->getTagLength() + pcc->getMkiLength(); // recompute payloadSize by subtracting SRTP data payloadSize -= pcc->getTagLength() + pcc->getMkiLength(); // unused?? // const uint8* mki = getRawPacket() + srtpDataIndex; const uint8* tag = getRawPacket() + srtpDataIndex + pcc->getMkiLength(); /* Replay control */ if (!pcc->checkReplay(cachedSeqNum)) { return -2; } /* Guess the index */ uint64 guessedIndex = pcc->guessIndex(cachedSeqNum); uint32 guessedRoc = (uint32)(guessedIndex >> 16); uint8* mac = new uint8[pcc->getTagLength()]; pcc->srtpAuthenticate(this, guessedRoc, mac); if (memcmp(tag, mac, pcc->getTagLength()) != 0) { delete[] mac; return -1; } delete[] mac; /* Decrypt the content */ pcc->srtpEncrypt( this, guessedIndex, cachedSSRC ); /* Update the Crypto-context */ pcc->update(cachedSeqNum); return 1; }
IPv4Datagram::IPv4Datagram ( DataLinkLayerPacket& packet ) : NetworkLayerPacket ( packet ) { u_char* temp = getRawPacket()->getPacket().get() + getPacketOffset(); _version = ( ( *temp ) & IPV4_VERSION_AND_VALUE ) >> IPV4_VERSION_SHIFT; _headerLength = ( ( *temp ) & IPV4_HEADERLENGTH_AND_VALUE ); _typeOfService = ( temp + IPV4_TYPEOFSERVICE_OFFSET ); _totalLength = ( two_byte* ) ( temp + IPV4_HEADERLENGTH_OFFSET ); _identification = ( two_byte* ) ( temp + IPV4_IDENTIFICATION_OFFSET ); _flags = ( ( * ( temp + IPV4_FLAGS_FRAG_OFFSET ) ) & IPV4_FLAGS_AND_VALUE ) >> IPV4_FLAGS_SHIFT; two_byte* temp_two = ( two_byte* ) ( temp + IPV4_FLAGS_FRAG_OFFSET ); _fragmentationOffset = *temp_two; _fragmentationOffset.U_main.S_uchar.high &= IPV4_OFFSET_AND_VALUE; temp_two = 0; _timeToLive = temp + IPV4_TIMETOLIVE_OFFSET; _protocol = temp + IPV4_PROTOCOL_OFFSET; _checksum = ( two_byte* ) ( temp + IPV4_CHECKSUM_OFFSET ); _sourceIP = ( ip_t* ) ( temp + IPV4_SOURCEADDRESS_OFFSET ); _destinationIP = ( ip_t* ) ( temp + IPV4_DESTINATIONADDRESS_OFFSET ); _payloadOffset = ( ( int ) _headerLength ) * 4; if ( _payloadOffset > IPV4_MINIMUM_LENGTH ) { _options = temp + IPV4_MINIMUM_LENGTH; } else { _options = 0; } };
void OutgoingRTPPkt::protect(uint32 ssrc, CryptoContext* pcc) { /* Encrypt the packet */ uint64 index = ((uint64)pcc->getRoc() << 16) | (uint64)getSeqNum(); pcc->srtpEncrypt(this, index, ssrc); // NO MKI support yet - here we assume MKI is zero. To build in MKI // take MKI length into account when storing the authentication tag. /* Compute MAC */ pcc->srtpAuthenticate(this, pcc->getRoc(), const_cast<uint8*>(getRawPacket()+srtpDataOffset) ); /* Update the ROC if necessary */ if (getSeqNum() == 0xFFFF ) { pcc->setRoc(pcc->getRoc() + 1); } }