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.43 by pcg, Thu Aug 7 16:34:21 2008 UTC vs.
Revision 1.59 by root, Tue Dec 4 10:29:43 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. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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>
28#include <errno.h> 38#include <errno.h>
29#include <netdb.h> 39#include <netdb.h>
30#include <sys/stat.h> 40#include <sys/stat.h>
31#include <sys/types.h> 41#include <sys/types.h>
32#include <unistd.h> 42#include <unistd.h>
43#include <pwd.h>
33 44
34#include "netcompat.h" 45#include "netcompat.h"
35 46
36#include <openssl/err.h> 47#include <openssl/err.h>
37#include <openssl/pem.h> 48#include <openssl/pem.h>
47char *thisnode; 58char *thisnode;
48char *identname; 59char *identname;
49 60
50struct configuration conf; 61struct configuration conf;
51 62
63u8
52u8 best_protocol (u8 protset) 64best_protocol (u8 protset)
53{ 65{
54 if (protset & PROT_IPv4 ) return PROT_IPv4; 66 if (protset & PROT_IPv4 ) return PROT_IPv4;
55 if (protset & PROT_ICMPv4) return PROT_ICMPv4; 67 if (protset & PROT_ICMPv4) return PROT_ICMPv4;
56 if (protset & PROT_UDPv4 ) return PROT_UDPv4; 68 if (protset & PROT_UDPv4 ) return PROT_UDPv4;
57 if (protset & PROT_TCPv4 ) return PROT_TCPv4; 69 if (protset & PROT_TCPv4 ) return PROT_TCPv4;
58 if (protset & PROT_DNSv4 ) return PROT_DNSv4; 70 if (protset & PROT_DNSv4 ) return PROT_DNSv4;
59 71
60 return 0; 72 return 0;
61} 73}
62 74
75const char *
63const char *strprotocol (u8 protocol) 76strprotocol (u8 protocol)
64{ 77{
65 if (protocol & PROT_IPv4 ) return "rawip"; 78 if (protocol & PROT_IPv4 ) return "rawip";
66 if (protocol & PROT_ICMPv4) return "icmp"; 79 if (protocol & PROT_ICMPv4) return "icmp";
67 if (protocol & PROT_UDPv4 ) return "udp"; 80 if (protocol & PROT_UDPv4 ) return "udp";
68 if (protocol & PROT_TCPv4 ) return "tcp"; 81 if (protocol & PROT_TCPv4 ) return "tcp";
82 95
83 return false; 96 return false;
84} 97}
85 98
86bool 99bool
87conf_node::can_direct (struct conf_node *other) 100conf_node::may_direct (struct conf_node *other)
88{ 101{
89 if (match_list (allow_direct, other->nodename)) 102 if (match_list (allow_direct, other->nodename))
90 return true; 103 return true;
91 104
92 if (match_list (deny_direct, other->nodename)) 105 if (match_list (deny_direct, other->nodename))
93 return false; 106 return false;
94 107
95 return true; 108 return true;
96}
97
98void
99conf_node::print ()
100{
101 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %s%s%d\n",
102 id,
103 id >> 8, id & 0xff,
104 compress ? 'Y' : 'N',
105 connectmode == C_ONDEMAND ? "ondemand" :
106 connectmode == C_NEVER ? "never" :
107 connectmode == C_ALWAYS ? "always" : "",
108 nodename,
109 hostname ? hostname : "",
110 hostname ? ":" : "",
111 hostname ? udp_port : 0
112 );
113} 109}
114 110
115conf_node::~conf_node () 111conf_node::~conf_node ()
116{ 112{
117#if 0 113#if 0
128 free (dns_hostname); 124 free (dns_hostname);
129#endif 125#endif
130#endif 126#endif
131} 127}
132 128
129void
133void configuration::init () 130configuration::init ()
134{ 131{
135 memset (this, 0, sizeof (*this)); 132 memset (this, 0, sizeof (*this));
136 133
137 mtu = DEFAULT_MTU; 134 mtu = DEFAULT_MTU;
135 nfmark = 0;
138 rekey = DEFAULT_REKEY; 136 rekey = DEFAULT_REKEY;
139 keepalive = DEFAULT_KEEPALIVE; 137 keepalive = DEFAULT_KEEPALIVE;
140 llevel = L_INFO; 138 llevel = L_INFO;
141 ip_proto = IPPROTO_GRE; 139 ip_proto = IPPROTO_GRE;
142#if ENABLE_ICMP 140#if ENABLE_ICMP
154 default_node.if_up_data = strdup (""); 152 default_node.if_up_data = strdup ("");
155 153
156#if ENABLE_DNS 154#if ENABLE_DNS
157 default_node.dns_port = 0; // default is 0 == client 155 default_node.dns_port = 0; // default is 0 == client
158 156
157 dns_case_preserving = true;
159 dns_forw_host = strdup ("127.0.0.1"); 158 dns_forw_host = strdup ("127.0.0.1");
160 dns_forw_port = 53; 159 dns_forw_port = 53;
161 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR; 160 dns_timeout_factor = DEFAULT_DNS_TIMEOUT_FACTOR;
162 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL; 161 dns_send_interval = DEFAULT_DNS_SEND_INTERVAL;
163 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR; 162 dns_overlap_factor = DEFAULT_DNS_OVERLAP_FACTOR;
165#endif 164#endif
166 165
167 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid"); 166 conf.pidfilename = strdup (LOCALSTATEDIR "/run/gvpe.pid");
168} 167}
169 168
169void
170void configuration::cleanup() 170configuration::cleanup ()
171{ 171{
172 if (rsa_key) 172 if (rsa_key)
173 RSA_free (rsa_key); 173 RSA_free (rsa_key);
174 174
175 rsa_key = 0; 175 rsa_key = 0;
176 176
177 free (pidfilename); pidfilename = 0; 177 free (pidfilename); pidfilename = 0;
178 free (ifname); ifname = 0; 178 free (ifname); ifname = 0;
179#if ENABLE_HTTP_PROXY 179#if ENABLE_HTTP_PROXY
180 free (proxy_host); proxy_host = 0; 180 free (proxy_host); proxy_host = 0;
181 free (proxy_auth); proxy_auth = 0; 181 free (proxy_auth); proxy_auth = 0;
182#endif 182#endif
183#if ENABLE_DNS 183#if ENABLE_DNS
184 free (dns_forw_host); dns_forw_host = 0; 184 free (dns_forw_host); dns_forw_host = 0;
185#endif 185#endif
186 free (change_root); change_root = 0;
187 free (script_if_up); script_if_up = 0;
188 free (script_node_up); script_node_up = 0;
189 free (script_node_change); script_node_change = 0;
190 free (script_node_down); script_node_down = 0;
186} 191}
187 192
188void 193void
189configuration::clear () 194configuration::clear ()
190{ 195{
194 nodes.clear (); 199 nodes.clear ();
195 200
196 cleanup (); 201 cleanup ();
197 init (); 202 init ();
198} 203}
204
205//static bool
206//is_true (const char *name)
207//{
208 //re
209//}
199 210
200#define parse_bool(target,name,trueval,falseval) do { \ 211#define parse_bool(target,name,trueval,falseval) do { \
201 if (!strcmp (val, "yes")) target = trueval; \ 212 if (!strcmp (val, "yes")) target = trueval; \
202 else if (!strcmp (val, "no")) target = falseval; \ 213 else if (!strcmp (val, "no")) target = falseval; \
203 else if (!strcmp (val, "true")) target = trueval; \ 214 else if (!strcmp (val, "true")) target = trueval; \
204 else if (!strcmp (val, "false")) target = falseval; \ 215 else if (!strcmp (val, "false")) target = falseval; \
205 else if (!strcmp (val, "on")) target = trueval; \ 216 else if (!strcmp (val, "on")) target = trueval; \
206 else if (!strcmp (val, "off")) target = falseval; \ 217 else if (!strcmp (val, "off")) target = falseval; \
207 else \ 218 else \
208 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed. (ignored)"); \ 219 return _("illegal boolean value, only 'yes|true|on' or 'no|false|off' allowed, ignored"); \
209} while (0) 220} while (0)
210 221
211const char * 222const char *
212configuration_parser::parse_line (char *line) 223configuration_parser::parse_line (char *line)
213{ 224{
231 return 0; /* comment: ignore */ 242 return 0; /* comment: ignore */
232 243
233 char *val = strtok (NULL, "\t\n\r ="); 244 char *val = strtok (NULL, "\t\n\r =");
234 245
235 if (!val || val[0] == '#') 246 if (!val || val[0] == '#')
236 return _("no value given for variable. (ignored)"); 247 return _("no value given for variable, ignored");
237 248
238 if (!strcmp (var, "on")) 249 else if (!strcmp (var, "on"))
239 { 250 {
240 if (!::thisnode 251 if (::thisnode
241 || (val[0] == '!' && strcmp (val + 1, ::thisnode)) 252 && ((val[0] == '!' && strcmp (val + 1, ::thisnode))
242 || !strcmp (val, ::thisnode)) 253 || !strcmp (val, ::thisnode)))
243 return parse_line (strtok (NULL, "\n\r")); 254 return parse_line (strtok (NULL, "\n\r"));
244 else 255 }
245 return 0; 256
257 else if (!strcmp (var, "include"))
258 {
259 char *fname = conf.config_filename (val);
260 parse_file (fname);
261 free (fname);
246 } 262 }
247 263
248 // truly global 264 // truly global
249 if (!strcmp (var, "loglevel")) 265 else if (!strcmp (var, "loglevel"))
250 { 266 {
251 loglevel l = string_to_loglevel (val); 267 loglevel l = string_to_loglevel (val);
252 268
253 if (l == L_NONE) 269 if (l == L_NONE)
254 return _("unknown loglevel. (skipping)"); 270 return _("unknown loglevel, ignored");
255 } 271 }
256 else if (!strcmp (var, "ip-proto")) 272 else if (!strcmp (var, "ip-proto"))
257 conf.ip_proto = atoi (val); 273 conf.ip_proto = atoi (val);
258 else if (!strcmp (var, "icmp-type")) 274 else if (!strcmp (var, "icmp-type"))
259 { 275 {
260#if ENABLE_ICMP 276#if ENABLE_ICMP
261 conf.icmp_type = atoi (val); 277 conf.icmp_type = atoi (val);
262#endif 278#endif
263 } 279 }
280 else if (!strcmp (var, "chuser"))
281 {
282 struct passwd *pw = getpwnam (val);
283 if (!pw)
284 return _("user specified for chuser not found");
264 285
265 // per config 286 conf.change_uid = pw->pw_uid;
287 conf.change_gid = pw->pw_gid;
288 }
289 else if (!strcmp (var, "chuid"))
290 conf.change_uid = atoi (val);
291 else if (!strcmp (var, "chgid"))
292 conf.change_gid = atoi (val);
293 else if (!strcmp (var, "chroot"))
294 free (conf.change_root), conf.change_root = strdup (val);
295
296 // per node
266 else if (!strcmp (var, "node")) 297 else if (!strcmp (var, "node"))
267 { 298 {
268 parse_argv (); 299 parse_argv ();
269 300
270 conf.default_node.id++; 301 conf.default_node.id++;
318 conf.rekey = atoi (val); 349 conf.rekey = atoi (val);
319 else if (!strcmp (var, "keepalive")) 350 else if (!strcmp (var, "keepalive"))
320 conf.keepalive = atoi (val); 351 conf.keepalive = atoi (val);
321 else if (!strcmp (var, "mtu")) 352 else if (!strcmp (var, "mtu"))
322 conf.mtu = atoi (val); 353 conf.mtu = atoi (val);
354 else if (!strcmp (var, "nfmark"))
355 conf.nfmark = atoi (val);
323 else if (!strcmp (var, "if-up")) 356 else if (!strcmp (var, "if-up"))
324 free (conf.script_if_up), conf.script_if_up = strdup (val); 357 free (conf.script_if_up), conf.script_if_up = strdup (val);
325 else if (!strcmp (var, "node-up")) 358 else if (!strcmp (var, "node-up"))
326 free (conf.script_node_up), conf.script_node_up = strdup (val); 359 free (conf.script_node_up), conf.script_node_up = strdup (val);
360 else if (!strcmp (var, "node-change"))
361 free (conf.script_node_change), conf.script_node_change = strdup (val);
327 else if (!strcmp (var, "node-down")) 362 else if (!strcmp (var, "node-down"))
328 free (conf.script_node_down), conf.script_node_down = strdup (val); 363 free (conf.script_node_down), conf.script_node_down = strdup (val);
329 else if (!strcmp (var, "pid-file")) 364 else if (!strcmp (var, "pid-file"))
330 free (conf.pidfilename), conf.pidfilename = strdup (val); 365 free (conf.pidfilename), conf.pidfilename = strdup (val);
331 else if (!strcmp (var, "dns-forw-host")) 366 else if (!strcmp (var, "dns-forw-host"))
360 } 395 }
361 else if (!strcmp (var, "dns-max-outstanding")) 396 else if (!strcmp (var, "dns-max-outstanding"))
362 { 397 {
363#if ENABLE_DNS 398#if ENABLE_DNS
364 conf.dns_max_outstanding = atoi (val); 399 conf.dns_max_outstanding = atoi (val);
400#endif
401 }
402 else if (!strcmp (var, "dns-case-preserving"))
403 {
404#if ENABLE_DNS
405 parse_bool (conf.dns_case_preserving, "dns-case-preserving", true, false);
365#endif 406#endif
366 } 407 }
367 else if (!strcmp (var, "http-proxy-host")) 408 else if (!strcmp (var, "http-proxy-host"))
368 { 409 {
369#if ENABLE_HTTP_PROXY 410#if ENABLE_HTTP_PROXY
425 else if (!strcmp (val, "always")) 466 else if (!strcmp (val, "always"))
426 node->connectmode = conf_node::C_ALWAYS; 467 node->connectmode = conf_node::C_ALWAYS;
427 else if (!strcmp (val, "disabled")) 468 else if (!strcmp (val, "disabled"))
428 node->connectmode = conf_node::C_DISABLED; 469 node->connectmode = conf_node::C_DISABLED;
429 else 470 else
430 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled'. (ignored)"); 471 return _("illegal value for 'connectmode', use one of 'ondemand', 'never', 'always' or 'disabled', ignored");
431 } 472 }
432 else if (!strcmp (var, "inherit-tos")) 473 else if (!strcmp (var, "inherit-tos"))
433 parse_bool (node->inherit_tos, "inherit-tos", true, false); 474 parse_bool (node->inherit_tos, "inherit-tos", true, false);
434 else if (!strcmp (var, "compress")) 475 else if (!strcmp (var, "compress"))
435 parse_bool (node->compress, "compress", true, false); 476 parse_bool (node->compress, "compress", true, false);
469 else if (!strcmp (var, "max-queue")) 510 else if (!strcmp (var, "max-queue"))
470 node->max_queue = atoi (val); 511 node->max_queue = atoi (val);
471 512
472 // unknown or misplaced 513 // unknown or misplaced
473 else 514 else
474 return _("unknown configuration directive. (ignored)"); 515 return _("unknown configuration directive - ignored");
475 516
476 return 0; 517 return 0;
477} 518}
478 519
520void
521conf_node::finalise ()
522{
523 if (max_queue < 1)
524 {
525 slog (L_WARN, _("%s: max-queue value invalid, setting it to 1."), nodename);
526 max_queue = 1;
527 }
528
529 if (routerprio > 1 && (connectmode != C_ALWAYS && connectmode != C_DISABLED))
530 {
531 //slog (L_WARN, _("%s: has non-zero router-priority but either 'never' or 'ondemand' as connectmode, setting it to 'always'."), nodename);
532 connectmode = C_ALWAYS;
533 }
534}
535
536void
479void configuration_parser::parse_argv () 537configuration_parser::parse_argv ()
480{ 538{
481 for (int i = 0; i < argc; ++i) 539 for (int i = 0; i < argc; ++i)
482 { 540 {
483 char *v = argv [i]; 541 char *v = argv [i];
484 542
505 if (warn) 563 if (warn)
506 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v); 564 slog (L_WARN, _("%s, while parsing command line option '%s'."), warn, v);
507 565
508 *v = 0; 566 *v = 0;
509 } 567 }
568 }
569}
570
571void
572configuration_parser::parse_file (const char *fname)
573{
574 if (FILE *f = fopen (fname, "r"))
575 {
576 char line [2048];
577 int lineno = 0;
578
579 while (fgets (line, sizeof (line), f))
580 {
581 lineno++;
582
583 const char *warn = parse_line (line);
584
585 if (warn)
586 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
587 }
588
589 fclose (f);
590
591 parse_argv ();
592 }
593 else
594 {
595 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
596 exit (EXIT_FAILURE);
510 } 597 }
511} 598}
512 599
513configuration_parser::configuration_parser (configuration &conf, 600configuration_parser::configuration_parser (configuration &conf,
514 bool need_keys, 601 bool need_keys,
515 int argc, 602 int argc,
516 char **argv) 603 char **argv)
517: conf (conf),need_keys (need_keys), argc (argc), argv (argv) 604: conf (conf),need_keys (need_keys), argc (argc), argv (argv)
518{ 605{
519 char *fname; 606 char *fname;
520 FILE *f;
521 607
522 conf.clear (); 608 conf.clear ();
609 node = &conf.default_node;
523 610
524 asprintf (&fname, "%s/gvpe.conf", confbase); 611 asprintf (&fname, "%s/gvpe.conf", confbase);
525 f = fopen (fname, "r"); 612 parse_file (fname);
526
527 if (f)
528 {
529 char line[16384];
530 int lineno = 0;
531 node = &conf.default_node;
532
533 while (fgets (line, sizeof (line), f))
534 {
535 lineno++;
536
537 const char *warn = parse_line (line);
538
539 if (warn)
540 slog (L_WARN, _("%s, at '%s', line %d."), warn, fname, lineno);
541 }
542
543 fclose (f);
544
545 parse_argv ();
546 }
547 else
548 {
549 slog (L_ERR, _("unable to read config file '%s': %s"), fname, strerror (errno));
550 exit (EXIT_FAILURE);
551 }
552
553 free (fname); 613 free (fname);
554 614
555 fname = conf.config_filename (conf.prikeyfile, "hostkey"); 615 fname = conf.config_filename (conf.prikeyfile, "hostkey");
556 616
557 f = fopen (fname, "r"); 617 if (FILE *f = fopen (fname, "r"))
558 if (f)
559 { 618 {
560 conf.rsa_key = RSA_new (); 619 conf.rsa_key = RSA_new ();
561 620
562 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL)) 621 if (!PEM_read_RSAPrivateKey (f, &conf.rsa_key, NULL, NULL))
563 { 622 {
575 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno)); 634 slog (need_keys ? L_ERR : L_NOTICE, _("unable to open private rsa key file '%s': %s"), fname, strerror (errno));
576 635
577 if (need_keys) 636 if (need_keys)
578 exit (EXIT_FAILURE); 637 exit (EXIT_FAILURE);
579 } 638 }
639
640 free (fname);
580 641
581 if (need_keys && ::thisnode 642 if (need_keys && ::thisnode
582 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key) 643 && conf.rsa_key && conf.thisnode && conf.thisnode->rsa_key)
583 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0 644 if (BN_cmp (conf.rsa_key->n, conf.thisnode->rsa_key->n) != 0
584 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0) 645 || BN_cmp (conf.rsa_key->e, conf.thisnode->rsa_key->e) != 0)
585 { 646 {
586 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode); 647 slog (L_NOTICE, _("private hostkey and public node key mismatch: is '%s' the correct node?"), ::thisnode);
587 exit (EXIT_FAILURE); 648 exit (EXIT_FAILURE);
588 } 649 }
589 650
590 free (fname); 651 for (configuration::node_vector::iterator i = conf.nodes.begin(); i != conf.nodes.end(); ++i)
652 (*i)->finalise ();
591} 653}
592 654
655char *
593char *configuration::config_filename (const char *name, const char *dflt) 656configuration::config_filename (const char *name, const char *dflt)
594{ 657{
595 char *fname; 658 char *fname;
596 659
597 asprintf (&fname, name ? name : dflt, ::thisnode); 660 asprintf (&fname, name ? name : dflt, ::thisnode);
598 661
602 asprintf (&fname, "%s/%s", confbase, rname); 665 asprintf (&fname, "%s/%s", confbase, rname);
603 free (rname); 666 free (rname);
604 } 667 }
605 668
606 return fname; 669 return fname;
670}
671
672void
673conf_node::print ()
674{
675 printf ("%4d fe:fd:80:00:0%1x:%02x %c %-8.8s %-10.10s %02x %s%s%d\n",
676 id,
677 id >> 8, id & 0xff,
678 compress ? 'Y' : 'N',
679 connectmode == C_ONDEMAND ? "ondemand"
680 : connectmode == C_NEVER ? "never"
681 : connectmode == C_ALWAYS ? "always"
682 : connectmode == C_DISABLED ? "disabled"
683 : "",
684 nodename,
685 protocols,
686 hostname ? hostname : "",
687 hostname ? ":" : "",
688 hostname ? udp_port : 0
689 );
607} 690}
608 691
609void 692void
610configuration::print () 693configuration::print ()
611{ 694{
618 printf (_("interface: %s\n"), ifname); 701 printf (_("interface: %s\n"), ifname);
619 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>"); 702 printf (_("primary rsa key: %s\n"), prikeyfile ? prikeyfile : "<default>");
620 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1); 703 printf (_("rsa key size: %d\n"), rsa_key ? RSA_size (rsa_key) * 8 : -1);
621 printf ("\n"); 704 printf ("\n");
622 705
623 printf ("%4s %-17s %s %-8.8s %-10.10s %s\n", 706 printf ("%4s %-17s %s %-8.8s %-10.10s %04s %s\n",
624 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Host:Port")); 707 _("ID#"), _("MAC"), _("Com"), _("Conmode"), _("Node"), _("Prot"), _("Host:Port"));
625 708
626 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i) 709 for (node_vector::iterator i = nodes.begin (); i != nodes.end (); ++i)
627 (*i)->print (); 710 (*i)->print ();
628 711
629 printf ("\n"); 712 printf ("\n");
639configuration::~configuration () 722configuration::~configuration ()
640{ 723{
641 cleanup (); 724 cleanup ();
642} 725}
643 726
644

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines