diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-21 22:30:54 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-21 22:30:54 +0000 |
commit | 0ac5d4626b676bbccebb1c67a2963277ebf2bc00 (patch) | |
tree | 00394b8779638e45a5b9968c4dfdba7d9e83256c /src/exit/gnunet-daemon-exit.c | |
parent | c5dc23a6f2cfd4cff8cb13fa50614816dd480843 (diff) | |
download | gnunet-0ac5d4626b676bbccebb1c67a2963277ebf2bc00.tar.gz gnunet-0ac5d4626b676bbccebb1c67a2963277ebf2bc00.zip |
-implementing ICMP PT and generation if ICMP payloads on EXIT->TUN link (for both service and Internet exit)
Diffstat (limited to 'src/exit/gnunet-daemon-exit.c')
-rw-r--r-- | src/exit/gnunet-daemon-exit.c | 358 |
1 files changed, 336 insertions, 22 deletions
diff --git a/src/exit/gnunet-daemon-exit.c b/src/exit/gnunet-daemon-exit.c index f55106243..514554b80 100644 --- a/src/exit/gnunet-daemon-exit.c +++ b/src/exit/gnunet-daemon-exit.c | |||
@@ -390,6 +390,12 @@ get_redirect_state (int af, | |||
390 | GNUNET_HashCode key; | 390 | GNUNET_HashCode key; |
391 | struct TunnelState *state; | 391 | struct TunnelState *state; |
392 | 392 | ||
393 | if (protocol == IPPROTO_ICMP) | ||
394 | { | ||
395 | /* ignore ports */ | ||
396 | destination_port = 0; | ||
397 | local_port = 0; | ||
398 | } | ||
393 | ri.remote_address.af = af; | 399 | ri.remote_address.af = af; |
394 | if (af == AF_INET) | 400 | if (af == AF_INET) |
395 | ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip); | 401 | ri.remote_address.address.ipv4 = *((struct in_addr*) destination_ip); |
@@ -1858,6 +1864,58 @@ send_icmp_packet_via_tun (const struct SocketAddress *destination_address, | |||
1858 | 1864 | ||
1859 | 1865 | ||
1860 | /** | 1866 | /** |
1867 | * Synthesize a plausible ICMP payload for an ICMPv4 error | ||
1868 | * response on the given tunnel. | ||
1869 | * | ||
1870 | * @param state tunnel information | ||
1871 | * @param ipp IPv6 header to fill in (ICMP payload) | ||
1872 | * @param udp "UDP" header to fill in (ICMP payload); might actually | ||
1873 | * also be the first 8 bytes of the TCP header | ||
1874 | */ | ||
1875 | static void | ||
1876 | make_up_icmpv4_payload (struct TunnelState *state, | ||
1877 | struct GNUNET_TUN_IPv4Header *ipp, | ||
1878 | struct GNUNET_TUN_UdpHeader *udp) | ||
1879 | { | ||
1880 | GNUNET_TUN_initialize_ipv4_header (ipp, | ||
1881 | state->ri.remote_address.proto, | ||
1882 | sizeof (struct GNUNET_TUN_TcpHeader), | ||
1883 | &state->ri.remote_address.address.ipv4, | ||
1884 | &state->ri.local_address.address.ipv4); | ||
1885 | udp->spt = htons (state->ri.remote_address.port); | ||
1886 | udp->dpt = htons (state->ri.local_address.port); | ||
1887 | udp->len = htons (0); | ||
1888 | udp->crc = htons (0); | ||
1889 | } | ||
1890 | |||
1891 | |||
1892 | /** | ||
1893 | * Synthesize a plausible ICMP payload for an ICMPv6 error | ||
1894 | * response on the given tunnel. | ||
1895 | * | ||
1896 | * @param state tunnel information | ||
1897 | * @param ipp IPv6 header to fill in (ICMP payload) | ||
1898 | * @param udp "UDP" header to fill in (ICMP payload); might actually | ||
1899 | * also be the first 8 bytes of the TCP header | ||
1900 | */ | ||
1901 | static void | ||
1902 | make_up_icmpv6_payload (struct TunnelState *state, | ||
1903 | struct GNUNET_TUN_IPv6Header *ipp, | ||
1904 | struct GNUNET_TUN_UdpHeader *udp) | ||
1905 | { | ||
1906 | GNUNET_TUN_initialize_ipv6_header (ipp, | ||
1907 | state->ri.remote_address.proto, | ||
1908 | sizeof (struct GNUNET_TUN_TcpHeader), | ||
1909 | &state->ri.remote_address.address.ipv6, | ||
1910 | &state->ri.local_address.address.ipv6); | ||
1911 | udp->spt = htons (state->ri.remote_address.port); | ||
1912 | udp->dpt = htons (state->ri.local_address.port); | ||
1913 | udp->len = htons (0); | ||
1914 | udp->crc = htons (0); | ||
1915 | } | ||
1916 | |||
1917 | |||
1918 | /** | ||
1861 | * Process a request to forward ICMP data to the Internet via this peer. | 1919 | * Process a request to forward ICMP data to the Internet via this peer. |
1862 | * | 1920 | * |
1863 | * @param cls closure, NULL | 1921 | * @param cls closure, NULL |
@@ -1882,6 +1940,7 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1882 | const struct in_addr *v4; | 1940 | const struct in_addr *v4; |
1883 | const struct in6_addr *v6; | 1941 | const struct in6_addr *v6; |
1884 | const void *payload; | 1942 | const void *payload; |
1943 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8]; | ||
1885 | int af; | 1944 | int af; |
1886 | 1945 | ||
1887 | GNUNET_STATISTICS_update (stats, | 1946 | GNUNET_STATISTICS_update (stats, |
@@ -1899,7 +1958,14 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1899 | pkt_len -= sizeof (struct GNUNET_EXIT_IcmpInternetMessage); | 1958 | pkt_len -= sizeof (struct GNUNET_EXIT_IcmpInternetMessage); |
1900 | 1959 | ||
1901 | af = (int) ntohl (msg->af); | 1960 | af = (int) ntohl (msg->af); |
1902 | state->ri.remote_address.af = af; | 1961 | if ( (NULL != state->heap_node) && |
1962 | (af != state->ri.remote_address.af) ) | ||
1963 | { | ||
1964 | /* other peer switched AF on this tunnel; not allowed */ | ||
1965 | GNUNET_break_op (0); | ||
1966 | return GNUNET_SYSERR; | ||
1967 | } | ||
1968 | |||
1903 | switch (af) | 1969 | switch (af) |
1904 | { | 1970 | { |
1905 | case AF_INET: | 1971 | case AF_INET: |
@@ -1917,6 +1983,48 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1917 | payload = &v4[1]; | 1983 | payload = &v4[1]; |
1918 | pkt_len -= sizeof (struct in_addr); | 1984 | pkt_len -= sizeof (struct in_addr); |
1919 | state->ri.remote_address.address.ipv4 = *v4; | 1985 | state->ri.remote_address.address.ipv4 = *v4; |
1986 | if (NULL == state->heap_node) | ||
1987 | { | ||
1988 | state->ri.remote_address.af = af; | ||
1989 | state->ri.remote_address.proto = IPPROTO_ICMP; | ||
1990 | setup_state_record (state); | ||
1991 | } | ||
1992 | /* check that ICMP type is something we want to support | ||
1993 | and possibly make up payload! */ | ||
1994 | switch (msg->icmp_header.type) | ||
1995 | { | ||
1996 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
1997 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
1998 | break; | ||
1999 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
2000 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
2001 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
2002 | if (0 != pkt_len) | ||
2003 | { | ||
2004 | GNUNET_break_op (0); | ||
2005 | return GNUNET_SYSERR; | ||
2006 | } | ||
2007 | /* make up payload */ | ||
2008 | { | ||
2009 | struct GNUNET_TUN_IPv4Header *ipp = (struct GNUNET_TUN_IPv4Header *) buf; | ||
2010 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
2011 | |||
2012 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2013 | pkt_len = sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
2014 | make_up_icmpv4_payload (state, | ||
2015 | ipp, | ||
2016 | udp); | ||
2017 | payload = ipp; | ||
2018 | } | ||
2019 | break; | ||
2020 | default: | ||
2021 | GNUNET_break_op (0); | ||
2022 | GNUNET_STATISTICS_update (stats, | ||
2023 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
2024 | 1, GNUNET_NO); | ||
2025 | return GNUNET_SYSERR; | ||
2026 | } | ||
2027 | /* end AF_INET */ | ||
1920 | break; | 2028 | break; |
1921 | case AF_INET6: | 2029 | case AF_INET6: |
1922 | if (pkt_len < sizeof (struct in6_addr)) | 2030 | if (pkt_len < sizeof (struct in6_addr)) |
@@ -1933,8 +2041,52 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1933 | payload = &v6[1]; | 2041 | payload = &v6[1]; |
1934 | pkt_len -= sizeof (struct in6_addr); | 2042 | pkt_len -= sizeof (struct in6_addr); |
1935 | state->ri.remote_address.address.ipv6 = *v6; | 2043 | state->ri.remote_address.address.ipv6 = *v6; |
1936 | break; | 2044 | if (NULL == state->heap_node) |
2045 | { | ||
2046 | state->ri.remote_address.af = af; | ||
2047 | state->ri.remote_address.proto = IPPROTO_ICMP; | ||
2048 | setup_state_record (state); | ||
2049 | } | ||
2050 | /* check that ICMP type is something we want to support | ||
2051 | and possibly make up payload! */ | ||
2052 | switch (msg->icmp_header.type) | ||
2053 | { | ||
2054 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | ||
2055 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
2056 | break; | ||
2057 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
2058 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
2059 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
2060 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
2061 | if (0 != pkt_len) | ||
2062 | { | ||
2063 | GNUNET_break_op (0); | ||
2064 | return GNUNET_SYSERR; | ||
2065 | } | ||
2066 | /* make up payload */ | ||
2067 | { | ||
2068 | struct GNUNET_TUN_IPv6Header *ipp = (struct GNUNET_TUN_IPv6Header *) buf; | ||
2069 | struct GNUNET_TUN_UdpHeader *udp = (struct GNUNET_TUN_UdpHeader *) &ipp[1]; | ||
2070 | |||
2071 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2072 | pkt_len = sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
2073 | make_up_icmpv6_payload (state, | ||
2074 | ipp, | ||
2075 | udp); | ||
2076 | payload = ipp; | ||
2077 | } | ||
2078 | break; | ||
2079 | default: | ||
2080 | GNUNET_break_op (0); | ||
2081 | GNUNET_STATISTICS_update (stats, | ||
2082 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
2083 | 1, GNUNET_NO); | ||
2084 | return GNUNET_SYSERR; | ||
2085 | } | ||
2086 | /* end AF_INET6 */ | ||
2087 | break; | ||
1937 | default: | 2088 | default: |
2089 | /* bad AF */ | ||
1938 | GNUNET_break_op (0); | 2090 | GNUNET_break_op (0); |
1939 | return GNUNET_SYSERR; | 2091 | return GNUNET_SYSERR; |
1940 | } | 2092 | } |
@@ -1948,15 +2100,6 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1948 | &state->ri.remote_address.address, | 2100 | &state->ri.remote_address.address, |
1949 | buf, sizeof (buf))); | 2101 | buf, sizeof (buf))); |
1950 | } | 2102 | } |
1951 | |||
1952 | /* FIXME: check that ICMP type is something we want to support */ | ||
1953 | |||
1954 | state->ri.remote_address.proto = IPPROTO_ICMP; | ||
1955 | state->ri.remote_address.port = 0; | ||
1956 | state->ri.local_address.port = 0; | ||
1957 | if (NULL == state->heap_node) | ||
1958 | setup_state_record (state); | ||
1959 | |||
1960 | send_icmp_packet_via_tun (&state->ri.remote_address, | 2103 | send_icmp_packet_via_tun (&state->ri.remote_address, |
1961 | &state->ri.local_address, | 2104 | &state->ri.local_address, |
1962 | &msg->icmp_header, | 2105 | &msg->icmp_header, |
@@ -1966,6 +2109,56 @@ receive_icmp_remote (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel, | |||
1966 | 2109 | ||
1967 | 2110 | ||
1968 | /** | 2111 | /** |
2112 | * Setup ICMP payload for ICMP error messages. Called | ||
2113 | * for both IPv4 and IPv6 addresses. | ||
2114 | * | ||
2115 | * @param state context for creating the IP Packet | ||
2116 | * @param buf where to create the payload, has at least | ||
2117 | * sizeof (struct GNUNET_TUN_IPv6Header) + 8 bytes | ||
2118 | * @return number of bytes of payload we created in buf | ||
2119 | */ | ||
2120 | static uint16_t | ||
2121 | make_up_icmp_service_payload (struct TunnelState *state, | ||
2122 | char *buf) | ||
2123 | { | ||
2124 | switch (state->serv->address.af) | ||
2125 | { | ||
2126 | case AF_INET: | ||
2127 | { | ||
2128 | struct GNUNET_TUN_IPv4Header *ipv4; | ||
2129 | struct GNUNET_TUN_UdpHeader *udp; | ||
2130 | |||
2131 | ipv4 = (struct GNUNET_TUN_IPv4Header *)buf; | ||
2132 | udp = (struct GNUNET_TUN_UdpHeader *) &ipv4[1]; | ||
2133 | make_up_icmpv4_payload (state, | ||
2134 | ipv4, | ||
2135 | udp); | ||
2136 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2137 | return sizeof (struct GNUNET_TUN_IPv4Header) + 8; | ||
2138 | } | ||
2139 | break; | ||
2140 | case AF_INET6: | ||
2141 | { | ||
2142 | struct GNUNET_TUN_IPv6Header *ipv6; | ||
2143 | struct GNUNET_TUN_UdpHeader *udp; | ||
2144 | |||
2145 | ipv6 = (struct GNUNET_TUN_IPv6Header *)buf; | ||
2146 | udp = (struct GNUNET_TUN_UdpHeader *) &ipv6[1]; | ||
2147 | make_up_icmpv6_payload (state, | ||
2148 | ipv6, | ||
2149 | udp); | ||
2150 | GNUNET_assert (8 == sizeof (struct GNUNET_TUN_UdpHeader)); | ||
2151 | return sizeof (struct GNUNET_TUN_IPv6Header) + 8; | ||
2152 | } | ||
2153 | break; | ||
2154 | default: | ||
2155 | GNUNET_break (0); | ||
2156 | } | ||
2157 | return 0; | ||
2158 | } | ||
2159 | |||
2160 | |||
2161 | /** | ||
1969 | * Process a request via mesh to send ICMP data to a service | 2162 | * Process a request via mesh to send ICMP data to a service |
1970 | * offered by this system. | 2163 | * offered by this system. |
1971 | * | 2164 | * |
@@ -1988,6 +2181,9 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
1988 | struct TunnelState *state = *tunnel_ctx; | 2181 | struct TunnelState *state = *tunnel_ctx; |
1989 | const struct GNUNET_EXIT_IcmpServiceMessage *msg; | 2182 | const struct GNUNET_EXIT_IcmpServiceMessage *msg; |
1990 | uint16_t pkt_len = ntohs (message->size); | 2183 | uint16_t pkt_len = ntohs (message->size); |
2184 | struct GNUNET_TUN_IcmpHeader icmp; | ||
2185 | char buf[sizeof (struct GNUNET_TUN_IPv6Header) + 8]; | ||
2186 | const void *payload; | ||
1991 | 2187 | ||
1992 | GNUNET_STATISTICS_update (stats, | 2188 | GNUNET_STATISTICS_update (stats, |
1993 | gettext_noop ("# Bytes received from MESH"), | 2189 | gettext_noop ("# Bytes received from MESH"), |
@@ -2013,23 +2209,141 @@ receive_icmp_service (void *cls GNUNET_UNUSED, struct GNUNET_MESH_Tunnel *tunnel | |||
2013 | GNUNET_break_op (0); | 2209 | GNUNET_break_op (0); |
2014 | return GNUNET_SYSERR; | 2210 | return GNUNET_SYSERR; |
2015 | } | 2211 | } |
2016 | if (state->serv->address.af != ntohl (msg->af)) | 2212 | icmp = msg->icmp_header; |
2213 | payload = &msg[1]; | ||
2214 | state->ri.remote_address = state->serv->address; | ||
2215 | setup_state_record (state); | ||
2216 | |||
2217 | /* check that ICMP type is something we want to support, | ||
2218 | perform ICMP PT if needed ans possibly make up payload */ | ||
2219 | switch (msg->af) | ||
2017 | { | 2220 | { |
2018 | GNUNET_STATISTICS_update (stats, | 2221 | case AF_INET: |
2019 | gettext_noop ("# ICMP service requests discarded (incompatible af)"), | 2222 | switch (msg->icmp_header.type) |
2020 | 1, GNUNET_NO); | 2223 | { |
2224 | case GNUNET_TUN_ICMPTYPE_ECHO_REPLY: | ||
2225 | if (state->serv->address.af == AF_INET6) | ||
2226 | icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REPLY; | ||
2227 | break; | ||
2228 | case GNUNET_TUN_ICMPTYPE_ECHO_REQUEST: | ||
2229 | if (state->serv->address.af == AF_INET6) | ||
2230 | icmp.type = GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST; | ||
2231 | break; | ||
2232 | case GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE: | ||
2233 | if (state->serv->address.af == AF_INET6) | ||
2234 | icmp.type = GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE; | ||
2235 | if (0 != pkt_len) | ||
2236 | { | ||
2237 | GNUNET_break_op (0); | ||
2238 | return GNUNET_SYSERR; | ||
2239 | } | ||
2240 | payload = buf; | ||
2241 | pkt_len = make_up_icmp_service_payload (state, buf); | ||
2242 | break; | ||
2243 | case GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED: | ||
2244 | if (state->serv->address.af == AF_INET6) | ||
2245 | icmp.type = GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED; | ||
2246 | if (0 != pkt_len) | ||
2247 | { | ||
2248 | GNUNET_break_op (0); | ||
2249 | return GNUNET_SYSERR; | ||
2250 | } | ||
2251 | payload = buf; | ||
2252 | pkt_len = make_up_icmp_service_payload (state, buf); | ||
2253 | break; | ||
2254 | case GNUNET_TUN_ICMPTYPE_SOURCE_QUENCH: | ||
2255 | if (state->serv->address.af == AF_INET6) | ||
2256 | { | ||
2257 | GNUNET_STATISTICS_update (stats, | ||
2258 | gettext_noop ("# ICMPv4 packets dropped (impossible PT to v6)"), | ||
2259 | 1, GNUNET_NO); | ||
2260 | return GNUNET_OK; | ||
2261 | } | ||
2262 | if (0 != pkt_len) | ||
2263 | { | ||
2264 | GNUNET_break_op (0); | ||
2265 | return GNUNET_SYSERR; | ||
2266 | } | ||
2267 | payload = buf; | ||
2268 | pkt_len = make_up_icmp_service_payload (state, buf); | ||
2269 | break; | ||
2270 | default: | ||
2271 | GNUNET_break_op (0); | ||
2272 | GNUNET_STATISTICS_update (stats, | ||
2273 | gettext_noop ("# ICMPv4 packets dropped (type not allowed)"), | ||
2274 | 1, GNUNET_NO); | ||
2275 | return GNUNET_SYSERR; | ||
2276 | } | ||
2277 | /* end of AF_INET */ | ||
2278 | break; | ||
2279 | case AF_INET6: | ||
2280 | switch (msg->icmp_header.type) | ||
2281 | { | ||
2282 | case GNUNET_TUN_ICMPTYPE6_ECHO_REPLY: | ||
2283 | if (state->serv->address.af == AF_INET) | ||
2284 | icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REPLY; | ||
2285 | break; | ||
2286 | case GNUNET_TUN_ICMPTYPE6_ECHO_REQUEST: | ||
2287 | if (state->serv->address.af == AF_INET) | ||
2288 | icmp.type = GNUNET_TUN_ICMPTYPE_ECHO_REQUEST; | ||
2289 | break; | ||
2290 | case GNUNET_TUN_ICMPTYPE6_DESTINATION_UNREACHABLE: | ||
2291 | if (state->serv->address.af == AF_INET) | ||
2292 | icmp.type = GNUNET_TUN_ICMPTYPE_DESTINATION_UNREACHABLE; | ||
2293 | if (0 != pkt_len) | ||
2294 | { | ||
2295 | GNUNET_break_op (0); | ||
2296 | return GNUNET_SYSERR; | ||
2297 | } | ||
2298 | payload = buf; | ||
2299 | pkt_len = make_up_icmp_service_payload (state, buf); | ||
2300 | break; | ||
2301 | case GNUNET_TUN_ICMPTYPE6_TIME_EXCEEDED: | ||
2302 | if (state->serv->address.af == AF_INET) | ||
2303 | icmp.type = GNUNET_TUN_ICMPTYPE_TIME_EXCEEDED; | ||
2304 | if (0 != pkt_len) | ||
2305 | { | ||
2306 | GNUNET_break_op (0); | ||
2307 | return GNUNET_SYSERR; | ||
2308 | } | ||
2309 | payload = buf; | ||
2310 | pkt_len = make_up_icmp_service_payload (state, buf); | ||
2311 | break; | ||
2312 | case GNUNET_TUN_ICMPTYPE6_PACKET_TOO_BIG: | ||
2313 | case GNUNET_TUN_ICMPTYPE6_PARAMETER_PROBLEM: | ||
2314 | if (state->serv->address.af == AF_INET) | ||
2315 | { | ||
2316 | GNUNET_STATISTICS_update (stats, | ||
2317 | gettext_noop ("# ICMPv6 packets dropped (impossible PT to v4)"), | ||
2318 | 1, GNUNET_NO); | ||
2319 | return GNUNET_OK; | ||
2320 | } | ||
2321 | if (0 != pkt_len) | ||
2322 | { | ||
2323 | GNUNET_break_op (0); | ||
2324 | return GNUNET_SYSERR; | ||
2325 | } | ||
2326 | payload = buf; | ||
2327 | pkt_len = make_up_icmp_service_payload (state, buf); | ||
2328 | break; | ||
2329 | default: | ||
2330 | GNUNET_break_op (0); | ||
2331 | GNUNET_STATISTICS_update (stats, | ||
2332 | gettext_noop ("# ICMPv6 packets dropped (type not allowed)"), | ||
2333 | 1, GNUNET_NO); | ||
2334 | return GNUNET_SYSERR; | ||
2335 | } | ||
2336 | /* end of AF_INET6 */ | ||
2337 | break; | ||
2338 | default: | ||
2339 | GNUNET_break_op (0); | ||
2021 | return GNUNET_SYSERR; | 2340 | return GNUNET_SYSERR; |
2022 | } | 2341 | } |
2023 | 2342 | ||
2024 | /* FIXME: check that ICMP type is something we want to support */ | ||
2025 | |||
2026 | state->ri.remote_address = state->serv->address; | ||
2027 | setup_state_record (state); | ||
2028 | |||
2029 | send_icmp_packet_via_tun (&state->ri.remote_address, | 2343 | send_icmp_packet_via_tun (&state->ri.remote_address, |
2030 | &state->ri.local_address, | 2344 | &state->ri.local_address, |
2031 | &msg->icmp_header, | 2345 | &icmp, |
2032 | &msg[1], pkt_len); | 2346 | payload, pkt_len); |
2033 | return GNUNET_YES; | 2347 | return GNUNET_YES; |
2034 | } | 2348 | } |
2035 | 2349 | ||