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.40 by pcg, Mon Mar 28 20:39:18 2005 UTC vs.
Revision 1.58 by root, Tue Jan 17 21:38:10 2012 UTC

1/* 1/*
2 conf.c -- configuration code 2 conf.C -- configuration code
3 Copyright (C) 2003-2005 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 7 GVPE is free software; you can redistribute it and/or modify it
8 it under the terms of the GNU General Public License as published by 8 under the terms of the GNU General Public License as published by the
9 the Free Software Foundation; either version 2 of the License, or 9 Free Software Foundation; either version 3 of the License, or (at your
10 (at your option) any later version. 10 option) any later version.
11 11
12 This program is distributed in the hope that it will be useful, 12 This program is distributed in the hope that it will be useful, but
13 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 GNU General Public License for more details. 15 Public License for more details.
16 16
17 You should have received a copy of the GNU General Public License 17 You should have received a copy of the GNU General Public License along
18 along with gvpe; if not, write to the Free Software 18 with this program; if not, see <http://www.gnu.org/licenses/>.
19 Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 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.
20*/ 30*/
21 31
22#include "config.h" 32#include "config.h"
23 33
24#include <cstdio> 34#include <cstdio>
47char *thisnode; 57char *thisnode;
48char *identname; 58char *identname;
49 59
50struct configuration conf; 60struct configuration conf;
51 61
62u8
52u8 best_protocol (u8 protset) 63best_protocol (u8 protset)
53{ 64{
54 if (protset & PROT_IPv4 ) return PROT_IPv4; 65 if (protset & PROT_IPv4 ) return PROT_IPv4;
55 if (protset & PROT_ICMPv4) return PROT_ICMPv4; 66 if (protset & PROT_ICMPv4) return PROT_ICMPv4;
56 if (protset & PROT_UDPv4 ) return PROT_UDPv4; 67 if (protset & PROT_UDPv4 ) return PROT_UDPv4;
57 if (protset & PROT_TCPv4 ) return PROT_TCPv4; 68 if (protset & PROT_TCPv4 ) return PROT_TCPv4;
58 if (protset & PROT_DNSv4 ) return PROT_DNSv4; 69 if (protset & PROT_DNSv4 ) return PROT_DNSv4;
59 70
60 return 0; 71 return 0;
61} 72}
62 73
74const char *
63const char *strprotocol (u8 protocol) 75strprotocol (u8 protocol)
64{ 76{
65 if (protocol & PROT_IPv4 ) return "rawip"; 77 if (protocol & PROT_IPv4 ) return "rawip";
66 if (protocol & PROT_ICMPv4) return "icmp"; 78 if (protocol & PROT_ICMPv4) return "icmp";
67 if (protocol & PROT_UDPv4 ) return "udp"; 79 if (protocol & PROT_UDPv4 ) return "udp";
68 if (protocol & PROT_TCPv4 ) return "tcp"; 80 if (protocol & PROT_TCPv4 ) return "tcp";
69 if (protocol & PROT_DNSv4 ) return "dns"; 81 if (protocol & PROT_DNSv4 ) return "dns";
70 82
71 return "<unknown>"; 83 return "<unknown>";
72} 84}
73 85
74void 86static bool
75conf_node::print () 87match_list (const vector<const char *> &list, const char *str)
76{ 88{
77 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n", 89 for (vector<const char *>::const_iterator i = list.end (); i-- > list.begin (); )
78 id, 90 if ((*i)[0] == '*' && !(*i)[1])
79 id >> 8, id & 0xff, 91 return true;
80 compress ? 'Y' : 'N', 92 else if (!strcmp (*i, str))
81 connectmode == C_ONDEMAND ? "ondemand" : 93 return true;
82 connectmode == C_NEVER ? "never" : 94
83 connectmode == C_ALWAYS ? "always" : "", 95 return false;
84 nodename, 96}
85 hostname ? hostname : "", 97
86 hostname ? ":" : "", 98bool
87 hostname ? udp_port : 0 99conf_node::may_direct (struct conf_node *other)
88 ); 100{
101 if (match_list (allow_direct, other->nodename))
102 return true;
103
104 if (match_list (deny_direct, other->nodename))
105 return false;
106
107 return true;
89} 108}
90 109
91conf_node::~conf_node () 110conf_node::~conf_node ()
92{ 111{
93#if 0 112#if 0
104 free (dns_hostname); 123 free (dns_hostname);
105#endif 124#endif
106#endif 125#endif
107} 126}
108 127
128void
109void configuration::init () 129configuration::init ()
110{ 130{
111 memset (this, 0, sizeof (*this)); 131 memset (this, 0, sizeof (*this));
112 132
113 mtu = DEFAULT_MTU; 133 mtu = DEFAULT_MTU;
134 nfmark = 0;
114 rekey = DEFAULT_REKEY; 135 rekey = DEFAULT_REKEY;
115 keepalive = DEFAULT_KEEPALIVE; 136 keepalive = DEFAULT_KEEPALIVE;
116 llevel = L_INFO; 137 llevel = L_INFO;
117 ip_proto = IPPROTO_GRE; 138 ip_proto = IPPROTO_GRE;
118#if ENABLE_ICMP 139#if ENABLE_ICMP
123 default_node.tcp_port = DEFAULT_UDPPORT; // ehrm 144 default_node.tcp_port = DEFAULT_UDPPORT; // ehrm
124 default_node.connectmode = conf_node::C_ALWAYS; 145 default_node.connectmode = conf_node::C_ALWAYS;
125 default_node.compress = true; 146 default_node.compress = true;
126 default_node.protocols = 0; 147 default_node.protocols = 0;
127 default_node.max_retry = DEFAULT_MAX_RETRY; 148 default_node.max_retry = DEFAULT_MAX_RETRY;
149 default_node.max_ttl = DEFAULT_MAX_TTL;
150 default_node.max_queue = DEFAULT_MAX_QUEUE;
128 default_node.if_up_data = strdup (""); 151 default_node.if_up_data = strdup ("");
129 152
130#if ENABLE_DNS 153#if ENABLE_DNS
131 default_node.dns_port = 0; // default is 0 == client 154 default_node.dns_port = 0; // default is 0 == client
132 155
156 dns_case_preserving = true;
133 dns_forw_host = strdup ("127.0.0.1"); 157 dns_forw_host = strdup ("127.0.0.1");
134 dns_forw_port = 53; 158 dns_forw_port = 53;
135 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR; 159 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR;
136 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL; 160 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
137 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR; 161 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
139#endif 163#endif
140 164
141 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); 165 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
142} 166}
143 167
168void
144void configuration::cleanup() 169configuration::cleanup ()
145{ 170{
146 if (rsa_key) 171 if (rsa_key)
147 RSA_free (rsa_key); 172 RSA_free (rsa_key);
148 173
149 rsa_key = 0; 174 rsa_key = 0;
150 175
151 free (pidfilename); pidfilename = 0; 176 free (pidfilename); pidfilename = 0;
152 free (ifname); ifname = 0; 177 free (ifname); ifname = 0;
153#if ENABLE_HTTP_PROXY 178#if ENABLE_HTTP_PROXY
154 free (proxy_host); proxy_host = 0; 179 free (proxy_host); proxy_host = 0;
155 free (proxy_auth); proxy_auth = 0; 180 free (proxy_auth); proxy_auth = 0;
156#endif 181#endif
157#if ENABLE_DNS 182#if ENABLE_DNS
158 free (dns_forw_host); dns_forw_host = 0; 183 free (dns_forw_host); dns_forw_host = 0;
159#endif 184#endif
185 free (script_if_up); script_if_up = 0;
186 free (script_node_up); script_node_up = 0;
187 free (script_node_change); script_node_change = 0;
188 free (script_node_down); script_node_down = 0;
160} 189}
161 190
162void 191void
163configuration::clear () 192configuration::clear ()
164{ 193{
168 nodes.clear (); 197 nodes.clear ();
169 198
170 cleanup (); 199 cleanup ();
171 init (); 200 init ();
172} 201}
202
203//static bool
204//is_true (const char *name)
205//{
206 //re
207//}
173 208
174#define parse_bool(target,name,trueval,falseval) do { \ 209#define parse_bool(target,name,trueval,falseval) do { \
175 if (!strcmp (val, "yes")) target = trueval; \ 210 if (!strcmp (val, "yes")) target = trueval; \
176 else if (!strcmp (val, "no")) target = falseval; \ 211 else if (!strcmp (val, "no")) target = falseval; \
177 else if (!strcmp (val, "true")) target = trueval; \ 212 else if (!strcmp (val, "true")) target = trueval; \
178 else if (!strcmp (val, "false")) target = falseval; \ 213 else if (!strcmp (val, "false")) target = falseval; \
179 else if (!strcmp (val, "on")) target = trueval; \ 214 else if (!strcmp (val, "on")) target = trueval; \
180 else if (!strcmp (val, "off")) target = falseval; \ 215 else if (!strcmp (val, "off")) target = falseval; \
181 else \ 216 else \
182 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed. (ignored)"); \ 217 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed, ignored"); \
183} while (0) 218} while (0)
184 219
185const char * 220const char *
186configuration_parser::parse_line (char *line) 221configuration_parser::parse_line (char *line)
187{ 222{
205 return 0; /* comment: ignore */ 240 return 0; /* comment: ignore */
206 241
207 char *val = strtok (NULL, "\t\n\r ="); 242 char *val = strtok (NULL, "\t\n\r =");
208 243
209 if (!val || val[0] == '#') 244 if (!val || val[0] == '#')
210 return _("no value given for variable. (ignored)"); 245 return _("no value given for variable, ignored");
211 246
212 if (!strcmp (var, "on")) 247 else if (!strcmp (var, "on"))
213 { 248 {
214 if (!::thisnode 249 if (::thisnode
215 || (val[0] == '!' && strcmp (val + 1, ::thisnode)) 250 && ((val[0] == '!' && strcmp (val + 1, ::thisnode))
216 || !strcmp (val, ::thisnode)) 251 || !strcmp (val, ::thisnode)))
217 return parse_line (strtok (NULL, "\n\r")); 252 return parse_line (strtok (NULL, "\n\r"));
218 else 253 }
219 return 0; 254
255 else if (!strcmp (var, "include"))
256 {
257 char *fname = conf.config_filename (val);
258 parse_file (fname);
259 free (fname);
220 } 260 }
221 261
222 // truly global 262 // truly global
223 if (!strcmp (var, "loglevel")) 263 else if (!strcmp (var, "loglevel"))
224 { 264 {
225 loglevel l = string_to_loglevel (val); 265 loglevel l = string_to_loglevel (val);
226 266
227 if (l == L_NONE) 267 if (l == L_NONE)
228 return _("unknown loglevel. (skipping)"); 268 return _("unknown loglevel, ignored");
229 } 269 }
230 else if (!strcmp (var, "ip-proto")) 270 else if (!strcmp (var, "ip-proto"))
231 conf.ip_proto = atoi (val); 271 conf.ip_proto = atoi (val);
232 else if (!strcmp (var, "icmp-type")) 272 else if (!strcmp (var, "icmp-type"))
233 { 273 {
292 conf.rekey = atoi (val); 332 conf.rekey = atoi (val);
293 else if (!strcmp (var, "keepalive")) 333 else if (!strcmp (var, "keepalive"))
294 conf.keepalive = atoi (val); 334 conf.keepalive = atoi (val);
295 else if (!strcmp (var, "mtu")) 335 else if (!strcmp (var, "mtu"))
296 conf.mtu = atoi (val); 336 conf.mtu = atoi (val);
337 else if (!strcmp (var, "nfmark"))
338 conf.nfmark = atoi (val);
297 else if (!strcmp (var, "if-up")) 339 else if (!strcmp (var, "if-up"))
298 free (conf.script_if_up), conf.script_if_up = strdup (val); 340 free (conf.script_if_up), conf.script_if_up = strdup (val);
299 else if (!strcmp (var, "node-up")) 341 else if (!strcmp (var, "node-up"))
300 free (conf.script_node_up), conf.script_node_up = strdup (val); 342 free (conf.script_node_up), conf.script_node_up = strdup (val);
343 else if (!strcmp (var, "node-change"))
344 free (conf.script_node_change), conf.script_node_change = strdup (val);
301 else if (!strcmp (var, "node-down")) 345 else if (!strcmp (var, "node-down"))
302 free (conf.script_node_down), conf.script_node_down = strdup (val); 346 free (conf.script_node_down), conf.script_node_down = strdup (val);
303 else if (!strcmp (var, "pid-file")) 347 else if (!strcmp (var, "pid-file"))
304 free (conf.pidfilename), conf.pidfilename = strdup (val); 348 free (conf.pidfilename), conf.pidfilename = strdup (val);
305 else if (!strcmp (var, "dns-forw-host")) 349 else if (!strcmp (var, "dns-forw-host"))
334 } 378 }
335 else if (!strcmp (var, "dns-max-outstanding")) 379 else if (!strcmp (var, "dns-max-outstanding"))
336 { 380 {
337#if ENABLE_DNS 381#if ENABLE_DNS
338 conf.dns_max_outstanding = atoi (val); 382 conf.dns_max_outstanding = atoi (val);
383#endif
384 }
385 else if (!strcmp (var, "dns-case-preserving"))
386 {
387#if ENABLE_DNS
388 parse_bool (conf.dns_case_preserving, "dns-case-preserving", true, false);
339#endif 389#endif
340 } 390 }
341 else if (!strcmp (var, "http-proxy-host")) 391 else if (!strcmp (var, "http-proxy-host"))
342 { 392 {
343#if ENABLE_HTTP_PROXY 393#if ENABLE_HTTP_PROXY
399 else if (!strcmp (val, "always")) 449 else if (!strcmp (val, "always"))
400 node->connectmode = conf_node::C_ALWAYS; 450 node->connectmode = conf_node::C_ALWAYS;
401 else if (!strcmp (val, "disabled")) 451 else if (!strcmp (val, "disabled"))
402 node->connectmode = conf_node::C_DISABLED; 452 node->connectmode = conf_node::C_DISABLED;
403 else 453 else
404 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled'. (ignored)"); 454 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', ignored");
405 } 455 }
406 else if (!strcmp (var, "inherit-tos")) 456 else if (!strcmp (var, "inherit-tos"))
407 parse_bool (node->inherit_tos, "inherit-tos", true, false); 457 parse_bool (node->inherit_tos, "inherit-tos", true, false);
408 else if (!strcmp (var, "compress")) 458 else if (!strcmp (var, "compress"))
409 parse_bool (node->compress, "compress", true, false); 459 parse_bool (node->compress, "compress", true, false);
432 } 482 }
433 else if (!strcmp (var, "enable-rawip")) 483 else if (!strcmp (var, "enable-rawip"))
434 { 484 {
435 u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v; 485 u8 v; parse_bool (v, "enable-rawip", PROT_IPv4, 0); node->protocols = (node->protocols & ~PROT_IPv4 ) | v;
436 } 486 }
487 else if (!strcmp (var, "allow-direct"))
488 node->allow_direct.push_back (strdup (val));
489 else if (!strcmp (var, "deny-direct"))
490 node->deny_direct.push_back (strdup (val));
491 else if (!strcmp (var, "max-ttl"))
492 node->max_ttl = atof (val);
493 else if (!strcmp (var, "max-queue"))
494 node->max_queue = atoi (val);
437 495
438 // unknown or misplaced 496 // unknown or misplaced
439 else 497 else
440 return _("unknown configuration directive. (ignored)"); 498 return _("unknown configuration directive - ignored");
441 499
442 return 0; 500 return 0;
443} 501}
444 502
503void
504conf_node::finalise ()
505{
506 if (max_queue < 1)
507 {
508 slog (L_WARN, _("%s: max-queue value invalid, setting it to 1."), nodename);
509 max_queue = 1;
510 }
511
512 if (routerprio > 1 && (connectmode != C_ALWAYS && connectmode != C_DISABLED))
513 {
514 //slog (L_WARN, _("%s: has non-zero router-priority but either 'never' or 'ondemand' as connectmode, setting it to 'always'."), nodename);
515 connectmode = C_ALWAYS;
516 }
517}
518
519void
445void configuration_parser::parse_argv () 520configuration_parser::parse_argv ()
446{ 521{
447 for (int i = 0; i < argc; ++i) 522 for (int i = 0; i < argc; ++i)
448 { 523 {
449 char *v = argv [i]; 524 char *v = argv [i];
450 525
471 if (warn) 546 if (warn)
472 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v); 547 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
473 548
474 *v = 0; 549 *v = 0;
475 } 550 }
551 }
552}
553
554void
555configuration_parser::parse_file (const char *fname)
556{
557 if (FILE *f = fopen (fname, "r"))
558 {
559 char line [2048];
560 int lineno = 0;
561
562 while (fgets (line, sizeof (line), f))
563 {
564 lineno++;
565
566 const char *warn = parse_line (line);
567
568 if (warn)
569 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
570 }
571
572 fclose (f);
573
574 parse_argv ();
575 }
576 else
577 {
578 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
579 exit (EXIT_FAILURE);
476 } 580 }
477} 581}
478 582
479configuration_parser::configuration_parser (configuration &conf, 583configuration_parser::configuration_parser (configuration &conf,
480 bool need_keys, 584 bool need_keys,
481 int argc, 585 int argc,
482 char **argv) 586 char **argv)
483: conf (conf),need_keys (need_keys), argc (argc), argv (argv) 587: conf (conf),need_keys (need_keys), argc (argc), argv (argv)
484{ 588{
485 char *fname; 589 char *fname;
486 FILE *f;
487 590
488 conf.clear (); 591 conf.clear ();
592 node = &conf.default_node;
489 593
490 asprintf (&fname, "%s/gvpe.conf", confbase); 594 asprintf (&fname, "%s/gvpe.conf", confbase);
491 f = fopen (fname, "r"); 595 parse_file (fname);
492
493 if (f)
494 {
495 char line[16384];
496 int lineno = 0;
497 node = &conf.default_node;
498
499 while (fgets (line, sizeof (line), f))
500 {
501 lineno++;
502
503 const char *warn = parse_line (line);
504
505 if (warn)
506 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
507 }
508
509 fclose (f);
510
511 parse_argv ();
512 }
513 else
514 {
515 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
516 exit (EXIT_FAILURE);
517 }
518
519 free (fname); 596 free (fname);
520 597
521 fname = conf.config_filename (conf.prikeyfile, "hostkey"); 598 fname = conf.config_filename (conf.prikeyfile, "hostkey");
522 599
523 f = fopen (fname, "r"); 600 if (FILE *f = fopen (fname, "r"))
524 if (f)
525 { 601 {
526 conf.rsa_key = RSA_new (); 602 conf.rsa_key = RSA_new ();
527 603
528 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL)) 604 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL))
529 { 605 {
541 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno)); 617 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
542 618
543 if (need_keys) 619 if (need_keys)
544 exit (EXIT_FAILURE); 620 exit (EXIT_FAILURE);
545 } 621 }
622
623 free (fname);
546 624
547 if (need_keys && ::thisnode 625 if (need_keys && ::thisnode
548 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key) 626 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key)
549 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0 627 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
550 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0) 628 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
551 { 629 {
552 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode); 630 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
553 exit (EXIT_FAILURE); 631 exit (EXIT_FAILURE);
554 } 632 }
555 633
556 free (fname); 634 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i)
635 (*i)->finalise ();
557} 636}
558 637
638char *
559char *configuration::config_filename (const char *name, const char *dflt) 639configuration::config_filename (const char *name, const char *dflt)
560{ 640{
561 char *fname; 641 char *fname;
562 642
563 asprintf (&fname, name ? name : dflt, ::thisnode); 643 asprintf (&fname, name ? name : dflt, ::thisnode);
564 644
568 asprintf (&fname, "%s/%s", confbase, rname); 648 asprintf (&fname, "%s/%s", confbase, rname);
569 free (rname); 649 free (rname);
570 } 650 }
571 651
572 return fname; 652 return fname;
653}
654
655void
656conf_node::print ()
657{
658 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %02x %s%s%d\n",
659 id,
660 id >> 8, id & 0xff,
661 compress ? 'Y' : 'N',
662 connectmode == C_ONDEMAND ? "ondemand"
663 : connectmode == C_NEVER ? "never"
664 : connectmode == C_ALWAYS ? "always"
665 : connectmode == C_DISABLED ? "disabled"
666 : "",
667 nodename,
668 protocols,
669 hostname ? hostname : "",
670 hostname ? ":" : "",
671 hostname ? udp_port : 0
672 );
573} 673}
574 674
575void 675void
576configuration::print () 676configuration::print ()
577{ 677{
584 printf (_("interface: %s\n"), ifname); 684 printf (_("interface: %s\n"), ifname);
585 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>"); 685 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
586 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1); 686 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1);
587 printf ("\n"); 687 printf ("\n");
588 688
589 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n", 689 printf ("%4s %-17s %s %-8.8s %-10.10s %04s %s\n",
590 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port")); 690 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Prot"), _("Host:Port"));
591 691
592 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i) 692 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
593 (*i)->print (); 693 (*i)->print ();
594 694
595 printf ("\n"); 695 printf ("\n");
605configuration::~configuration () 705configuration::~configuration ()
606{ 706{
607 cleanup (); 707 cleanup ();
608} 708}
609 709
610

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines