TOR: fix compilation
[tomato.git] / release / src / router / miniupnpd / options.c
blobac4878810555f1c7d0f22c1d6836ce97c355afa2
1 /* $Id: options.c,v 1.33 2016/02/09 09:37:44 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 { UPNPNATPOSTCHAIN, "upnp_nat_postrouting_chain"},
65 #endif
66 #ifdef ENABLE_NATPMP
67 { UPNPENABLENATPMP, "enable_natpmp"},
68 #endif
69 #ifdef ENABLE_PCP
70 { UPNPPCPMINLIFETIME, "min_lifetime"},
71 { UPNPPCPMAXLIFETIME, "max_lifetime"},
72 { UPNPPCPALLOWTHIRDPARTY, "pcp_allow_thirdparty"},
73 #endif
74 { UPNPENABLE, "enable_upnp"},
75 #ifdef USE_PF
76 { UPNPANCHOR, "anchor"},
77 { UPNPQUEUE, "queue"},
78 { UPNPTAG, "tag"},
79 #endif
80 #ifdef PF_ENABLE_FILTER_RULES
81 { UPNPQUICKRULES, "quickrules" },
82 #endif
83 #ifdef ENABLE_LEASEFILE
84 { UPNPLEASEFILE, "lease_file"},
85 #endif
86 { UPNPMINISSDPDSOCKET, "minissdpdsocket"},
87 { UPNPSECUREMODE, "secure_mode"}
90 int
91 readoptionsfile(const char * fname)
93 FILE *hfile = NULL;
94 char buffer[1024];
95 char *equals;
96 char *name;
97 char *value;
98 char *t;
99 int linenum = 0;
100 unsigned int i;
101 enum upnpconfigoptions id;
102 size_t string_repo_len = 0;
103 size_t len;
104 void *tmp;
106 if(!fname || (strlen(fname) == 0))
107 return -1;
109 memset(buffer, 0, sizeof(buffer));
111 #ifdef DEBUG
112 printf("Reading configuration from file %s\n", fname);
113 #endif
115 if(!(hfile = fopen(fname, "r")))
116 return -1;
118 if(ary_options != NULL)
120 free(ary_options);
121 num_options = 0;
124 while(fgets(buffer, sizeof(buffer), hfile))
126 linenum++;
127 t = strchr(buffer, '\n');
128 if(t)
130 *t = '\0';
131 t--;
132 /* remove spaces at the end of the line */
133 while((t >= buffer) && isspace(*t))
135 *t = '\0';
136 t--;
140 /* skip leading whitespaces */
141 name = buffer;
142 while(isspace(*name))
143 name++;
145 /* check for comments or empty lines */
146 if(name[0] == '#' || name[0] == '\0') continue;
148 len = strlen(name); /* length of the whole line excluding leading
149 * and ending white spaces */
150 /* check for UPnP permissions rule */
151 if((len > 6) && (0 == memcmp(name, "allow", 5) || 0 == memcmp(name, "deny", 4)))
153 tmp = realloc(upnppermlist, sizeof(struct upnpperm) * (num_upnpperm+1));
154 if(tmp == NULL)
156 fprintf(stderr, "memory allocation error. Permission line in file %s line %d\n",
157 fname, linenum);
159 else
161 upnppermlist = tmp;
162 /* parse the rule */
163 if(read_permission_line(upnppermlist + num_upnpperm, name) >= 0)
165 num_upnpperm++;
167 else
169 fprintf(stderr, "parsing error file %s line %d : %s\n",
170 fname, linenum, name);
173 continue;
175 #ifdef PCP_SADSCP
176 /* check for DSCP values configuration */
177 if((len > 15) && 0 == memcmp(name, "set_learn_dscp", sizeof("set_learn_dscp")-1) )
179 tmp = realloc(dscp_values_list, sizeof(struct dscp_values) * (num_dscp_values+1));
180 if(tmp == NULL)
182 fprintf(stderr, "memory allocation error. DSCP line in file %s line %d\n",
183 fname, linenum);
185 else
187 dscp_values_list = tmp;
188 /* parse the rule */
189 if(read_learn_dscp_line(dscp_values_list + num_dscp_values, name) >= 0)
191 num_dscp_values++;
193 else
195 fprintf(stderr, "parsing error file %s line %d : %s\n",
196 fname, linenum, name);
199 continue;
201 #endif /* PCP_SADSCP */
202 if(!(equals = strchr(name, '=')))
204 fprintf(stderr, "parsing error file %s line %d : %s\n",
205 fname, linenum, name);
206 continue;
209 /* remove ending whitespaces */
210 for(t=equals-1; t>name && isspace(*t); t--)
211 *t = '\0';
213 *equals = '\0';
214 value = equals+1;
216 /* skip leading whitespaces */
217 while(isspace(*value))
218 value++;
220 id = UPNP_INVALID;
221 for(i=0; i<sizeof(optionids)/sizeof(optionids[0]); i++)
223 /*printf("%2d %2d %s %s\n", i, optionids[i].id, name,
224 optionids[i].name); */
226 if(0 == strcmp(name, optionids[i].name))
228 id = optionids[i].id;
229 break;
233 if(id == UPNP_INVALID)
235 fprintf(stderr, "invalid option in file %s line %d : %s=%s\n",
236 fname, linenum, name, value);
238 else
240 tmp = realloc(ary_options, (num_options + 1) * sizeof(struct option));
241 if(tmp == NULL)
243 fprintf(stderr, "memory allocation error. Option in file %s line %d.\n",
244 fname, linenum);
246 else
248 ary_options = tmp;
249 len = strlen(value) + 1; /* +1 for terminating '\0' */
250 tmp = realloc(string_repo, string_repo_len + len);
251 if(tmp == NULL)
253 fprintf(stderr, "memory allocation error, Option value in file %s line %d : %s=%s\n",
254 fname, linenum, name, value);
256 else
258 string_repo = tmp;
259 memcpy(string_repo + string_repo_len, value, len);
260 ary_options[num_options].id = id;
261 /* save the offset instead of the absolute address because realloc() could
262 * change it */
263 ary_options[num_options].value = (const char *)string_repo_len;
264 num_options += 1;
265 string_repo_len += len;
272 fclose(hfile);
274 for(i = 0; i < num_options; i++)
276 /* add start address of string_repo to get right pointer */
277 ary_options[i].value = string_repo + (size_t)ary_options[i].value;
280 return 0;
283 void
284 freeoptions(void)
286 if(ary_options)
288 free(ary_options);
289 ary_options = NULL;
290 num_options = 0;
292 if(string_repo)
294 free(string_repo);
295 string_repo = NULL;
297 if(upnppermlist)
299 free(upnppermlist);
300 upnppermlist = NULL;
301 num_upnpperm = 0;
303 #ifdef PCP_SADSCP
304 if(dscp_values_list)
306 unsigned int i;
307 for (i = 0; i < num_dscp_values; i++) {
308 if (dscp_values_list[i].app_name) {
309 free(dscp_values_list[i].app_name);
310 dscp_values_list[i].app_name = NULL;
313 free(dscp_values_list);
314 dscp_values_list = NULL;
315 num_dscp_values = 0;
317 #endif /* PCP_SADSCP */
320 #endif /* DISABLE_CONFIG_FILE */