[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r19303 - in gnunet/src: exit vpn
From: |
gnunet |
Subject: |
[GNUnet-SVN] r19303 - in gnunet/src: exit vpn |
Date: |
Sat, 21 Jan 2012 21:05:04 +0100 |
Author: grothoff
Date: 2012-01-21 21:05:03 +0100 (Sat, 21 Jan 2012)
New Revision: 19303
Modified:
gnunet/src/exit/gnunet-daemon-exit.c
gnunet/src/vpn/gnunet-service-vpn.c
Log:
-implementing ICMP PT and type checking on VPN->TUN link
Modified: gnunet/src/exit/gnunet-daemon-exit.c
===================================================================
--- gnunet/src/exit/gnunet-daemon-exit.c 2012-01-21 19:28:46 UTC (rev
19302)
+++ gnunet/src/exit/gnunet-daemon-exit.c 2012-01-21 20:05:03 UTC (rev
19303)
@@ -649,7 +649,7 @@
break;
default:
GNUNET_STATISTICS_update (stats,
- gettext_noop ("# ICMPv4 packets dropped (not
allowed)"),
+ gettext_noop ("# ICMPv4 packets dropped (type
not allowed)"),
1, GNUNET_NO);
return;
}
@@ -684,7 +684,7 @@
break;
default:
GNUNET_STATISTICS_update (stats,
- gettext_noop ("# ICMPv6 packets dropped (not
allowed)"),
+ gettext_noop ("# ICMPv6 packets dropped (type
not allowed)"),
1, GNUNET_NO);
return;
}
Modified: gnunet/src/vpn/gnunet-service-vpn.c
===================================================================
--- gnunet/src/vpn/gnunet-service-vpn.c 2012-01-21 19:28:46 UTC (rev 19302)
+++ gnunet/src/vpn/gnunet-service-vpn.c 2012-01-21 20:05:03 UTC (rev 19303)
@@ -1600,6 +1600,44 @@
/**
+ * Synthesize a plausible ICMP payload for an ICMP error
+ * response on the given tunnel.
+ *
+ * @param ts tunnel information
+ * @param ipp IPv4 header to fill in (ICMP payload)
+ * @param udp "UDP" header to fill in (ICMP payload); might actually
+ * also be the first 8 bytes of the TCP header
+ */
+static void
+make_up_icmpv4_payload (struct TunnelState *ts,
+ struct GNUNET_TUN_IPv4Header *ipp,
+ struct GNUNET_TUN_UdpHeader *udp)
+{
+ /* FIXME */
+ GNUNET_break (0);
+}
+
+
+/**
+ * Synthesize a plausible ICMP payload for an ICMP error
+ * response on the given tunnel.
+ *
+ * @param ts tunnel information
+ * @param ipp IPv6 header to fill in (ICMP payload)
+ * @param udp "UDP" header to fill in (ICMP payload); might actually
+ * also be the first 8 bytes of the TCP header
+ */
+static void
+make_up_icmpv6_payload (struct TunnelState *ts,
+ struct GNUNET_TUN_IPv6Header *ipp,
+ struct GNUNET_TUN_UdpHeader *udp)
+{
+ /* FIXME */
+ GNUNET_break (0);
+}
+
+
+/**
* We got an ICMP packet back from the MESH tunnel. Pass it on to the
* local virtual interface via the helper.
*
@@ -1663,13 +1701,14 @@
sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
mlen;
{
- char buf[size];
+ /* reserve some extra space in case we have an ICMP type here where
+ we will need to make up the payload ourselves */
+ char buf[size + sizeof (struct GNUNET_TUN_IPv4Header) + 8];
struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
struct GNUNET_TUN_Layer2PacketHeader *tun = (struct
GNUNET_TUN_Layer2PacketHeader*) &msg[1];
struct GNUNET_TUN_IPv4Header *ipv4 = (struct GNUNET_TUN_IPv4Header *)
&tun[1];
struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *)
&ipv4[1];
msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
- msg->size = htons (size);
tun->flags = htons (0);
tun->proto = htons (ETH_P_IPV4);
GNUNET_TUN_initialize_ipv4_header (ipv4,
@@ -1681,7 +1720,108 @@
memcpy (&icmp[1],
&i2v[1],
mlen);
- /* FIXME: for some ICMP types, we need to adjust the payload here... */
+ /* For some ICMP types, we need to adjust (make up) the payload here.
+ Also, depending on the AF used on the other side, we have to
+ do ICMP PT (translate ICMP types) */
+ switch (ntohl (i2v->af))
+ {
+ case AF_INET:
+ switch (icmp->type)
+ {
+ case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
+ case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
+ break;
+ case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
+ case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
+ case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
+ {
+ struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header
*) &icmp[1];
+ struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader
*) &ipp[1];
+
+ if (mlen != 0)
+ {
+ /* sender did not strip ICMP payload? */
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
+ GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
+ make_up_icmpv4_payload (ts, ipp, udp);
+ }
+ break;
+ default:
+ GNUNET_break_op (0);
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# ICMPv4 packets dropped
(type not allowed)"),
+ 1, GNUNET_NO);
+ return GNUNET_SYSERR;
+ }
+ /* end AF_INET */
+ break;
+ case AF_INET6:
+ /* ICMP PT 6-to-4 and possibly making up payloads */
+ switch (icmp->type)
+ {
+ case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
+ icmp->type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE;
+ {
+ struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header
*) &icmp[1];
+ struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader
*) &ipp[1];
+
+ if (mlen != 0)
+ {
+ /* sender did not strip ICMP payload? */
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
+ GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
+ make_up_icmpv4_payload (ts, ipp, udp);
+ }
+ break;
+ case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
+ icmp->type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED;
+ {
+ struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header
*) &icmp[1];
+ struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader
*) &ipp[1];
+
+ if (mlen != 0)
+ {
+ /* sender did not strip ICMP payload? */
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ size += sizeof (struct GNUNET_TUN_IPv4Header) + 8;
+ GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
+ make_up_icmpv4_payload (ts, ipp, udp);
+ }
+ break;
+ case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
+ case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# ICMPv6 packets dropped
(impossible PT to v4)"),
+ 1, GNUNET_NO);
+ return GNUNET_OK;
+ case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
+ icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST;
+ break;
+ case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY:
+ icmp->type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY;
+ break;
+ default:
+ GNUNET_break_op (0);
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# ICMPv6 packets dropped
(type not allowed)"),
+ 1, GNUNET_NO);
+ return GNUNET_SYSERR;
+ }
+ /* end AF_INET6 */
+ break;
+ default:
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ msg->size = htons (size);
GNUNET_TUN_calculate_icmp_checksum (icmp,
&i2v[1],
mlen);
@@ -1700,13 +1840,12 @@
sizeof (struct GNUNET_TUN_Layer2PacketHeader) +
mlen;
{
- char buf[size];
+ char buf[size + sizeof (struct GNUNET_TUN_IPv6Header) + 8];
struct GNUNET_MessageHeader *msg = (struct GNUNET_MessageHeader *) buf;
struct GNUNET_TUN_Layer2PacketHeader *tun = (struct
GNUNET_TUN_Layer2PacketHeader*) &msg[1];
struct GNUNET_TUN_IPv6Header *ipv6 = (struct GNUNET_TUN_IPv6Header *)
&tun[1];
struct GNUNET_TUN_IcmpHeader *icmp = (struct GNUNET_TUN_IcmpHeader *)
&ipv6[1];
msg->type = htons (GNUNET_MESSAGE_TYPE_VPN_HELPER);
- msg->size = htons (size);
tun->flags = htons (0);
tun->proto = htons (ETH_P_IPV6);
GNUNET_TUN_initialize_ipv6_header (ipv6,
@@ -1718,7 +1857,108 @@
memcpy (&icmp[1],
&i2v[1],
mlen);
- /* FIXME: for some ICMP types, we need to adjust the payload here... */
+
+ /* For some ICMP types, we need to adjust (make up) the payload here.
+ Also, depending on the AF used on the other side, we have to
+ do ICMP PT (translate ICMP types) */
+ switch (ntohl (i2v->af))
+ {
+ case AF_INET:
+ /* ICMP PT 4-to-6 and possibly making up payloads */
+ switch (icmp->type)
+ {
+ case GNUNET_TUN_ICMPTYPE_ECHO_REPLY:
+ icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY;
+ break;
+ case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST:
+ icmp->type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST;
+ break;
+ case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE:
+ icmp->type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE;
+ {
+ struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header
*) &icmp[1];
+ struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader
*) &ipp[1];
+
+ if (mlen != 0)
+ {
+ /* sender did not strip ICMP payload? */
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
+ GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
+ make_up_icmpv6_payload (ts, ipp, udp);
+ }
+ break;
+ case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED:
+ icmp->type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED;
+ {
+ struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header
*) &icmp[1];
+ struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader
*) &ipp[1];
+
+ if (mlen != 0)
+ {
+ /* sender did not strip ICMP payload? */
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
+ GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
+ make_up_icmpv6_payload (ts, ipp, udp);
+ }
+ break;
+ case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH:
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# ICMPv4 packets dropped
(impossible PT to v6)"),
+ 1, GNUNET_NO);
+ return GNUNET_OK;
+ default:
+ GNUNET_break_op (0);
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# ICMPv4 packets dropped
(type not allowed)"),
+ 1, GNUNET_NO);
+ return GNUNET_SYSERR;
+ }
+ /* end AF_INET */
+ break;
+ case AF_INET6:
+ switch (icmp->type)
+ {
+ case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE:
+ case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED:
+ case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG:
+ case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM:
+ {
+ struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header
*) &icmp[1];
+ struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader
*) &ipp[1];
+
+ if (mlen != 0)
+ {
+ /* sender did not strip ICMP payload? */
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ size += sizeof (struct GNUNET_TUN_IPv6Header) + 8;
+ GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader));
+ make_up_icmpv6_payload (ts, ipp, udp);
+ }
+ break;
+ case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST:
+ break;
+ default:
+ GNUNET_break_op (0);
+ GNUNET_STATISTICS_update (stats,
+ gettext_noop ("# ICMPv6 packets dropped
(type not allowed)"),
+ 1, GNUNET_NO);
+ return GNUNET_SYSERR;
+ }
+ /* end AF_INET6 */
+ break;
+ default:
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ msg->size = htons (size);
GNUNET_TUN_calculate_icmp_checksum (icmp,
&i2v[1], mlen);
(void) GNUNET_HELPER_send (helper_handle,
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r19303 - in gnunet/src: exit vpn,
gnunet <=