1 | /* |
1 | /* |
2 | vpn.C -- handle the protocol, encryption, handshaking etc. |
2 | vpn.C -- handle the protocol, encryption, handshaking etc. |
|
|
3 | Copyright (C) 2003 Marc Lehmann <pcg@goof.com> |
3 | |
4 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by |
6 | it under the terms of the GNU General Public License as published by |
6 | the Free Software Foundation; either version 2 of the License, or |
7 | the Free Software Foundation; either version 2 of the License, or |
7 | (at your option) any later version. |
8 | (at your option) any later version. |
… | |
… | |
39 | |
40 | |
40 | #include "connection.h" |
41 | #include "connection.h" |
41 | #include "util.h" |
42 | #include "util.h" |
42 | #include "vpn.h" |
43 | #include "vpn.h" |
43 | |
44 | |
|
|
45 | vpn network; // THE vpn (bad design...) |
|
|
46 | |
44 | ///////////////////////////////////////////////////////////////////////////// |
47 | ///////////////////////////////////////////////////////////////////////////// |
45 | |
48 | |
46 | const char *vpn::script_if_up () |
49 | const char *vpn::script_if_up () |
47 | { |
50 | { |
48 | // the tunnel device mtu should be the physical mtu - overhead |
51 | // the tunnel device mtu should be the physical mtu - overhead |
… | |
… | |
335 | |
338 | |
336 | return true; |
339 | return true; |
337 | } |
340 | } |
338 | |
341 | |
339 | void |
342 | void |
|
|
343 | vpn::inject_data_packet (tap_packet *pkt, int dst) |
|
|
344 | { |
|
|
345 | if (dst) |
|
|
346 | { |
|
|
347 | // unicast |
|
|
348 | if (dst != THISNODE->id) |
|
|
349 | conns[dst - 1]->inject_data_packet (pkt); |
|
|
350 | } |
|
|
351 | else |
|
|
352 | { |
|
|
353 | // broadcast, this is ugly, but due to the security policy |
|
|
354 | // we have to connect to all hosts... |
|
|
355 | for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) |
|
|
356 | if ((*c)->conf != THISNODE) |
|
|
357 | (*c)->inject_data_packet (pkt, true); |
|
|
358 | } |
|
|
359 | } |
|
|
360 | |
|
|
361 | void |
340 | vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) |
362 | vpn::recv_vpn_packet (vpn_packet *pkt, const sockinfo &rsi) |
341 | { |
363 | { |
342 | unsigned int src = pkt->src (); |
364 | unsigned int src = pkt->src (); |
343 | unsigned int dst = pkt->dst (); |
365 | unsigned int dst = pkt->dst (); |
344 | |
366 | |
… | |
… | |
358 | connection *c = conns[src - 1]; |
380 | connection *c = conns[src - 1]; |
359 | |
381 | |
360 | if (dst == 0) |
382 | if (dst == 0) |
361 | slog (L_WARN, _("%s(%s): received broadcast (protocol violation)"), |
383 | slog (L_WARN, _("%s(%s): received broadcast (protocol violation)"), |
362 | c->conf->nodename, (const char *)rsi); |
384 | c->conf->nodename, (const char *)rsi); |
363 | else if (dst != 0 && dst != THISNODE->id) |
385 | else if (dst != THISNODE->id) |
364 | { |
386 | { |
365 | if (THISNODE->routerprio) |
387 | if (THISNODE->routerprio) |
366 | // the tos setting gets lost here. who cares. |
388 | // the tos setting gets lost here. who cares. |
367 | conns[dst - 1]->inject_vpn_packet (pkt); |
389 | conns[dst - 1]->inject_vpn_packet (pkt); |
368 | else |
390 | else |
… | |
… | |
529 | /* process data */ |
551 | /* process data */ |
530 | tap_packet *pkt; |
552 | tap_packet *pkt; |
531 | |
553 | |
532 | pkt = tap->recv (); |
554 | pkt = tap->recv (); |
533 | |
555 | |
|
|
556 | if (!pkt) |
|
|
557 | return; |
|
|
558 | |
|
|
559 | if (pkt->len > 14) |
|
|
560 | { |
534 | int dst = mac2id (pkt->dst); |
561 | int dst = mac2id (pkt->dst); |
535 | int src = mac2id (pkt->src); |
562 | int src = mac2id (pkt->src); |
536 | |
563 | |
537 | if (src != THISNODE->id) |
564 | if (src != THISNODE->id) |
538 | { |
|
|
539 | slog (L_ERR, _("FATAL: tap packet not originating on current node received, exiting.")); |
|
|
540 | exit (1); |
|
|
541 | } |
|
|
542 | |
|
|
543 | if (dst == THISNODE->id) |
|
|
544 | { |
|
|
545 | slog (L_ERR, _("FATAL: tap packet destined for current node received, exiting.")); |
|
|
546 | exit (1); |
|
|
547 | } |
|
|
548 | |
|
|
549 | if (dst > conns.size ()) |
|
|
550 | slog (L_ERR, _("tap packet for unknown node %d received, ignoring."), dst); |
|
|
551 | else |
|
|
552 | { |
|
|
553 | if (dst) |
|
|
554 | { |
565 | { |
555 | // unicast |
566 | slog (L_ERR, _("FATAL: tap packet not originating on current node received, exiting.")); |
556 | if (dst != THISNODE->id) |
567 | exit (1); |
557 | conns[dst - 1]->inject_data_packet (pkt); |
|
|
558 | } |
568 | } |
|
|
569 | |
|
|
570 | if (dst == THISNODE->id) |
|
|
571 | { |
|
|
572 | slog (L_ERR, _("FATAL: tap packet destined for current node received, exiting.")); |
|
|
573 | exit (1); |
|
|
574 | } |
|
|
575 | |
|
|
576 | if (dst > conns.size ()) |
|
|
577 | slog (L_ERR, _("tap packet for unknown node %d received, ignoring."), dst); |
559 | else |
578 | else |
560 | { |
|
|
561 | // broadcast, this is ugly, but due to the security policy |
|
|
562 | // we have to connect to all hosts... |
|
|
563 | for (conns_vector::iterator c = conns.begin (); c != conns.end (); ++c) |
|
|
564 | if ((*c)->conf != THISNODE) |
|
|
565 | (*c)->inject_data_packet (pkt); |
579 | inject_data_packet (pkt, dst); |
566 | } |
|
|
567 | } |
580 | } |
568 | |
581 | |
569 | delete pkt; |
582 | delete pkt; |
570 | } |
583 | } |
571 | else if (revents & (POLLHUP | POLLERR)) |
584 | else if (revents & (POLLHUP | POLLERR)) |