ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/gvpe/src/conf.C
(Generate patch)

Comparing gvpe/src/conf.C (file contents):
Revision 1.53 by root, Tue Feb 8 23:13:48 2011 UTC vs.
Revision 1.63 by root, Thu Jul 18 13:35:16 2013 UTC

1/* 1/*
2 conf.c -- configuration code 2 conf.C -- configuration code
3 Copyright (C) 2003-2008 Marc Lehmann <gvpe@schmorp.de> 3 Copyright (C) 2003-2008,2011 Marc Lehmann <gvpe@schmorp.de>
4 4
5 This file is part of GVPE. 5 This file is part of GVPE.
6 6
7 GVPE is free software; you can redistribute it and/or modify it 7 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 8 under the terms of the GNU General Public License as published by the
38#include <errno.h> 38#include <errno.h>
39#include <netdb.h> 39#include <netdb.h>
40#include <sys/stat.h> 40#include <sys/stat.h>
41#include <sys/types.h> 41#include <sys/types.h>
42#include <unistd.h> 42#include <unistd.h>
43#include <pwd.h>
43 44
44#include "netcompat.h" 45#include "netcompat.h"
45 46
46#include <openssl/err.h> 47#include <openssl/err.h>
47#include <openssl/pem.h> 48#include <openssl/pem.h>
103 104
104 if (match_list (deny_direct, other->nodename)) 105 if (match_list (deny_direct, other->nodename))
105 return false; 106 return false;
106 107
107 return true; 108 return true;
108}
109
110void
111conf_node::print ()
112{
113 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n",
114 id,
115 id >> 8, id & 0xff,
116 compress ? 'Y' : 'N',
117 connectmode == C_ONDEMAND ? "ondemand"
118 : connectmode == C_NEVER ? "never"
119 : connectmode == C_ALWAYS ? "always"
120 : connectmode == C_DISABLED ? "disabled"
121 : "",
122 nodename,
123 hostname ? hostname : "",
124 hostname ? ":" : "",
125 hostname ? udp_port : 0
126 );
127} 109}
128 110
129conf_node::~conf_node () 111conf_node::~conf_node ()
130{ 112{
131#if 0 113#if 0
170 default_node.if_up_data = strdup (""); 152 default_node.if_up_data = strdup ("");
171 153
172#if ENABLE_DNS 154#if ENABLE_DNS
173 default_node.dns_port = 0; // default is 0 == client 155 default_node.dns_port = 0; // default is 0 == client
174 156
157 dns_case_preserving = true;
175 dns_forw_host = strdup ("127.0.0.1"); 158 dns_forw_host = strdup ("127.0.0.1");
176 dns_forw_port = 53; 159 dns_forw_port = 53;
177 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR; 160 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR;
178 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL; 161 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
179 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR; 162 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
180 dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING; 163 dns_max_outstanding = DEFAULT_DNS_MAX_OUTSTANDING;
181#endif 164#endif
182 165
183 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); 166 pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
167 seed_dev = strdup ("/dev/urandom");
168 reseed = DEFAULT_RESEED;
184} 169}
185 170
186void 171void
187configuration::cleanup () 172configuration::cleanup ()
188{ 173{
189 if (rsa_key) 174 if (rsa_key)
190 RSA_free (rsa_key); 175 RSA_free (rsa_key);
191 176
192 rsa_key = 0; 177 rsa_key = 0;
193 178
179 free (seed_dev); seed_dev = 0;
194 free (pidfilename); pidfilename = 0; 180 free (pidfilename); pidfilename = 0;
195 free (ifname); ifname = 0; 181 free (ifname); ifname = 0;
196#if ENABLE_HTTP_PROXY 182#if ENABLE_HTTP_PROXY
197 free (proxy_host); proxy_host = 0; 183 free (proxy_host); proxy_host = 0;
198 free (proxy_auth); proxy_auth = 0; 184 free (proxy_auth); proxy_auth = 0;
199#endif 185#endif
200#if ENABLE_DNS 186#if ENABLE_DNS
201 free (dns_forw_host); dns_forw_host = 0; 187 free (dns_forw_host); dns_forw_host = 0;
202#endif 188#endif
189 free (change_root); change_root = 0;
203 free (script_if_up); script_if_up = 0; 190 free (script_if_up); script_if_up = 0;
204 free (script_node_up); script_node_up = 0; 191 free (script_node_up); script_node_up = 0;
205 free (script_node_change); script_node_change = 0; 192 free (script_node_change); script_node_change = 0;
206 free (script_node_down); script_node_down = 0; 193 free (script_node_down); script_node_down = 0;
207} 194}
215 nodes.clear (); 202 nodes.clear ();
216 203
217 cleanup (); 204 cleanup ();
218 init (); 205 init ();
219} 206}
207
208conf_node *
209configuration::find_node (const char *name)
210{
211 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i)
212 if (!strcmp ((*i)->nodename, name))
213 return *i;
214
215 return 0;
216}
217
218//static bool
219//is_true (const char *name)
220//{
221 //re
222//}
220 223
221#define parse_bool(target,name,trueval,falseval) do { \ 224#define parse_bool(target,name,trueval,falseval) do { \
222 if (!strcmp (val, "yes")) target = trueval; \ 225 if (!strcmp (val, "yes")) target = trueval; \
223 else if (!strcmp (val, "no")) target = falseval; \ 226 else if (!strcmp (val, "no")) target = falseval; \
224 else if (!strcmp (val, "true")) target = trueval; \ 227 else if (!strcmp (val, "true")) target = trueval; \
225 else if (!strcmp (val, "false")) target = falseval; \ 228 else if (!strcmp (val, "false")) target = falseval; \
226 else if (!strcmp (val, "on")) target = trueval; \ 229 else if (!strcmp (val, "on")) target = trueval; \
227 else if (!strcmp (val, "off")) target = falseval; \ 230 else if (!strcmp (val, "off")) target = falseval; \
228 else \ 231 else \
229 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed. (ignored)"); \ 232 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed, ignored"); \
230} while (0) 233} while (0)
231 234
232const char * 235const char *
233configuration_parser::parse_line (char *line) 236configuration_parser::parse_line (char *line)
234{ 237{
249 return 0; /* no tokens on this line */ 252 return 0; /* no tokens on this line */
250 253
251 if (var[0] == '#') 254 if (var[0] == '#')
252 return 0; /* comment: ignore */ 255 return 0; /* comment: ignore */
253 256
257 if (!strcmp (var, "global"))
258 {
259 node = &conf.default_node;
260 return 0;
261 }
262
254 char *val = strtok (NULL, "\t\n\r ="); 263 char *val = strtok (NULL, "\t\n\r =");
255 264
256 if (!val || val[0] == '#') 265 if (!val || val[0] == '#')
257 return _("no value given for variable. (ignored)"); 266 return _("no value given for variable, ignored");
258 267
259 if (!strcmp (var, "on")) 268 else if (!strcmp (var, "on"))
260 { 269 {
261 if (!::thisnode 270 if (::thisnode
262 || (val[0] == '!' && strcmp (val + 1, ::thisnode)) 271 && ((val[0] == '!' && strcmp (val + 1, ::thisnode))
263 || !strcmp (val, ::thisnode)) 272 || !strcmp (val, ::thisnode)))
264 return parse_line (strtok (NULL, "\n\r")); 273 return parse_line (strtok (NULL, "\n\r"));
265 else 274 }
266 return 0; 275
276 else if (!strcmp (var, "include"))
277 {
278 char *fname = conf.config_filename (val);
279 parse_file (fname);
280 free (fname);
267 } 281 }
268 282
269 // truly global 283 // truly global
270 if (!strcmp (var, "loglevel")) 284 else if (!strcmp (var, "loglevel"))
271 { 285 {
272 loglevel l = string_to_loglevel (val); 286 loglevel l = string_to_loglevel (val);
273 287
274 if (l == L_NONE) 288 if (l == L_NONE)
275 return _("unknown loglevel. (skipping)"); 289 return _("unknown loglevel, ignored");
276 } 290 }
277 else if (!strcmp (var, "ip-proto")) 291 else if (!strcmp (var, "ip-proto"))
278 conf.ip_proto = atoi (val); 292 conf.ip_proto = atoi (val);
279 else if (!strcmp (var, "icmp-type")) 293 else if (!strcmp (var, "icmp-type"))
280 { 294 {
281#if ENABLE_ICMP 295#if ENABLE_ICMP
282 conf.icmp_type = atoi (val); 296 conf.icmp_type = atoi (val);
283#endif 297#endif
284 } 298 }
299 else if (!strcmp (var, "chuser"))
300 {
301 struct passwd *pw = getpwnam (val);
302 if (!pw)
303 return _("user specified for chuser not found");
285 304
286 // per config 305 conf.change_uid = pw->pw_uid;
306 conf.change_gid = pw->pw_gid;
307 }
308 else if (!strcmp (var, "chuid"))
309 conf.change_uid = atoi (val);
310 else if (!strcmp (var, "chgid"))
311 conf.change_gid = atoi (val);
312 else if (!strcmp (var, "chroot"))
313 free (conf.change_root), conf.change_root = strdup (val);
314
315 // per node
287 else if (!strcmp (var, "node")) 316 else if (!strcmp (var, "node"))
288 { 317 {
289 parse_argv (); 318 node = conf.find_node (val);
290 319
320 if (!node)
321 {
291 conf.default_node.id++; 322 conf.default_node.id++;
292 node = new conf_node (conf.default_node); 323 node = new conf_node (conf.default_node);
293 conf.nodes.push_back (node); 324 conf.nodes.push_back (node);
294 node->nodename = strdup (val); 325 node->nodename = strdup (val);
295
296 {
297 char *fname;
298 FILE *f;
299
300 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
301
302 f = fopen (fname, "r");
303 if (f)
304 {
305 node->rsa_key = RSA_new ();
306
307 if (!PEM_read_RSAPublicKey(f, &node->rsa_key, NULL, NULL))
308 {
309 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
310 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
311 exit (EXIT_FAILURE);
312 }
313
314 require (RSA_blinding_on (node->rsa_key, 0));
315
316 fclose (f);
317 } 326 }
318 else
319 {
320 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
321
322 if (need_keys)
323 exit (EXIT_FAILURE);
324 }
325
326 free (fname);
327 }
328
329 if (::thisnode && !strcmp (node->nodename, ::thisnode))
330 conf.thisnode = node;
331 } 327 }
332 else if (!strcmp (var, "private-key")) 328 else if (!strcmp (var, "private-key"))
333 free (conf.prikeyfile), conf.prikeyfile = strdup (val); 329 free (conf.prikeyfile), conf.prikeyfile = strdup (val);
334 else if (!strcmp (var, "ifpersist")) 330 else if (!strcmp (var, "ifpersist"))
335 parse_bool (conf.ifpersist, "ifpersist", true, false); 331 parse_bool (conf.ifpersist, "ifpersist", true, false);
341 conf.keepalive = atoi (val); 337 conf.keepalive = atoi (val);
342 else if (!strcmp (var, "mtu")) 338 else if (!strcmp (var, "mtu"))
343 conf.mtu = atoi (val); 339 conf.mtu = atoi (val);
344 else if (!strcmp (var, "nfmark")) 340 else if (!strcmp (var, "nfmark"))
345 conf.nfmark = atoi (val); 341 conf.nfmark = atoi (val);
342 else if (!strcmp (var, "seed-device"))
343 free (conf.seed_dev), conf.seed_dev = strdup (val);
344 else if (!strcmp (var, "seed-interval"))
345 conf.reseed = atoi (val);
346 else if (!strcmp (var, "if-up")) 346 else if (!strcmp (var, "if-up"))
347 free (conf.script_if_up), conf.script_if_up = strdup (val); 347 free (conf.script_if_up), conf.script_if_up = strdup (val);
348 else if (!strcmp (var, "node-up")) 348 else if (!strcmp (var, "node-up"))
349 free (conf.script_node_up), conf.script_node_up = strdup (val); 349 free (conf.script_node_up), conf.script_node_up = strdup (val);
350 else if (!strcmp (var, "node-change")) 350 else if (!strcmp (var, "node-change"))
387 { 387 {
388#if ENABLE_DNS 388#if ENABLE_DNS
389 conf.dns_max_outstanding = atoi (val); 389 conf.dns_max_outstanding = atoi (val);
390#endif 390#endif
391 } 391 }
392 else if (!strcmp (var, "dns-case-preserving"))
393 {
394#if ENABLE_DNS
395 parse_bool (conf.dns_case_preserving, "dns-case-preserving", true, false);
396#endif
397 }
392 else if (!strcmp (var, "http-proxy-host")) 398 else if (!strcmp (var, "http-proxy-host"))
393 { 399 {
394#if ENABLE_HTTP_PROXY 400#if ENABLE_HTTP_PROXY
395 free (conf.proxy_host), conf.proxy_host = strdup (val); 401 free (conf.proxy_host), conf.proxy_host = strdup (val);
396#endif 402#endif
450 else if (!strcmp (val, "always")) 456 else if (!strcmp (val, "always"))
451 node->connectmode = conf_node::C_ALWAYS; 457 node->connectmode = conf_node::C_ALWAYS;
452 else if (!strcmp (val, "disabled")) 458 else if (!strcmp (val, "disabled"))
453 node->connectmode = conf_node::C_DISABLED; 459 node->connectmode = conf_node::C_DISABLED;
454 else 460 else
455 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled'. (ignored)"); 461 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', ignored");
456 } 462 }
457 else if (!strcmp (var, "inherit-tos")) 463 else if (!strcmp (var, "inherit-tos"))
458 parse_bool (node->inherit_tos, "inherit-tos", true, false); 464 parse_bool (node->inherit_tos, "inherit-tos", true, false);
459 else if (!strcmp (var, "compress")) 465 else if (!strcmp (var, "compress"))
460 parse_bool (node->compress, "compress", true, false); 466 parse_bool (node->compress, "compress", true, false);
494 else if (!strcmp (var, "max-queue")) 500 else if (!strcmp (var, "max-queue"))
495 node->max_queue = atoi (val); 501 node->max_queue = atoi (val);
496 502
497 // unknown or misplaced 503 // unknown or misplaced
498 else 504 else
499 return _("unknown configuration directive. (ignored)"); 505 return _("unknown configuration directive - ignored");
500 506
501 return 0; 507 return 0;
502} 508}
503 509
504void 510void
516 connectmode = C_ALWAYS; 522 connectmode = C_ALWAYS;
517 } 523 }
518} 524}
519 525
520void 526void
521configuration_parser::parse_argv () 527configuration_parser::parse_file (const char *fname)
522{ 528{
523 for (int i = 0; i < argc; ++i) 529 if (FILE *f = fopen (fname, "r"))
524 { 530 {
525 char *v = argv [i]; 531 char line [2048];
532 int lineno = 0;
526 533
527 if (!*v) 534 while (fgets (line, sizeof (line), f))
528 continue;
529
530 char *enode = v;
531
532 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
533 enode++;
534
535 if (*enode != '.')
536 enode = 0;
537
538 char *wnode = node == &conf.default_node
539 ? 0
540 : node->nodename;
541
542 if ((!wnode && !enode)
543 || (wnode && enode && !strncmp (wnode, v, enode - v)))
544 { 535 {
536 lineno++;
537
545 const char *warn = parse_line (enode ? enode + 1 : v); 538 const char *warn = parse_line (line);
546 539
547 if (warn) 540 if (warn)
548 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v); 541 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
549
550 *v = 0;
551 } 542 }
543
544 fclose (f);
545 }
546 else
547 {
548 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
549 exit (EXIT_FAILURE);
552 } 550 }
553} 551}
554 552
555configuration_parser::configuration_parser (configuration &conf, 553configuration_parser::configuration_parser (configuration &conf,
556 bool need_keys, 554 bool need_keys,
557 int argc, 555 int argc,
558 char **argv) 556 char **argv)
559: conf (conf),need_keys (need_keys), argc (argc), argv (argv) 557: conf (conf), need_keys (need_keys), argc (argc), argv (argv)
560{ 558{
561 char *fname; 559 char *fname;
562 FILE *f;
563 560
564 conf.clear (); 561 conf.clear ();
562 node = &conf.default_node;
565 563
566 asprintf (&fname, "%s/gvpe.conf", confbase); 564 asprintf (&fname, "%s/gvpe.conf", confbase);
567 f = fopen (fname, "r"); 565 parse_file (fname);
568
569 if (f)
570 {
571 char line[16384];
572 int lineno = 0;
573 node = &conf.default_node;
574
575 while (fgets (line, sizeof (line), f))
576 {
577 lineno++;
578
579 const char *warn = parse_line (line);
580
581 if (warn)
582 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
583 }
584
585 fclose (f);
586
587 parse_argv ();
588 }
589 else
590 {
591 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
592 exit (EXIT_FAILURE);
593 }
594
595 free (fname); 566 free (fname);
596 567
597 fname = conf.config_filename (conf.prikeyfile, "hostkey"); 568 fname = conf.config_filename (conf.prikeyfile, "hostkey");
598 569
599 f = fopen (fname, "r"); 570 if (FILE *f = fopen (fname, "r"))
600 if (f)
601 { 571 {
602 conf.rsa_key = RSA_new (); 572 conf.rsa_key = RSA_new ();
603 573
604 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL)) 574 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL))
605 { 575 {
612 582
613 fclose (f); 583 fclose (f);
614 } 584 }
615 else 585 else
616 { 586 {
617 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
618
619 if (need_keys) 587 if (need_keys)
588 {
589 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
620 exit (EXIT_FAILURE); 590 exit (EXIT_FAILURE);
621 }
622
623 if (need_keys && ::thisnode
624 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key)
625 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
626 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
627 {
628 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
629 exit (EXIT_FAILURE);
630 } 591 }
592 }
631 593
632 free (fname); 594 free (fname);
633 595
596 fname = conf.config_filename (conf.pidfilename);
597 free (conf.pidfilename); conf.pidfilename = fname;
598
634 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i) 599 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i)
600 {
601 conf_node *node = *i;
602 char *fname;
603 FILE *f;
604
605 asprintf (&fname, "%s/pubkey/%s", confbase, node->nodename);
606
607 f = fopen (fname, "r");
608 if (f)
609 {
610 node->rsa_key = RSA_new ();
611
612 if (!PEM_read_RSAPublicKey (f, &node->rsa_key, NULL, NULL))
613 {
614 ERR_load_RSA_strings (); ERR_load_PEM_strings ();
615 slog (L_ERR, _("unable to open public rsa key file '%s': %s"), fname, ERR_error_string (ERR_get_error (), 0));
616 exit (EXIT_FAILURE);
617 }
618
619 require (RSA_blinding_on (node->rsa_key, 0));
620
621 fclose (f);
622 }
623 else
624 {
625 slog (need_keys ? L_ERR : L_NOTICE, _("unable to read public rsa key file '%s': %s"), fname, strerror (errno));
626
627 if (need_keys)
628 exit (EXIT_FAILURE);
629 }
630
631 free (fname);
632
635 (*i)->finalise (); 633 (*i)->finalise ();
634 }
635
636 if (::thisnode)
637 {
638 conf.thisnode = conf.find_node (::thisnode);
639
640 if (need_keys)
641 {
642 if (!conf.thisnode)
643 {
644 slog (L_NOTICE, _("local node ('%s') not found in config file, aborting."), ::thisnode);
645 exit (EXIT_FAILURE);
646 }
647
648 if (conf.rsa_key && conf.thisnode->rsa_key)
649 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
650 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
651 {
652 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
653 exit (EXIT_FAILURE);
654 }
655 }
656 }
657
658 parse_argv ();
659}
660
661void
662configuration_parser::parse_argv ()
663{
664 for (int i = 0; i < argc; ++i)
665 {
666 char *v = argv [i];
667
668 if (!*v)
669 continue;
670
671 char *enode = v;
672
673 while (*enode != '.' && *enode > ' ' && *enode != '=' && *enode)
674 enode++;
675
676 if (*enode != '.')
677 enode = 0;
678
679 if (enode)
680 {
681 char *val = strdup (v);
682 val [enode - v] = 0;
683 node = conf.find_node (val);
684 free (val);
685
686 if (!node)
687 {
688 slog (L_WARN, _("command line option '%s' refers to unknown node, ignoring."), v);
689 continue;
690 }
691 }
692 else
693 node = &conf.default_node;
694
695 const char *warn = parse_line (enode ? enode + 1 : v);
696
697 if (warn)
698 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
699 }
636} 700}
637 701
638char * 702char *
639configuration::config_filename (const char *name, const char *dflt) 703configuration::config_filename (const char *name, const char *dflt)
640{ 704{
641 char *fname; 705 char *fname;
642 706
643 asprintf (&fname, name ? name : dflt, ::thisnode); 707 asprintf (&fname, name ? name : dflt, ::thisnode ? ::thisnode : "<unset>");
644 708
645 if (!ABSOLUTE_PATH (fname)) 709 if (!ABSOLUTE_PATH (fname))
646 { 710 {
647 char *rname = fname; 711 char *rname = fname;
648 asprintf (&fname, "%s/%s", confbase, rname); 712 asprintf (&fname, "%s/%s", confbase, rname);
649 free (rname); 713 free (rname);
650 } 714 }
651 715
652 return fname; 716 return fname;
717}
718
719void
720conf_node::print ()
721{
722 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %02x %s%s%d\n",
723 id,
724 id >> 8, id & 0xff,
725 compress ? 'Y' : 'N',
726 connectmode == C_ONDEMAND ? "ondemand"
727 : connectmode == C_NEVER ? "never"
728 : connectmode == C_ALWAYS ? "always"
729 : connectmode == C_DISABLED ? "disabled"
730 : "",
731 nodename,
732 protocols,
733 hostname ? hostname : "",
734 hostname ? ":" : "",
735 hostname ? udp_port : 0
736 );
653} 737}
654 738
655void 739void
656configuration::print () 740configuration::print ()
657{ 741{
664 printf (_("interface: %s\n"), ifname); 748 printf (_("interface: %s\n"), ifname);
665 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>"); 749 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
666 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1); 750 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1);
667 printf ("\n"); 751 printf ("\n");
668 752
669 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n", 753 printf ("%4s %-17s %s %-8.8s %-10.10s %04s %s\n",
670 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port")); 754 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Prot"), _("Host:Port"));
671 755
672 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i) 756 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
673 (*i)->print (); 757 (*i)->print ();
674 758
675 printf ("\n"); 759 printf ("\n");

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines