32 int buffer_used = 0, count = 0;
39 buffer_used += snprintf(results + buffer_used,
40 buffer_size - buffer_used,
41 "Time received: %s\n",
43 buffer_used += snprintf(results + buffer_used,
44 buffer_size - buffer_used,
46 (ssdp_message->
mac != NULL ? ssdp_message->
mac :
47 "(Could not be determined)"));
48 buffer_used += snprintf(results + buffer_used,
49 buffer_size - buffer_used,
50 "Origin-IP: %s\nMessage length: %d Bytes\n",
53 buffer_used += snprintf(results + buffer_used,
54 buffer_size - buffer_used,
55 "Request: %s\nProtocol: %s\n",
60 buffer_used += snprintf(results + buffer_used,
61 buffer_size - buffer_used,
62 "Custom field[%d][%s]: %s\n",
73 buffer_used += snprintf(results + buffer_used,
74 buffer_size - buffer_used,
75 "Header[%d][type:%d;%s]: %s\n",
76 count, ssdp_headers->
type,
79 ssdp_headers = ssdp_headers->
next;
99 const struct sockaddr_storage *da,
int port,
int timeout,
102 if(url == NULL || strlen(url) < 1) {
103 PRINT_ERROR(
"send_stuff(): url not set");
108 PRINT_DEBUG(
"send_stuff(): creating socket");
130 PRINT_ERROR(
"send_stuff(): %s", strerror(errno));
135 PRINT_DEBUG(
"send_stuff(): setting up socket address");
137 if(da->ss_family == AF_INET) {
138 struct sockaddr_in *da_ipv4 = (
struct sockaddr_in *)da;
139 da_ipv4->sin_port = htons(port);
142 struct sockaddr_in6 *da_ipv6 = (
struct sockaddr_in6 *)da;
143 da_ipv6->sin6_port = htons(port);
149 PRINT_DEBUG(
"send_stuff(): connecting to destination (%s; ss_family = "
150 "%s [%d])", tmp_ip, (da->ss_family == AF_INET ?
"AF_INET" :
"AF_INET6"),
155 if(connect(send_sock, (
struct sockaddr*)da,
sizeof(
struct sockaddr)) ==
157 PRINT_ERROR(
"send_stuff(): connect(): %d, %s", errno, strerror(errno));
170 inet_ntop(da->ss_family, (da->ss_family == AF_INET ?
171 (
void *)&((
struct sockaddr_in *)da)->sin_addr :
174 int request_size = strlen(data) + 150;
175 char *request = (
char *)malloc(
sizeof(
char) * request_size);
176 memset(request,
'\0', request_size);
179 used_length = snprintf(request + used_length,
180 request_size - used_length,
181 "POST %s HTTP/1.1\r\n", url);
182 used_length += snprintf(request + used_length,
183 request_size - used_length,
185 used_length += snprintf(request + used_length,
186 request_size - used_length,
187 "Connection: close\r\n");
188 used_length += snprintf(request + used_length,
189 request_size - used_length,
191 used_length += snprintf(request + used_length,
192 request_size - used_length,
193 "Content-type: text/xml\r\n");
194 used_length += snprintf(request + used_length,
195 request_size - used_length,
196 "Content-length: %d\r\n\r\n", (
int)strlen(data));
197 used_length += snprintf(request + used_length,
198 request_size - used_length,
202 PRINT_DEBUG(
"send_stuff(): sending string:\n%s", request);
203 int bytes = send(send_sock, request, strlen(request), 0);
206 PRINT_ERROR(
"send_stuff(): Failed forwarding message (%d bytes sent)",
212 PRINT_DEBUG(
"send_stuff(): sent %d bytes", bytes);
213 int response_size = 10240;
214 char *response = (
char *)malloc(
sizeof(
char) * response_size);
216 PRINT_ERROR(
"Allocation failed: %s", strerror(errno));
219 memset(response,
'\0', response_size);
223 bytes = recv(send_sock, response + all_bytes, response_size - all_bytes, 0);
227 PRINT_DEBUG(
"send_stuff(): received %d bytes:\n%s", all_bytes, response);
230 PRINT_DEBUG(
"send_stuff(): closing socket");
246 if (!ssdp_cache_pointer) {
247 PRINT_ERROR(
"No ssdp cache list given");
252 if(NULL != *ssdp_cache_pointer) {
255 ssdp_cache = *ssdp_cache_pointer;
258 ssdp_cache = ssdp_cache->
first;
266 PRINT_DEBUG(
"Freeing one cache element");
274 next_cache = ssdp_cache->
next;
276 ssdp_cache = next_cache;
278 }
while(NULL != ssdp_cache);
281 *ssdp_cache_pointer = NULL;
285 PRINT_DEBUG(
"*ssdp_cache_pointer is NULL");
296 if (!ssdp_cache_pointer) {
297 PRINT_ERROR(
"No ssdp cache list given");
302 if (!(*ssdp_cache_pointer)) {
303 PRINT_DEBUG(
"Initializing the SSDP cache");
305 if (!(*ssdp_cache_pointer)) {
306 PRINT_ERROR(
"Failed to allocate memory for the ssdp cache list");
312 (*ssdp_cache_pointer)->first = *ssdp_cache_pointer;
315 (*ssdp_cache_pointer)->
next = NULL;
319 (
unsigned int *)malloc(
sizeof(
unsigned int));
320 *(*ssdp_cache_pointer)->ssdp_messages_count = 0;
325 ssdp_cache = (*ssdp_cache_pointer)->
first;
331 PRINT_DEBUG(
"Found duplicate SSDP message (IP '%s'), updating",
335 PRINT_DEBUG(
"Field MAC was empty, updating to '%s'",
340 PRINT_DEBUG(
"Trowing away the duplicate ssdp message and using "
347 ssdp_cache = ssdp_cache->
next;
353 ssdp_cache = *ssdp_cache_pointer;
357 if(NULL != ssdp_cache->
next) {
358 PRINT_DEBUG(
"Given SSDP Cache list is not pointing to the last element");
359 while(NULL != ssdp_cache->
next) {
360 ssdp_cache = ssdp_cache->
next;
362 PRINT_DEBUG(
"Moved to the last element in the cache list");
370 PRINT_DEBUG(
"Creating a new element in the SSDP cache list");
376 ssdp_cache = ssdp_cache->
next;
382 PRINT_DEBUG(
"SSDP cache counter increased to %d",
387 *ssdp_cache_pointer = ssdp_cache;
393 const char *url,
struct sockaddr_storage *sockaddr_recipient,
int port,
397 char ssdp_list[ssdp_list_size];
401 if(
cache_to_json(ssdp_cache, ssdp_list, ssdp_list_size) < 1) {
402 PRINT_ERROR(
"Failed creating JSON blob from ssdp cache");
409 if(
cache_to_xml(ssdp_cache, ssdp_list, ssdp_list_size) < 1) {
410 PRINT_ERROR(
"Failed creating XML blob from ssdp cache");
418 PRINT_ERROR(
"Failed creating plain-text message");
423 if (
send_stuff(url, ssdp_list, sockaddr_recipient, port, timeout, conf)) {
424 PRINT_WARN(
"Failed to send SSDP list to the specified forward address");
#define IPv6_STR_MAX_SIZE
SOCKET setup_socket(socket_conf_s *conf)
const char * get_header_string(const unsigned int header_type, const ssdp_header_s *header)
char ip[IPv6_STR_MAX_SIZE]
static void free_ssdp_cache(ssdp_cache_s **ssdp_cache_pointer)
struct ssdp_custom_field_struct * custom_fields
char interface[IPv6_STR_MAX_SIZE]
static int send_stuff(const char *url, const char *data, const struct sockaddr_storage *da, int port, int timeout, configuration_s *conf)
struct ssdp_header_struct * headers
BOOL flush_ssdp_cache(configuration_s *conf, ssdp_cache_s **ssdp_cache_pointer, const char *url, struct sockaddr_storage *sockaddr_recipient, int port, int timeout)
void free_ssdp_message(ssdp_message_s **message_pointer)
BOOL add_ssdp_message_to_cache(ssdp_cache_s **ssdp_cache_pointer, ssdp_message_s **ssdp_message_pointer)
struct ssdp_cache_struct * next
struct ssdp_custom_field_struct * first
struct ssdp_cache_struct * first
ssdp_message_s * ssdp_message
static configuration_s conf
unsigned int * ssdp_messages_count
static BOOL create_plain_text_message(char *results, int buffer_size, ssdp_message_s *ssdp_message)
char * get_ip_from_sock_address(const struct sockaddr_storage *saddr, char *ip_buffer)
struct ssdp_custom_field_struct * next