1 /*
2 * checkconf.c - Miredo conf parser unit test
3 */
4
5 /***********************************************************************
6 * Copyright © 2005-2007 Rémi Denis-Courmont. *
7 * This program is free software; you can redistribute and/or modify *
8 * it under the terms of the GNU General Public License as published *
9 * by the Free Software Foundation; version 2 of the license, or (at *
10 * your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
15 * See the GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, you can get it from: *
19 * http://www.gnu.org/copyleft/gpl.html *
20 ***********************************************************************/
21
22 #ifdef HAVE_CONFIG_H
23 # include <config.h>
24 #endif
25
26 #include <gettext.h>
27 #include <locale.h>
28 #include "binreloc.h"
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 #include <string.h>
34 #include <stdbool.h>
35
36 #include <unistd.h>
37 #include <inttypes.h>
38 #include <netinet/in.h>
39 #include "miredo.h"
40 #include "conf.h"
41
42 #ifdef HAVE_GETOPT_H
43 # include <getopt.h>
44 #endif
45
logger(void * fail,bool error,const char * fmt,va_list ap)46 static void logger (void *fail, bool error, const char *fmt, va_list ap)
47 {
48 *((bool *)fail) = true;
49 (void)error;
50
51 vfprintf (stderr, fmt, ap);
52 fputc ('\n', stderr);
53 }
54
55 /* FIXME: use same more clever code as in main.c */
56 static const char conffile[] = SYSCONFDIR"/miredo/miredo.conf";
57
miredo_checkconf(miredo_conf * conf)58 static int miredo_checkconf (miredo_conf *conf)
59 {
60 int i, res = 0;
61 if (!miredo_conf_parse_syslog_facility (conf, "SyslogFacility", &i))
62 res = -1;
63
64 bool client = true;
65
66 unsigned line;
67 char *val = miredo_conf_get (conf, "RelayType", &line);
68
69 if (val != NULL)
70 {
71 if ((strcasecmp (val, "client") == 0)
72 || (strcasecmp (val, "autoclient") == 0))
73 client = true;
74 else
75 if ((strcasecmp (val, "relay") == 0)
76 || (strcasecmp (val, "cone") == 0)
77 || (strcasecmp (val, "restricted") == 0))
78 client = false;
79 else
80 {
81 fprintf (stderr, _("Invalid relay type \"%s\" at line %u"),
82 val, line);
83 fputc ('\n', stderr);
84 res = -1;
85 }
86 free (val);
87 }
88
89 uint32_t u32;
90 uint16_t u16;
91
92 if (client)
93 {
94 #ifdef MIREDO_TEREDO_CLIENT
95 uint32_t ip = 0;
96
97 if (!miredo_conf_parse_IPv4 (conf, "ServerAddress", &ip)
98 || !miredo_conf_parse_IPv4 (conf, "ServerAddress2", &u32))
99 res = -1;
100
101 if (ip == 0)
102 {
103 fprintf (stderr, "%s\n", _("Server address not specified"));
104 res = -1;
105 }
106 #else
107 fprintf (stderr, "%s\n", _("Unsupported Teredo client mode"));
108 res = -1;
109 #endif
110 }
111 else
112 {
113 uint32_t pref;
114 if (!miredo_conf_parse_teredo_prefix (conf, "Prefix", &pref)
115 || !miredo_conf_get_int16 (conf, "InterfaceMTU", &u16, NULL))
116 res = -1;
117 }
118
119 if (!miredo_conf_parse_IPv4 (conf, "BindAddress", &u32)
120 || !miredo_conf_get_int16 (conf, "BindPort", &u16, NULL))
121 res = -1;
122
123 char *str = miredo_conf_get (conf, "InterfaceName", NULL);
124 if (str != NULL)
125 free (str);
126
127 miredo_conf_clear (conf, 5);
128 return res;
129 }
130
131
miredo_checkconffile(const char * filename)132 static int miredo_checkconffile (const char *filename)
133 {
134 bool failed = false;
135 miredo_conf *conf = miredo_conf_create (logger, &failed);
136
137 if (conf == NULL)
138 return -1;
139
140 if (!miredo_conf_read_file (conf, filename))
141 failed = true;
142 else
143 if (miredo_checkconf (conf))
144 failed = true;
145
146 miredo_conf_destroy (conf);
147 if (failed)
148 {
149 fprintf (stderr, "%s\n", _("Fatal configuration error"));
150 return -1;
151 }
152 return 0;
153 }
154
155
usage(const char * path)156 static int usage (const char *path)
157 {
158 printf ("Usage: %s [CONF_FILE]\n", path);
159 return 0;
160 }
161
162
main(int argc,char * argv[])163 int main(int argc, char *argv[])
164 {
165 (void)br_init (NULL);
166 (void)setlocale (LC_ALL, "");
167 char *path = br_find_locale_dir (LOCALEDIR);
168 (void)bindtextdomain (PACKAGE_NAME, path);
169 free (path);
170 path = NULL;
171
172 static const struct option opts[] =
173 {
174 { "conf", required_argument, NULL, 'c' },
175 { "config", required_argument, NULL, 'c' },
176 { "foreground", no_argument, NULL, 'f' },
177 { "help", no_argument, NULL, 'h' },
178 { "pidfile", required_argument, NULL, 'p' },
179 { "chroot", required_argument, NULL, 't' },
180 { "chrootdir", required_argument, NULL, 't' },
181 { "user", required_argument, NULL, 'u' },
182 { "username", required_argument, NULL, 'u' },
183 { "version", no_argument, NULL, 'V' },
184 { NULL, no_argument, NULL, '\0'}
185 };
186
187 const char *filename = NULL;
188
189 int c;
190 while ((c = getopt_long (argc, argv, "c:fhp:t:u:V", opts, NULL)) != -1)
191 switch (c)
192 {
193 case 'c':
194 filename = optarg;
195 break;
196
197 case 'h':
198 return usage(argv[0]);
199
200 case 'V':
201 return miredo_version();
202 }
203
204 if (optind < argc)
205 filename = argv[optind++];
206 else
207 if (filename == NULL)
208 {
209 /* No parameters provided - attempt in source tree test */
210 const char *srcdir = getenv ("srcdir");
211
212 if (srcdir != NULL)
213 filename = "../misc/miredo.conf";
214 else
215 filename = conffile;
216 }
217
218 int res = miredo_checkconffile (filename);
219
220 if (path != NULL)
221 free (path);
222
223 return res;
224 }
225