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