Coverage Report

Created: 2025-10-10 07:28

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/PcapPlusPlus/Packet++/src/SdpLayer.cpp
Line
Count
Source
1
3.14k
#define LOG_MODULE PacketLogModuleSdpLayer
2
3
#include "SdpLayer.h"
4
#include "Logger.h"
5
#include <sstream>
6
7
namespace pcpp
8
{
9
10
  std::vector<std::string> splitByWhiteSpaces(const std::string& str)
11
5.29k
  {
12
5.29k
    std::string buf;
13
5.29k
    std::stringstream stream(str);
14
5.29k
    std::vector<std::string> result;
15
26.1k
    while (stream >> buf)
16
20.8k
      result.push_back(buf);
17
18
5.29k
    return result;
19
5.29k
  }
20
21
  SdpLayer::SdpLayer(uint8_t* data, size_t dataLen, Layer* prevLayer, Packet* packet)
22
30.5k
      : TextBasedProtocolMessage(data, dataLen, prevLayer, packet, SDP)
23
30.5k
  {
24
30.5k
    m_FieldsOffset = 0;
25
30.5k
    parseFields();
26
30.5k
  }
27
28
  SdpLayer::SdpLayer()
29
0
  {
30
0
    m_Protocol = SDP;
31
0
    m_FieldsOffset = 0;
32
0
  }
33
34
  SdpLayer::SdpLayer(const std::string& username, long sessionID, long sessionVersion, IPv4Address ipAddress,
35
                     const std::string& sessionName, long startTime, long stopTime)
36
0
  {
37
0
    m_Protocol = SDP;
38
0
    m_FieldsOffset = 0;
39
40
    // must initialize m_Data otherwise addField() will fail while trying to extend the layer
41
    // initializing in length of 1 but keeping m_DataLen with value of 0.
42
    // when extending the field m_Data is purged so there isn't a memory leak here
43
0
    m_Data = new uint8_t[1];
44
0
    m_DataLen = 0;
45
46
0
    addField(PCPP_SDP_PROTOCOL_VERSION_FIELD, "0");
47
48
0
    std::stringstream sessionIDStream;
49
0
    sessionIDStream << sessionID;
50
0
    std::stringstream sessionVersionStream;
51
0
    sessionVersionStream << sessionVersion;
52
0
    std::string networkInfo = "IN IP4 " + ipAddress.toString();
53
0
    std::string originatorFieldValue =
54
0
        username + " " + sessionIDStream.str() + " " + sessionVersionStream.str() + " " + networkInfo;
55
0
    addField(PCPP_SDP_ORIGINATOR_FIELD, originatorFieldValue);
56
57
0
    addField(PCPP_SDP_SESSION_NAME_FIELD, sessionName);
58
59
0
    addField(PCPP_SDP_CONNECTION_INFO_FIELD, networkInfo);
60
61
0
    std::stringstream startTimeStream;
62
0
    startTimeStream << startTime;
63
0
    std::stringstream stopTimeStream;
64
0
    stopTimeStream << stopTime;
65
0
    addField(PCPP_SDP_TIME_FIELD, startTimeStream.str() + " " + stopTimeStream.str());
66
0
  }
67
68
  std::string SdpLayer::toString() const
69
5.74k
  {
70
5.74k
    return "SDP Layer";
71
5.74k
  }
72
73
  IPv4Address SdpLayer::getOwnerIPv4Address() const
74
2.87k
  {
75
2.87k
    HeaderField* originator = getFieldByName(PCPP_SDP_ORIGINATOR_FIELD);
76
2.87k
    if (originator == nullptr)
77
682
      return IPv4Address::Zero;
78
79
2.18k
    std::vector<std::string> tokens = splitByWhiteSpaces(originator->getFieldValue());
80
2.18k
    if (tokens.size() < 6)
81
1.38k
      return IPv4Address::Zero;
82
83
808
    if (tokens[3] != "IN" || tokens[4] != "IP4")
84
477
      return IPv4Address::Zero;
85
86
331
    try
87
331
    {
88
331
      return IPv4Address(tokens[5]);
89
331
    }
90
331
    catch (const std::exception&)
91
331
    {
92
191
      return IPv4Address::Zero;
93
191
    }
94
331
  }
95
96
  uint16_t SdpLayer::getMediaPort(const std::string& mediaType) const
97
2.87k
  {
98
2.87k
    int mediaFieldIndex = 0;
99
2.87k
    HeaderField* mediaDesc = getFieldByName(PCPP_SDP_MEDIA_NAME_FIELD, mediaFieldIndex);
100
101
4.74k
    while (mediaDesc != nullptr)
102
3.10k
    {
103
3.10k
      std::vector<std::string> tokens = splitByWhiteSpaces(mediaDesc->getFieldValue());
104
105
3.10k
      if (tokens.size() >= 2 && tokens[0] == mediaType)
106
1.22k
        return atoi(tokens[1].c_str());
107
108
1.87k
      mediaFieldIndex++;
109
1.87k
      mediaDesc = getFieldByName(PCPP_SDP_MEDIA_NAME_FIELD, mediaFieldIndex);
110
1.87k
    }
111
112
1.64k
    return 0;
113
2.87k
  }
114
115
  bool SdpLayer::addMediaDescription(const std::string& mediaType, uint16_t mediaPort,
116
                                     const std::string& mediaProtocol, const std::string& mediaFormat,
117
                                     const std::vector<std::string>& mediaAttributes)
118
2.87k
  {
119
2.87k
    std::stringstream portStream;
120
2.87k
    portStream << mediaPort;
121
122
2.87k
    std::string mediaFieldValue = mediaType + " " + portStream.str() + " " + mediaProtocol + " " + mediaFormat;
123
2.87k
    if (addField(PCPP_SDP_MEDIA_NAME_FIELD, mediaFieldValue) == nullptr)
124
1.57k
    {
125
1.57k
      PCPP_LOG_ERROR("Failed to add media description field");
126
1.57k
      return false;
127
1.57k
    }
128
129
1.29k
    for (const auto& iter : mediaAttributes)
130
1.29k
    {
131
1.29k
      if (addField(PCPP_SDP_MEDIA_ATTRIBUTE_FIELD, iter) == nullptr)
132
0
      {
133
0
        PCPP_LOG_ERROR("Failed to add media attribute '" << iter << "'");
134
0
        return false;
135
0
      }
136
1.29k
    }
137
138
1.29k
    return true;
139
1.29k
  }
140
141
}  // namespace pcpp