/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 |