ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/conf.C
Revision: 1.45
Committed: Fri Aug 8 16:48:00 2008 UTC (15 years, 9 months ago) by pcg
Content type: text/plain
Branch: MAIN
Changes since 1.44: +6 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 pcg 1.1 /*
2     conf.c -- configuration code
3 pcg 1.44 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de>
4 pcg 1.1
5 pcg 1.31 This file is part of GVPE.
6    
7 pcg 1.44 GVPE is free software; you can redistribute it and/or modify it
8     under the terms of the GNU General Public License as published by the
9     Free Software Foundation; either version 3 of the License, or (at your
10     option) any later version.
11    
12     This program is distributed in the hope that it will be useful, but
13     WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15     Public License for more details.
16    
17     You should have received a copy of the GNU General Public License along
18     with this program; if not, see <http://www.gnu.org/licenses/>.
19    
20     Additional permission under GNU GPL version 3 section 7
21    
22     If you modify this Program, or any covered work, by linking or
23     combining it with the OpenSSL project's OpenSSL library (or a modified
24     version of that library), containing parts covered by the terms of the
25     OpenSSL or SSLeay licenses, the licensors of this Program grant you
26     additional permission to convey the resulting work. Corresponding
27     Source for a non-source form of such a combination shall include the
28     source code for the parts of OpenSSL used as well as that of the
29     covered work.
30 pcg 1.1 */
31    
32     #include "config.h"
33    
34     #include <cstdio>
35     #include <cstdlib>
36     #include <cstring>
37    
38     #include <errno.h>
39     #include <netdb.h>
40     #include <sys/stat.h>
41     #include <sys/types.h>
42     #include <unistd.h>
43    
44 pcg 1.17 #include "netcompat.h"
45 pcg 1.5
46 pcg 1.1 #include <openssl/err.h>
47     #include <openssl/pem.h>
48     #include <openssl/rsa.h>
49     #include <openssl/rand.h>
50 pcg 1.22 #include <openssl/bn.h>
51 pcg 1.1
52     #include "conf.h"
53     #include "slog.h"
54     #include "util.h"
55    
56     char *confbase;
57     char *thisnode;
58     char *identname;
59    
60     struct configuration conf;
61    
62 pcg 1.7 u8 best_protocol (u8 protset)
63     {
64 pcg 1.13 if (protset & PROT_IPv4 ) return PROT_IPv4;
65     if (protset & PROT_ICMPv4) return PROT_ICMPv4;
66     if (protset & PROT_UDPv4 ) return PROT_UDPv4;
67     if (protset & PROT_TCPv4 ) return PROT_TCPv4;
68 pcg 1.24 if (protset & PROT_DNSv4 ) return PROT_DNSv4;
69 pcg 1.7
70 pcg 1.9 return 0;
71 pcg 1.7 }
72    
73     const char *strprotocol (u8 protocol)
74     {
75 pcg 1.13 if (protocol & PROT_IPv4 ) return "rawip";
76     if (protocol & PROT_ICMPv4) return "icmp";
77     if (protocol & PROT_UDPv4 ) return "udp";
78     if (protocol & PROT_TCPv4 ) return "tcp";
79 pcg 1.24 if (protocol & PROT_DNSv4 ) return "dns";
80 pcg 1.7
81     return "<unknown>";
82     }
83    
84 pcg 1.42 static bool
85     match_list (const vector<const char *> &list, const char *str)
86     {
87     for (vector<const char *>::const_iterator i = list.end (); i-- > list.begin (); )
88     if ((*i)[0] == '*' && !(*i)[1])
89     return true;
90     else if (!strcmp (*i, str))
91     return true;
92    
93     return false;
94     }
95    
96     bool
97     conf_node::can_direct (struct conf_node *other)
98     {
99     if (match_list (allow_direct, other->nodename))
100     return true;
101    
102     if (match_list (deny_direct, other->nodename))
103     return false;
104    
105     return true;
106     }
107    
108 pcg 1.12 void
109     conf_node::print ()
110 pcg 1.1 {
111 pcg 1.12 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n",
112     id,
113     id >> 8, id & 0xff,
114     compress ? 'Y' : 'N',
115     connectmode == C_ONDEMAND ? "ondemand" :
116     connectmode == C_NEVER ? "never" :
117     connectmode == C_ALWAYS ? "always" : "",
118     nodename,
119     hostname ? hostname : "",
120     hostname ? ":" : "",
121     hostname ? udp_port : 0
122     );
123 pcg 1.1 }
124    
125 pcg 1.12 conf_node::~conf_node ()
126 pcg 1.1 {
127 pcg 1.39 #if 0
128     // does not work, because string pointers etc. are shared
129     // is not called, however
130 pcg 1.12 if (rsa_key)
131     RSA_free (rsa_key);
132    
133     free (nodename);
134     free (hostname);
135 pcg 1.39 free (if_up_data);
136 pcg 1.30 #if ENABLE_DNS
137 pcg 1.28 free (domain);
138 pcg 1.30 free (dns_hostname);
139     #endif
140 pcg 1.39 #endif
141 pcg 1.1 }
142    
143     void configuration::init ()
144     {
145     memset (this, 0, sizeof (*this));
146    
147 pcg 1.19 mtu = DEFAULT_MTU;
148 pcg 1.1 rekey = DEFAULT_REKEY;
149     keepalive = DEFAULT_KEEPALIVE;
150 pcg 1.2 llevel = L_INFO;
151 pcg 1.5 ip_proto = IPPROTO_GRE;
152 pcg 1.16 #if ENABLE_ICMP
153 pcg 1.13 icmp_type = ICMP_ECHOREPLY;
154 pcg 1.16 #endif
155 pcg 1.1
156 pcg 1.5 default_node.udp_port = DEFAULT_UDPPORT;
157 pcg 1.24 default_node.tcp_port = DEFAULT_UDPPORT; // ehrm
158 pcg 1.1 default_node.connectmode = conf_node::C_ALWAYS;
159     default_node.compress = true;
160 pcg 1.29 default_node.protocols = 0;
161 pcg 1.27 default_node.max_retry = DEFAULT_MAX_RETRY;
162 pcg 1.43 default_node.max_ttl = DEFAULT_MAX_TTL;
163     default_node.max_queue = DEFAULT_MAX_QUEUE;
164 pcg 1.39 default_node.if_up_data = strdup ("");
165 pcg 1.25
166 pcg 1.30 #if ENABLE_DNS
167 pcg 1.32 default_node.dns_port = 0; // default is 0 == client
168 pcg 1.38
169     dns_forw_host = strdup ("127.0.0.1");
170     dns_forw_port = 53;
171     dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR;
172     dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
173     dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
174     dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING;
175 pcg 1.30 #endif
176    
177 pcg 1.27 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
178 pcg 1.1 }
179    
180     void configuration::cleanup()
181     {
182     if (rsa_key)
183     RSA_free (rsa_key);
184    
185 pcg 1.12 rsa_key = 0;
186 pcg 1.1
187 pcg 1.28 free (pidfilename); pidfilename = 0;
188     free (ifname); ifname = 0;
189 pcg 1.12 #if ENABLE_HTTP_PROXY
190 pcg 1.28 free (proxy_host); proxy_host = 0;
191     free (proxy_auth); proxy_auth = 0;
192     #endif
193     #if ENABLE_DNS
194     free (dns_forw_host); dns_forw_host = 0;
195 pcg 1.12 #endif
196 pcg 1.1 }
197    
198     void
199 pcg 1.40 configuration::clear ()
200 pcg 1.1 {
201     for (configuration::node_vector::iterator i = nodes.begin(); i != nodes.end(); ++i)
202     delete *i;
203    
204     nodes.clear ();
205    
206     cleanup ();
207     init ();
208     }
209    
210 pcg 1.37 #define parse_bool(target,name,trueval,falseval) do { \
211     if (!strcmp (val, "yes")) target = trueval; \
212 pcg 1.5 else if (!strcmp (val, "no")) target = falseval; \
213     else if (!strcmp (val, "true")) target = trueval; \
214     else if (!strcmp (val, "false")) target = falseval; \
215     else if (!strcmp (val, "on")) target = trueval; \
216     else if (!strcmp (val, "off")) target = falseval; \
217     else \
218 pcg 1.40 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed. (ignored)"); \
219 pcg 1.37 } while (0)
220 pcg 1.5
221 pcg 1.40 const char *
222     configuration_parser::parse_line (char *line)
223 pcg 1.1 {
224 pcg 1.40 {
225     char *end = line + strlen (line);
226    
227     while (*end < ' ' && end >= line)
228     end--;
229 pcg 1.1
230 pcg 1.40 *++end = 0;
231     }
232 pcg 1.1
233 pcg 1.40 char *tok = line;
234     const char *var = strtok (tok, "\t =");
235     tok = 0;
236 pcg 1.1
237 pcg 1.40 if (!var || !var[0])
238     return 0; /* no tokens on this line */
239 pcg 1.1
240 pcg 1.40 if (var[0] == '#')
241     return 0; /* comment: ignore */
242 pcg 1.1
243 pcg 1.40 char *val = strtok (NULL, "\t\n\r =");
244 pcg 1.1
245 pcg 1.40 if (!val || val[0] == '#')
246     return _("no value given for variable. (ignored)");
247 pcg 1.1
248 pcg 1.40 if (!strcmp (var, "on"))
249     {
250     if (!::thisnode
251     || (val[0] == '!' && strcmp (val + 1, ::thisnode))
252     || !strcmp (val, ::thisnode))
253     return parse_line (strtok (NULL, "\n\r"));
254     else
255     return 0;
256     }
257 pcg 1.1
258 pcg 1.40 // truly global
259     if (!strcmp (var, "loglevel"))
260     {
261     loglevel l = string_to_loglevel (val);
262 pcg 1.1
263 pcg 1.40 if (l == L_NONE)
264     return _("unknown loglevel. (skipping)");
265     }
266     else if (!strcmp (var, "ip-proto"))
267     conf.ip_proto = atoi (val);
268     else if (!strcmp (var, "icmp-type"))
269     {
270 pcg 1.16 #if ENABLE_ICMP
271 pcg 1.40 conf.icmp_type = atoi (val);
272 pcg 1.16 #endif
273 pcg 1.40 }
274 pcg 1.1
275 pcg 1.40 // per config
276     else if (!strcmp (var, "node"))
277     {
278     parse_argv ();
279 pcg 1.1
280 pcg 1.40 conf.default_node.id++;
281     node = new conf_node (conf.default_node);
282     conf.nodes.push_back (node);
283     node->nodename = strdup (val);
284 pcg 1.1
285 pcg 1.40 {
286     char *fname;
287     FILE *f;
288    
289     asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
290 pcg 1.1
291 pcg 1.40 f = fopen (fname, "r");
292     if (f)
293     {
294     node->rsa_key = RSA_new ();
295 pcg 1.1
296 pcg 1.40 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
297 pcg 1.1 {
298 pcg 1.40 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
299     slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
300     exit (EXIT_FAILURE);
301     }
302    
303     require (RSA_blinding_on (node->rsa_key, 0));
304 pcg 1.1
305 pcg 1.40 fclose (f);
306     }
307     else
308     {
309     slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
310 pcg 1.1
311 pcg 1.40 if (need_keys)
312     exit (EXIT_FAILURE);
313     }
314 pcg 1.1
315 pcg 1.40 free (fname);
316     }
317 pcg 1.1
318 pcg 1.40 if (::thisnode && !strcmp (node->nodename, ::thisnode))
319     conf.thisnode = node;
320     }
321     else if (!strcmp (var, "private-key"))
322     free (conf.prikeyfile), conf.prikeyfile = strdup (val);
323     else if (!strcmp (var, "ifpersist"))
324     parse_bool (conf.ifpersist, "ifpersist", true, false);
325     else if (!strcmp (var, "ifname"))
326     free (conf.ifname), conf.ifname = strdup (val);
327     else if (!strcmp (var, "rekey"))
328     conf.rekey = atoi (val);
329     else if (!strcmp (var, "keepalive"))
330     conf.keepalive = atoi (val);
331     else if (!strcmp (var, "mtu"))
332     conf.mtu = atoi (val);
333     else if (!strcmp (var, "if-up"))
334     free (conf.script_if_up), conf.script_if_up = strdup (val);
335     else if (!strcmp (var, "node-up"))
336     free (conf.script_node_up), conf.script_node_up = strdup (val);
337     else if (!strcmp (var, "node-down"))
338     free (conf.script_node_down), conf.script_node_down = strdup (val);
339     else if (!strcmp (var, "pid-file"))
340     free (conf.pidfilename), conf.pidfilename = strdup (val);
341     else if (!strcmp (var, "dns-forw-host"))
342     {
343 pcg 1.30 #if ENABLE_DNS
344 pcg 1.40 free (conf.dns_forw_host), conf.dns_forw_host = strdup (val);
345 pcg 1.34 #endif
346 pcg 1.40 }
347     else if (!strcmp (var, "dns-forw-port"))
348     {
349 pcg 1.34 #if ENABLE_DNS
350 pcg 1.40 conf.dns_forw_port = atoi (val);
351 pcg 1.28 #endif
352 pcg 1.40 }
353     else if (!strcmp (var, "dns-timeout-factor"))
354     {
355 pcg 1.38 #if ENABLE_DNS
356 pcg 1.40 conf.dns_timeout_factor = atof (val);
357 pcg 1.38 #endif
358 pcg 1.40 }
359     else if (!strcmp (var, "dns-send-interval"))
360     {
361 pcg 1.38 #if ENABLE_DNS
362 pcg 1.40 conf.dns_send_interval = atoi (val);
363 pcg 1.38 #endif
364 pcg 1.40 }
365     else if (!strcmp (var, "dns-overlap-factor"))
366     {
367 pcg 1.38 #if ENABLE_DNS
368 pcg 1.40 conf.dns_overlap_factor = atof (val);
369 pcg 1.38 #endif
370 pcg 1.40 }
371     else if (!strcmp (var, "dns-max-outstanding"))
372     {
373 pcg 1.38 #if ENABLE_DNS
374 pcg 1.40 conf.dns_max_outstanding = atoi (val);
375 pcg 1.38 #endif
376 pcg 1.40 }
377     else if (!strcmp (var, "http-proxy-host"))
378     {
379 pcg 1.12 #if ENABLE_HTTP_PROXY
380 pcg 1.40 free (conf.proxy_host), conf.proxy_host = strdup (val);
381 pcg 1.20 #endif
382 pcg 1.40 }
383     else if (!strcmp (var, "http-proxy-port"))
384     {
385 pcg 1.20 #if ENABLE_HTTP_PROXY
386 pcg 1.40 conf.proxy_port = atoi (val);
387 pcg 1.20 #endif
388 pcg 1.40 }
389     else if (!strcmp (var, "http-proxy-auth"))
390     {
391 pcg 1.20 #if ENABLE_HTTP_PROXY
392 pcg 1.40 conf.proxy_auth = (char *)base64_encode ((const u8 *)val, strlen (val));
393 pcg 1.12 #endif
394 pcg 1.40 }
395 pcg 1.1
396 pcg 1.40 /* node-specific, non-defaultable */
397     else if (node != &conf.default_node && !strcmp (var, "hostname"))
398     free (node->hostname), node->hostname = strdup (val);
399    
400     /* node-specific, defaultable */
401     else if (!strcmp (var, "udp-port"))
402     node->udp_port = atoi (val);
403     else if (!strcmp (var, "tcp-port"))
404     node->tcp_port = atoi (val);
405     else if (!strcmp (var, "dns-hostname"))
406     {
407 pcg 1.30 #if ENABLE_DNS
408 pcg 1.40 free (node->dns_hostname), node->dns_hostname = strdup (val);
409 pcg 1.34 #endif
410 pcg 1.40 }
411     else if (!strcmp (var, "dns-port"))
412     {
413 pcg 1.34 #if ENABLE_DNS
414 pcg 1.40 node->dns_port = atoi (val);
415 pcg 1.34 #endif
416 pcg 1.40 }
417     else if (!strcmp (var, "dns-domain"))
418     {
419 pcg 1.34 #if ENABLE_DNS
420 pcg 1.40 free (node->domain), node->domain = strdup (val);
421 pcg 1.28 #endif
422 pcg 1.40 }
423     else if (!strcmp (var, "if-up-data"))
424     free (node->if_up_data), node->if_up_data = strdup (val);
425     else if (!strcmp (var, "router-priority"))
426     node->routerprio = atoi (val);
427     else if (!strcmp (var, "max-retry"))
428     node->max_retry = atoi (val);
429     else if (!strcmp (var, "connect"))
430     {
431     if (!strcmp (val, "ondemand"))
432     node->connectmode = conf_node::C_ONDEMAND;
433     else if (!strcmp (val, "never"))
434     node->connectmode = conf_node::C_NEVER;
435     else if (!strcmp (val, "always"))
436     node->connectmode = conf_node::C_ALWAYS;
437     else if (!strcmp (val, "disabled"))
438     node->connectmode = conf_node::C_DISABLED;
439     else
440     return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled'. (ignored)");
441     }
442     else if (!strcmp (var, "inherit-tos"))
443     parse_bool (node->inherit_tos, "inherit-tos", true, false);
444     else if (!strcmp (var, "compress"))
445     parse_bool (node->compress, "compress", true, false);
446     // all these bool options really really cost a lot of executable size!
447     else if (!strcmp (var, "enable-tcp"))
448     {
449 pcg 1.11 #if ENABLE_TCP
450 pcg 1.40 u8 v; parse_bool (v, "enable-tcp" , PROT_TCPv4, 0); node->protocols = (node->protocols & ~PROT_TCPv4) | v;
451 pcg 1.13 #endif
452 pcg 1.40 }
453     else if (!strcmp (var, "enable-icmp"))
454     {
455 pcg 1.13 #if ENABLE_ICMP
456 pcg 1.40 u8 v; parse_bool (v, "enable-icmp" , PROT_ICMPv4, 0); node->protocols = (node->protocols & ~PROT_ICMPv4) | v;
457 pcg 1.11 #endif
458 pcg 1.40 }
459     else if (!strcmp (var, "enable-dns"))
460     {
461 pcg 1.24 #if ENABLE_DNS
462 pcg 1.40 u8 v; parse_bool (v, "enable-dns" , PROT_DNSv4, 0); node->protocols = (node->protocols & ~PROT_DNSv4) | v;
463 pcg 1.24 #endif
464 pcg 1.40 }
465     else if (!strcmp (var, "enable-udp"))
466     {
467     u8 v; parse_bool (v, "enable-udp" , PROT_UDPv4, 0); node->protocols = (node->protocols & ~PROT_UDPv4) | v;
468     }
469     else if (!strcmp (var, "enable-rawip"))
470     {
471     u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v;
472     }
473 pcg 1.42 else if (!strcmp (var, "allow-direct"))
474     node->allow_direct.push_back (strdup (val));
475     else if (!strcmp (var, "deny-direct"))
476     node->deny_direct.push_back (strdup (val));
477 pcg 1.43 else if (!strcmp (var, "max-ttl"))
478     node->max_ttl = atof (val);
479     else if (!strcmp (var, "max-queue"))
480 pcg 1.45 {
481     node->max_queue = atoi (val);
482    
483     if (node->max_queue < 1)
484     node->max_queue = 1;
485     }
486 pcg 1.40
487     // unknown or misplaced
488     else
489     return _("unknown configuration directive. (ignored)");
490    
491     return 0;
492     }
493    
494     void configuration_parser::parse_argv ()
495     {
496     for (int i = 0; i < argc; ++i)
497     {
498     char *v = argv [i];
499    
500     if (!*v)
501     continue;
502    
503     char *enode = v;
504    
505     while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
506     enode++;
507    
508     if (*enode != '.')
509     enode = 0;
510    
511     char *wnode = node == &conf.default_node
512     ? 0
513     : node->nodename;
514    
515     if ((!wnode && !enode)
516     || (wnode && enode && !strncmp (wnode, v, enode - v)))
517     {
518     const char *warn = parse_line (enode ? enode + 1 : v);
519    
520     if (warn)
521     slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
522    
523     *v = 0;
524     }
525     }
526     }
527    
528     configuration_parser::configuration_parser (configuration &conf,
529     bool need_keys,
530     int argc,
531     char **argv)
532     : conf (conf),need_keys (need_keys), argc (argc), argv (argv)
533     {
534     char *fname;
535     FILE *f;
536    
537     conf.clear ();
538    
539     asprintf (&fname, "%s/gvpe.conf", confbase);
540     f = fopen (fname, "r");
541    
542     if (f)
543     {
544     char line[16384];
545     int lineno = 0;
546     node = &conf.default_node;
547    
548     while (fgets (line, sizeof (line), f))
549     {
550     lineno++;
551    
552     const char *warn = parse_line (line);
553    
554     if (warn)
555     slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
556 pcg 1.1 }
557    
558     fclose (f);
559 pcg 1.40
560     parse_argv ();
561 pcg 1.1 }
562     else
563     {
564     slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
565 pcg 1.22 exit (EXIT_FAILURE);
566 pcg 1.1 }
567    
568     free (fname);
569    
570 pcg 1.40 fname = conf.config_filename (conf.prikeyfile, "hostkey");
571 pcg 1.1
572     f = fopen (fname, "r");
573     if (f)
574     {
575 pcg 1.40 conf.rsa_key = RSA_new ();
576 pcg 1.1
577 pcg 1.40 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL))
578 pcg 1.1 {
579     ERR_load_RSA_strings (); ERR_load_PEM_strings ();
580     slog (L_ERR, _("unable to read private rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
581 pcg 1.22 exit (EXIT_FAILURE);
582 pcg 1.1 }
583    
584 pcg 1.40 require (RSA_blinding_on (conf.rsa_key, 0));
585 pcg 1.1
586     fclose (f);
587     }
588     else
589     {
590     slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
591    
592     if (need_keys)
593 pcg 1.22 exit (EXIT_FAILURE);
594 pcg 1.1 }
595 pcg 1.22
596 pcg 1.23 if (need_keys && ::thisnode
597 pcg 1.40 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key)
598     if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
599     || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
600 pcg 1.22 {
601     slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
602     exit (EXIT_FAILURE);
603     }
604 pcg 1.1
605     free (fname);
606     }
607    
608     char *configuration::config_filename (const char *name, const char *dflt)
609     {
610     char *fname;
611    
612     asprintf (&fname, name ? name : dflt, ::thisnode);
613    
614     if (!ABSOLUTE_PATH (fname))
615     {
616     char *rname = fname;
617     asprintf (&fname, "%s/%s", confbase, rname);
618     free (rname);
619     }
620    
621     return fname;
622     }
623    
624     void
625     configuration::print ()
626     {
627     printf (_("\nConfiguration\n\n"));
628     printf (_("# of nodes: %d\n"), nodes.size ());
629     printf (_("this node: %s\n"), thisnode ? thisnode->nodename : "<unset>");
630     printf (_("MTU: %d\n"), mtu);
631     printf (_("rekeying interval: %d\n"), rekey);
632     printf (_("keepalive interval: %d\n"), keepalive);
633     printf (_("interface: %s\n"), ifname);
634     printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
635 pcg 1.15 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1);
636 pcg 1.1 printf ("\n");
637    
638     printf ("%4s %-17s %s %-8.8s %-10.10s %s\n",
639     _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port"));
640    
641     for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
642     (*i)->print ();
643    
644     printf ("\n");
645     }
646    
647 pcg 1.12 configuration::configuration ()
648     {
649 pcg 1.27 asprintf (&confbase, "%s/gvpe", CONFDIR);
650 pcg 1.26
651 pcg 1.12 init ();
652     }
653    
654     configuration::~configuration ()
655 pcg 1.1 {
656 pcg 1.12 cleanup ();
657 pcg 1.1 }
658 pcg 1.12
659 pcg 1.1