common_header.cc (3165B)
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 <cstddef> 14 #include <cstdint> 15 16 #include "modules/rtp_rtcp/source/byte_io.h" 17 #include "rtc_base/logging.h" 18 19 namespace webrtc { 20 namespace rtcp { 21 // 0 1 1 2 3 22 // 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 23 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 24 // 0 |V=2|P| C/F | 25 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 26 // 1 | Packet Type | 27 // ----------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 28 // 2 | length | 29 // --------------------------------+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 30 // 31 // Common header for all RTCP packets, 4 octets. 32 bool CommonHeader::Parse(const uint8_t* buffer, size_t size_bytes) { 33 const uint8_t kVersion = 2; 34 35 if (size_bytes < kHeaderSizeBytes) { 36 RTC_LOG(LS_WARNING) 37 << "Too little data (" << size_bytes << " byte" 38 << (size_bytes != 1 ? "s" : "") 39 << ") remaining in buffer to parse RTCP header (4 bytes)."; 40 return false; 41 } 42 43 uint8_t version = buffer[0] >> 6; 44 if (version != kVersion) { 45 RTC_LOG(LS_WARNING) << "Invalid RTCP header: Version must be " 46 << static_cast<int>(kVersion) << " but was " 47 << static_cast<int>(version); 48 return false; 49 } 50 51 bool has_padding = (buffer[0] & 0x20) != 0; 52 count_or_format_ = buffer[0] & 0x1F; 53 packet_type_ = buffer[1]; 54 payload_size_ = ByteReader<uint16_t>::ReadBigEndian(&buffer[2]) * 4; 55 payload_ = buffer + kHeaderSizeBytes; 56 padding_size_ = 0; 57 58 if (size_bytes < kHeaderSizeBytes + payload_size_) { 59 RTC_LOG(LS_WARNING) << "Buffer too small (" << size_bytes 60 << " bytes) to fit an RtcpPacket with a header and " 61 << payload_size_ << " bytes."; 62 return false; 63 } 64 65 if (has_padding) { 66 if (payload_size_ == 0) { 67 RTC_LOG(LS_WARNING) 68 << "Invalid RTCP header: Padding bit set but 0 payload " 69 "size specified."; 70 return false; 71 } 72 73 padding_size_ = payload_[payload_size_ - 1]; 74 if (padding_size_ == 0) { 75 RTC_LOG(LS_WARNING) 76 << "Invalid RTCP header: Padding bit set but 0 padding " 77 "size specified."; 78 return false; 79 } 80 if (padding_size_ > payload_size_) { 81 RTC_LOG(LS_WARNING) << "Invalid RTCP header: Too many padding bytes (" 82 << padding_size_ << ") for a packet payload size of " 83 << payload_size_ << " bytes."; 84 return false; 85 } 86 payload_size_ -= padding_size_; 87 } 88 return true; 89 } 90 } // namespace rtcp 91 } // namespace webrtc