LIBSSDP
 All Classes Files Functions Variables Typedefs Macros
ssdp_filter.c
Go to the documentation of this file.
1 
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 
11 #include "log.h"
12 #include "ssdp_filter.h"
13 #include "ssdp_message.h"
14 #include "string_utils.h"
15 
17  if (factory) {
18  if (factory->filters) {
19  int fc;
20  for(fc = 0; fc < (factory->filters_count); fc++) {
21  if (factory->filters[fc].header) {
22  free(factory->filters[fc].header);
23  factory->filters[fc].header = NULL;
24  }
25  if ((factory->filters + fc)->value) {
26  free(factory->filters[fc].value);
27  factory->filters[fc].value = NULL;
28  }
29  }
30  free(factory->filters);
31  factory->filters = NULL;
32  }
33  free(factory);
34  factory = NULL;
35  }
36 }
37 
38 void parse_filters(char *raw_filter, filters_factory_s **filters_factory,
39  BOOL print_filters) {
40  char *pos = NULL, *last_pos = raw_filter, *splitter = NULL;
41  unsigned char filters_count = 0;
42  filters_factory_s *ff = NULL;
43 
44  if(raw_filter == NULL || strlen(raw_filter) < 1) {
45  if(print_filters) {
46  printf("No filters applied.\n");
47  }
48  return;
49  }
50 
51  /* Get rid of leading and trailing ',' and '=' */
52  while(*last_pos == ',' || *last_pos == '=') {
53  last_pos++;
54  }
55 
56  while(*(last_pos + strlen(last_pos) - 1) == ',' || *(last_pos + strlen(last_pos) - 1) == '=') {
57  memcpy((last_pos + strlen(last_pos) - 1), "\0", 1);
58  }
59 
60  /* Number of filters (filter delimiters) found */
61  filters_count = strcount(last_pos, ",") + 1;
62 
63  /* Create filter factory (a container for global use) */
64  *filters_factory = (filters_factory_s *)malloc(sizeof(filters_factory_s));
65 
66  /* Simplify access name and initialize */
67  ff = *filters_factory;
68  memset(ff, '\0', sizeof(filters_factory_s));
69  ff->filters_count = filters_count;
70 
71  /* Create place for all the filters */
72  ff->filters = (filter_s *)malloc(sizeof(filter_s) * filters_count);
73  memset(ff->filters, '\0', sizeof(filter_s) * filters_count);
74 
75  int fc;
76  for(fc = 0; fc < filters_count; fc++) {
77 
78  /* Header name which value to apply filter on */
79  ff->filters[fc].header = (char *)malloc(sizeof(char) * 64);
80  memset((ff->filters[fc]).header, '\0', sizeof(char) * 64);
81 
82  /* Header value to filter on */
83  ff->filters[fc].value = (char *)malloc(sizeof(char) * 2048);
84  memset(ff->filters[fc].value, '\0', sizeof(char) * 2048);
85 
86  /* Find filter splitter (',') */
87  pos = strstr(last_pos, ",");
88  if(pos == NULL) {
89  pos = last_pos + strlen(last_pos);
90  }
91 
92  /* Find name and value splitter ('=') */
93  splitter = strstr(last_pos, "=");
94  if(splitter > 0) {
95  strncpy(ff->filters[fc].header, last_pos, splitter - last_pos);
96  splitter++;
97  strncpy(ff->filters[fc].value, splitter, pos - splitter);
98  }
99  else {
100  strncpy(ff->filters[fc].header, last_pos, pos - last_pos);
101  }
102  last_pos = pos + 1;
103 
104  }
105 
106  if(print_filters) {
107  printf("\nFilters applied:\n");
108  int c;
109  for(c = 0; c < filters_count; c++) {
110  printf("%d: %s = %s\n", c, ff->filters[c].header, ff->filters[c].value);
111  }
112  }
113 }
114 
115 BOOL filter(ssdp_message_s *ssdp_message, filters_factory_s *filters_factory) {
116 
117  PRINT_DEBUG("traversing filters");
118  BOOL drop_message = FALSE;
119  int fc;
120  for(fc = 0; fc < filters_factory->filters_count; fc++) {
121 
122  BOOL filter_found = FALSE;
123  char *filter_value = filters_factory->filters[fc].value;
124  char *filter_header = filters_factory->filters[fc].header;
125 
126  /* If IP filtering has been set, check values */
127  if(strcmp(filter_header, "ip") == 0) {
128  filter_found = TRUE;
129  if(strstr(ssdp_message->ip, filter_value) == NULL) {
130  PRINT_DEBUG("IP filter mismatch, dropping message");
131  drop_message = TRUE;
132  break;
133  }
134  }
135 
136  /* If mac filtering has been set, check values */
137  if(strcmp(filter_header, "mac") == 0) {
138  filter_found = TRUE;
139  if(strstr(ssdp_message->mac, filter_value) == NULL) {
140  PRINT_DEBUG("MAC filter mismatch, dropping message");
141  drop_message = TRUE;
142  break;
143  }
144  }
145 
146  /* If protocol filtering has been set, check values */
147  if(strcmp(filter_header, "protocol") == 0) {
148  filter_found = TRUE;
149  if(strstr(ssdp_message->protocol, filter_value) == NULL) {
150  PRINT_DEBUG("Protocol filter mismatch, dropping message");
151  drop_message = TRUE;
152  break;
153  }
154  }
155 
156  /* If request filtering has been set, check values */
157  if(strcmp(filter_header, "request") == 0) {
158  filter_found = TRUE;
159  if(strstr(ssdp_message->request, filter_value) == NULL) {
160  PRINT_DEBUG("Request filter mismatch, dropping message");
161  drop_message = TRUE;
162  break;
163  }
164  }
165 
166  ssdp_header_s *ssdp_headers = ssdp_message->headers;
167 
168  /* If any other filter has been set try to match it
169  with a header type and then check values */
170  while(ssdp_headers) {
171 
172  /* See if the headet type matches the filter type
173  and if so check the values */
174  char const *ssdp_header_string = get_header_string(ssdp_headers->type, ssdp_headers);
175  if(strcmp(ssdp_header_string, filter_header) == 0) {
176  filter_found = TRUE;
177 
178  /* Then see if the values match */
179  if(strstr(ssdp_headers->contents, filter_value) == NULL) {
180  PRINT_DEBUG("Header (%s) filter mismatch, marked for dropping", filter_header);
181  drop_message = TRUE;
182  break;
183  }
184  }
185  ssdp_headers = ssdp_headers->next;
186  }
187 
188  /* If no comparison (match or missmatch) was made then drop the message */
189  if(!filter_found) {
190  PRINT_DEBUG("Filter type not found, marked for dropping");
191  drop_message = TRUE;
192  }
193 
194  if(drop_message) {
195  break;
196  }
197  }
198 
199  return drop_message;
200 }
201 
const char * get_header_string(const unsigned int header_type, const ssdp_header_s *header)
Definition: ssdp_message.c:402
void parse_filters(char *raw_filter, filters_factory_s **filters_factory, BOOL print_filters)
Definition: ssdp_filter.c:38
unsigned char type
Definition: ssdp_message.h:58
struct ssdp_header_struct * next
Definition: ssdp_message.h:66
struct ssdp_header_struct * headers
Definition: ssdp_message.h:108
unsigned char filters_count
Definition: ssdp_filter.h:29
#define TRUE
#define FALSE
char * header
Definition: ssdp_filter.h:15
int BOOL
char * value
Definition: ssdp_filter.h:17
BOOL filter(ssdp_message_s *ssdp_message, filters_factory_s *filters_factory)
Definition: ssdp_filter.c:115
unsigned char strcount(const char *haystack, const char *needle)
Definition: string_utils.c:19
void free_ssdp_filters_factory(filters_factory_s *factory)
Definition: ssdp_filter.c:16