1 /* 2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "modules/rtp_rtcp/source/rtcp_packet/common_header.h" 12 13 #include "modules/rtp_rtcp/source/byte_io.h" 14 #include "rtc_base/logging.h" 15 16 namespace webrtc { 17 namespace rtcp { 18 constexpr size_t CommonHeader::kHeaderSizeBytes; 19 // 0 1 1 2 3 20 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 21 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 22 // 0 |V=2|P| C/F | 23 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 24 // 1 | Packet Type | 25 // ----------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 26 // 2 | length | 27 // --------------------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 28 // 29 // Common header for all RTCP packets, 4 octets. Parse(const uint8_t * buffer,size_t size_bytes)30bool CommonHeader::Parse(const uint8_t* buffer, size_t size_bytes) { 31 const uint8_t kVersion = 2; 32 33 if (size_bytes < kHeaderSizeBytes) { 34 RTC_LOG(LS_WARNING) 35 << "Too little data (" << size_bytes << " byte" 36 << (size_bytes != 1 ? "s" : "") 37 << ") remaining in buffer to parse RTCP header (4 bytes)."; 38 return false; 39 } 40 41 uint8_t version = buffer[0] >> 6; 42 if (version != kVersion) { 43 RTC_LOG(LS_WARNING) << "Invalid RTCP header: Version must be " 44 << static_cast<int>(kVersion) << " but was " 45 << static_cast<int>(version); 46 return false; 47 } 48 49 bool has_padding = (buffer[0] & 0x20) != 0; 50 count_or_format_ = buffer[0] & 0x1F; 51 packet_type_ = buffer[1]; 52 payload_size_ = ByteReader<uint16_t>::ReadBigEndian(&buffer[2]) * 4; 53 payload_ = buffer + kHeaderSizeBytes; 54 padding_size_ = 0; 55 56 if (size_bytes < kHeaderSizeBytes + payload_size_) { 57 RTC_LOG(LS_WARNING) << "Buffer too small (" << size_bytes 58 << " bytes) to fit an RtcpPacket with a header and " 59 << payload_size_ << " bytes."; 60 return false; 61 } 62 63 if (has_padding) { 64 if (payload_size_ == 0) { 65 RTC_LOG(LS_WARNING) 66 << "Invalid RTCP header: Padding bit set but 0 payload " 67 "size specified."; 68 return false; 69 } 70 71 padding_size_ = payload_[payload_size_ - 1]; 72 if (padding_size_ == 0) { 73 RTC_LOG(LS_WARNING) 74 << "Invalid RTCP header: Padding bit set but 0 padding " 75 "size specified."; 76 return false; 77 } 78 if (padding_size_ > payload_size_) { 79 RTC_LOG(LS_WARNING) << "Invalid RTCP header: Too many padding bytes (" 80 << padding_size_ << ") for a packet payload size of " 81 << payload_size_ << " bytes."; 82 return false; 83 } 84 payload_size_ -= padding_size_; 85 } 86 return true; 87 } 88 } // namespace rtcp 89 } // namespace webrtc 90