Skip to content

Commit 175d94d

Browse files
authored
Merge pull request #97 from CESNET/ssdp_fix_payload_handling
SSDP Plugin: Fixed payload handling.
2 parents 6d9b63e + 17d3a18 commit 175d94d

File tree

2 files changed

+41
-31
lines changed

2 files changed

+41
-31
lines changed

process/ssdp.cpp

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -142,21 +142,26 @@ void SSDPPlugin::finish(bool print_stats)
142142
* \param [in] ip_version IP version of the Location url being parsed.
143143
* \return Parsed port number on success, 0 otherwise.
144144
*/
145-
uint16_t SSDPPlugin::parse_loc_port(char *data, uint8_t ip_version)
145+
uint16_t SSDPPlugin::parse_loc_port(const char *data, unsigned data_len, uint8_t ip_version)
146146
{
147147
uint16_t port;
148148
char *end_ptr = nullptr;
149+
const void *data_mem = static_cast<const void *>(data);
149150

150151
if (ip_version == IP::v6) {
151-
data = strchr(data, ']');
152+
data_mem = memchr(data_mem, ']', data_len);
152153
} else {
153-
data = strchr(data, '.');
154+
data_mem = memchr(data_mem, '.', data_len);
154155
}
155-
data = strchr(data, ':');
156+
if (data_mem == nullptr) {
157+
return 0;
158+
}
159+
data_mem = memchr(data_mem, ':', data_len);
156160

157-
if (data == nullptr) {
161+
if (data_mem == nullptr) {
158162
return 0;
159163
}
164+
data = static_cast<const char *>(data_mem);
160165
data++;
161166

162167
port = strtol(data, &end_ptr, 0);
@@ -174,7 +179,7 @@ uint16_t SSDPPlugin::parse_loc_port(char *data, uint8_t ip_version)
174179
* \param [in] len Lenght of the desired header.
175180
* \return True if the header is found, otherwise false.
176181
*/
177-
bool SSDPPlugin::get_header_val(char **data, const char *header, const int len)
182+
bool SSDPPlugin::get_header_val(const char **data, const char *header, const int len)
178183
{
179184
if (strncasecmp(*data, header, len) == 0 && (*data)[len] == ':') {
180185
(*data) += len + 1;
@@ -193,34 +198,33 @@ bool SSDPPlugin::get_header_val(char **data, const char *header, const int len)
193198
* \param [in] payload_len Lenght of payload data
194199
* \param [in] conf Struct containing parser configuration.
195200
*/
196-
void SSDPPlugin::parse_headers(char *data, size_t payload_len, header_parser_conf conf)
201+
void SSDPPlugin::parse_headers(const uint8_t *data, size_t payload_len, header_parser_conf conf)
197202
{
198-
char *ptr = data;
199-
char *old_ptr = ptr;
203+
const char *ptr = (const char *)(data);
204+
const char *old_ptr = ptr;
200205
size_t len = 0;
201206

202207
while (*ptr != '\0' && len <= payload_len) {
203208
if (*ptr == '\n' && *(ptr - 1) == '\r') {
204-
*(ptr - 1) = '\0';
205209
for (unsigned j = 0, i = 0; j < conf.select_cnt; j++) {
206210
i = conf.select[j];
207211
if (get_header_val(&old_ptr, conf.headers[i], strlen(conf.headers[i]))) {
208212
switch ((header_types) i) {
209213
case ST:
210214
if (get_header_val(&old_ptr, "urn", strlen("urn"))) {
211215
SSDP_DEBUG_MSG("%s\n", old_ptr);
212-
append_value(conf.ext->st, SSDP_URN_LEN, old_ptr);
216+
append_value(conf.ext->st, SSDP_URN_LEN, old_ptr, ptr-old_ptr);
213217
}
214218
break;
215219
case NT:
216220
if (get_header_val(&old_ptr, "urn", strlen("urn"))) {
217221
SSDP_DEBUG_MSG("%s\n", old_ptr);
218-
append_value(conf.ext->nt, SSDP_URN_LEN, old_ptr);
222+
append_value(conf.ext->nt, SSDP_URN_LEN, old_ptr, ptr-old_ptr);
219223
}
220224
break;
221225
case LOCATION:
222226
{
223-
uint16_t port = parse_loc_port(old_ptr, conf.ip_version);
227+
uint16_t port = parse_loc_port(old_ptr, ptr-old_ptr,conf.ip_version);
224228

225229
if (port > 0) {
226230
SSDP_DEBUG_MSG("%d <- %d\n", conf.ext->port, port);
@@ -230,11 +234,11 @@ void SSDPPlugin::parse_headers(char *data, size_t payload_len, header_parser_con
230234
}
231235
case USER_AGENT:
232236
SSDP_DEBUG_MSG("%s\n", old_ptr);
233-
append_value(conf.ext->user_agent, SSDP_USER_AGENT_LEN, old_ptr);
237+
append_value(conf.ext->user_agent, SSDP_USER_AGENT_LEN, old_ptr, ptr-old_ptr);
234238
break;
235239
case SERVER:
236240
SSDP_DEBUG_MSG("%s\n", old_ptr);
237-
append_value(conf.ext->server, SSDP_SERVER_LEN, old_ptr);
241+
append_value(conf.ext->server, SSDP_SERVER_LEN, old_ptr, ptr-old_ptr);
238242
break;
239243
default:
240244
break;
@@ -259,14 +263,22 @@ void SSDPPlugin::parse_headers(char *data, size_t payload_len, header_parser_con
259263
* \param [in] entry_max Maximum length if the entry.
260264
* \param [in] value String containing the new entry.
261265
*/
262-
void SSDPPlugin::append_value(char *curr_entry, unsigned entry_max, char *value)
266+
void SSDPPlugin::append_value(char *curr_entry, unsigned entry_max, const char *value, unsigned value_len)
263267
{
264-
if (strlen(curr_entry) + strlen(value) + 1 < entry_max) {
265-
if (strstr(curr_entry, value) == nullptr) {
266-
SSDP_DEBUG_MSG("New entry\n");
267-
strcat(curr_entry, value);
268-
strcat(curr_entry, ";");
268+
if (strlen(curr_entry) + value_len + 1 < entry_max) {
269+
// return if value already in curr_entry
270+
for (unsigned i = 0; i < strlen(curr_entry) - value_len; i++) {
271+
if (strlen(curr_entry) < value_len) {
272+
break;
273+
}
274+
if (strncmp(&curr_entry[i], value, value_len) == 0) {
275+
return;
276+
}
269277
}
278+
279+
SSDP_DEBUG_MSG("New entry\n");
280+
strncat(curr_entry, value, value_len);
281+
strcat(curr_entry, ";");
270282
}
271283
}
272284

@@ -285,24 +297,22 @@ void SSDPPlugin::parse_ssdp_message(Flow &rec, const Packet &pkt)
285297
rec.ip_version,
286298
static_cast<RecordExtSSDP *>(rec.get_extension(RecordExtSSDP::REGISTERED_ID))
287299
};
288-
char *data = (char *) pkt.payload;
289-
size_t payload_len = pkt.payload_len;
290300

291301
total++;
292-
if (data[0] == 'N') {
302+
if (pkt.payload[0] == 'N') {
293303
notifies++;
294304
SSDP_DEBUG_MSG("Notify #%d\n", notifies);
295305
int notify_headers[] = { NT, LOCATION, SERVER };
296306
parse_conf.select = notify_headers;
297307
parse_conf.select_cnt = sizeof(notify_headers) / sizeof(notify_headers[0]);
298-
parse_headers(data, payload_len, parse_conf);
299-
} else if (data[0] == 'M') {
308+
parse_headers(pkt.payload, pkt.payload_len, parse_conf);
309+
} else if (pkt.payload[0] == 'M') {
300310
searches++;
301311
SSDP_DEBUG_MSG("M-search #%d\n", searches);
302312
int search_headers[] = { ST, USER_AGENT };
303313
parse_conf.select = search_headers;
304314
parse_conf.select_cnt = sizeof(search_headers) / sizeof(search_headers[0]);
305-
parse_headers(data, payload_len, parse_conf);
315+
parse_headers(pkt.payload, pkt.payload_len, parse_conf);
306316
}
307317
SSDP_DEBUG_MSG("\n");
308318
}

process/ssdp.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,11 +217,11 @@ class SSDPPlugin : public ProcessPlugin
217217
uint32_t searches; /**< Total number of parsed SSDP m-searches. */
218218
uint32_t total; /**< Total number of parsed SSDP packets. */
219219

220-
uint16_t parse_loc_port(char *data, uint8_t ip_version);
221-
bool get_header_val(char **data, const char *header, const int len);
222-
void parse_headers(char *data, size_t payload_len, header_parser_conf conf);
220+
uint16_t parse_loc_port(const char *data, unsigned data_len, uint8_t ip_version);
221+
bool get_header_val(const char **data, const char *header, const int len);
222+
void parse_headers(const uint8_t *data, size_t payload_len, header_parser_conf conf);
223223
void parse_ssdp_message(Flow &rec, const Packet &pkt);
224-
void append_value(char *curr_entry, unsigned entry_max, char *value);
224+
void append_value(char *curr_entry, unsigned entry_max, const char *value, unsigned value_len);
225225
};
226226

227227
}

0 commit comments

Comments
 (0)