Miniupnpd: update from 1.8 (20140422) to 1.9 (20141209)
[tomato.git] / release / src / router / miniupnpd / options.c
blobb37d69dd208ea0c07609ecbbe2159ac05259bf62
1 /* $Id: options.c,v 1.32 2014/05/22 07:52:45 nanard Exp $ */
2 /* MiniUPnP project
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * author: Ryan Wagoner
5 * (c) 2006-2014 Thomas Bernard
6 * This software is subject to the conditions detailed
7 * in the LICENCE file provided within the distribution */
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <ctype.h>
13 #include <syslog.h>
14 #include "config.h"
15 #include "options.h"
16 #include "upnppermissions.h"
17 #ifdef PCP_SADSCP
18 #include "pcplearndscp.h"
19 #endif /* PCP_SADSPC */
20 #include "upnpglobalvars.h"
22 #ifndef DISABLE_CONFIG_FILE
23 struct option * ary_options = NULL;
24 static char * string_repo = NULL;
25 unsigned int num_options = 0;
27 static const struct {
28 enum upnpconfigoptions id;
29 const char * name;
30 } optionids[] = {
31 { UPNPEXT_IFNAME, "ext_ifname" },
32 { UPNPEXT_IP, "ext_ip" },
33 { UPNPLISTENING_IP, "listening_ip" },
34 #ifdef ENABLE_IPV6
35 { UPNPIPV6_LISTENING_IP, "ipv6_listening_ip" },
36 #endif /* ENABLE_IPV6 */
37 { UPNPPORT, "port" },
38 { UPNPPORT, "http_port" }, /* "port" and "http_port" are synonims */
39 #ifdef ENABLE_HTTPS
40 { UPNPHTTPSPORT, "https_port" },
41 #endif /* ENABLE_HTTPS */
42 { UPNPBITRATE_UP, "bitrate_up" },
43 { UPNPBITRATE_DOWN, "bitrate_down" },
44 { UPNPPRESENTATIONURL, "presentation_url" },
45 #ifdef ENABLE_MANUFACTURER_INFO_CONFIGURATION
46 { UPNPFRIENDLY_NAME, "friendly_name" },
47 { UPNPMANUFACTURER_NAME, "manufacturer_name" },
48 { UPNPMANUFACTURER_URL, "manufacturer_url" },
49 { UPNPMODEL_NAME, "model_name" },
50 { UPNPMODEL_DESCRIPTION, "model_description" },
51 { UPNPMODEL_URL, "model_url" },
52 #endif
53 { UPNPNOTIFY_INTERVAL, "notify_interval" },
54 { UPNPSYSTEM_UPTIME, "system_uptime" },
55 { UPNPPACKET_LOG, "packet_log" },
56 { UPNPUUID, "uuid"},
57 { UPNPSERIAL, "serial"},
58 { UPNPMODEL_NUMBER, "model_number"},
59 { UPNPCLEANTHRESHOLD, "clean_ruleset_threshold"},
60 { UPNPCLEANINTERVAL, "clean_ruleset_interval"},
61 #ifdef USE_NETFILTER
62 { UPNPFORWARDCHAIN, "upnp_forward_chain"},
63 { UPNPNATCHAIN, "upnp_nat_chain"},
64 #endif
65 #ifdef ENABLE_NATPMP
66 { UPNPENABLENATPMP, "enable_natpmp"},
67 #endif
68 #ifdef ENABLE_PCP
69 { UPNPPCPMINLIFETIME, "min_lifetime"},
70 { UPNPPCPMAXLIFETIME, "max_lifetime"},
71 { UPNPPCPALLOWTHIRDPARTY, "pcp_allow_thirdparty"},
72 #endif
73 { UPNPENABLE, "enable_upnp"},
74 #ifdef USE_PF
75 { UPNPANCHOR, "anchor"},
76 { UPNPQUEUE, "queue"},
77 { UPNPTAG, "tag"},
78 #endif
79 #ifdef PF_ENABLE_FILTER_RULES
80 { UPNPQUICKRULES, "quickrules" },
81 #endif
82 #ifdef ENABLE_LEASEFILE
83 { UPNPLEASEFILE, "lease_file"},
84 #endif
85 { UPNPMINISSDPDSOCKET, "minissdpdsocket"},
86 { UPNPSECUREMODE, "secure_mode"}
89 int
90 readoptionsfile(const char * fname)
92 FILE *hfile = NULL;
93 char buffer[1024];
94 char *equals;
95 char *name;
96 char *value;
97 char *t;
98 int linenum = 0;
99 unsigned int i;
100 enum upnpconfigoptions id;
101 size_t string_repo_len = 0;
102 size_t len;
103 void *tmp;
105 if(!fname || (strlen(fname) == 0))
106 return -1;
108 memset(buffer, 0, sizeof(buffer));
110 #ifdef DEBUG
111 printf("Reading configuration from file %s\n", fname);
112 #endif
114 if(!(hfile = fopen(fname, "r")))
115 return -1;
117 if(ary_options != NULL)
119 free(ary_options);
120 num_options = 0;
123 while(fgets(buffer, sizeof(buffer), hfile))
125 linenum++;
126 t = strchr(buffer, '\n');
127 if(t)
129 *t = '\0';
130 t--;
131 /* remove spaces at the end of the line */
132 while((t >= buffer) && isspace(*t))
134 *t = '\0';
135 t--;
139 /* skip leading whitespaces */
140 name = buffer;
141 while(isspace(*name))
142 name++;
144 /* check for comments or empty lines */
145 if(name[0] == '#' || name[0] == '\0') continue;
147 len = strlen(name); /* length of the whole line excluding leading
148 * and ending white spaces */
149 /* check for UPnP permissions rule */
150 if((len > 6) && (0 == memcmp(name, "allow", 5) || 0 == memcmp(name, "deny", 4)))
152 tmp = realloc(upnppermlist, sizeof(struct upnpperm) * (num_upnpperm+1));
153 if(tmp == NULL)
155 fprintf(stderr, "memory allocation error. Permission line in file %s line %d\n",
156 fname, linenum);
158 else
160 upnppermlist = tmp;
161 /* parse the rule */
162 if(read_permission_line(upnppermlist + num_upnpperm, name) >= 0)
164 num_upnpperm++;
166 else
168 fprintf(stderr, "parsing error file %s line %d : %s\n",
169 fname, linenum, name);
172 continue;
174 #ifdef PCP_SADSCP
175 /* check for DSCP values configuration */
176 if((len > 15) && 0 == memcmp(name, "set_learn_dscp", sizeof("set_learn_dscp")-1) )
178 tmp = realloc(dscp_values_list, sizeof(struct dscp_values) * (num_dscp_values+1));
179 if(tmp == NULL)
181 fprintf(stderr, "memory allocation error. DSCP line in file %s line %d\n",
182 fname, linenum);
184 else
186 dscp_values_list = tmp;
187 /* parse the rule */
188 if(read_learn_dscp_line(dscp_values_list + num_dscp_values, name) >= 0)
190 num_dscp_values++;
192 else
194 fprintf(stderr, "parsing error file %s line %d : %s\n",
195 fname, linenum, name);
198 continue;
200 #endif /* PCP_SADSCP */
201 if(!(equals = strchr(name, '=')))
203 fprintf(stderr, "parsing error file %s line %d : %s\n",
204 fname, linenum, name);
205 continue;
208 /* remove ending whitespaces */
209 for(t=equals-1; t>name && isspace(*t); t--)
210 *t = '\0';
212 *equals = '\0';
213 value = equals+1;
215 /* skip leading whitespaces */
216 while(isspace(*value))
217 value++;
219 id = UPNP_INVALID;
220 for(i=0; i<sizeof(optionids)/sizeof(optionids[0]); i++)
222 /*printf("%2d %2d %s %s\n", i, optionids[i].id, name,
223 optionids[i].name); */
225 if(0 == strcmp(name, optionids[i].name))
227 id = optionids[i].id;
228 break;
232 if(id == UPNP_INVALID)
234 fprintf(stderr, "invalid option in file %s line %d : %s=%s\n",
235 fname, linenum, name, value);
237 else
239 tmp = realloc(ary_options, (num_options + 1) * sizeof(struct option));
240 if(tmp == NULL)
242 fprintf(stderr, "memory allocation error. Option in file %s line %d.\n",
243 fname, linenum);
245 else
247 ary_options = tmp;
248 len = strlen(value) + 1; /* +1 for terminating '\0' */
249 tmp = realloc(string_repo, string_repo_len + len);
250 if(tmp == NULL)
252 fprintf(stderr, "memory allocation error, Option value in file %s line %d : %s=%s\n",
253 fname, linenum, name, value);
255 else
257 string_repo = tmp;
258 memcpy(string_repo + string_repo_len, value, len);
259 ary_options[num_options].id = id;
260 /* save the offset instead of the absolute address because realloc() could
261 * change it */
262 ary_options[num_options].value = (const char *)string_repo_len;
263 num_options += 1;
264 string_repo_len += len;
271 fclose(hfile);
273 for(i = 0; i < num_options; i++)
275 /* add start address of string_repo to get right pointer */
276 ary_options[i].value = string_repo + (size_t)ary_options[i].value;
279 return 0;
282 void
283 freeoptions(void)
285 if(ary_options)
287 free(ary_options);
288 ary_options = NULL;
289 num_options = 0;
291 if(string_repo)
293 free(string_repo);
294 string_repo = NULL;
296 if(upnppermlist)
298 free(upnppermlist);
299 upnppermlist = NULL;
300 num_upnpperm = 0;
302 #ifdef PCP_SADSCP
303 if(dscp_values_list)
305 unsigned int i;
306 for (i = 0; i < num_dscp_values; i++) {
307 if (dscp_values_list[i].app_name) {
308 free(dscp_values_list[i].app_name);
309 dscp_values_list[i].app_name = NULL;
312 free(dscp_values_list);
313 dscp_values_list = NULL;
314 num_dscp_values = 0;
316 #endif /* PCP_SADSCP */
319 #endif /* DISABLE_CONFIG_FILE */