diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-01-21 15:11:58 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-01-21 15:11:58 +0000 |
commit | 57c6b46b6b90ca4d894cb032aff46567d5210654 (patch) | |
tree | a60d6186b28836a74a0f024bf38acbccc1ae7ee1 /src/vpn | |
parent | c8964e3192015a9723ebcd0aed020f503287c9b0 (diff) | |
download | gnunet-57c6b46b6b90ca4d894cb032aff46567d5210654.tar.gz gnunet-57c6b46b6b90ca4d894cb032aff46567d5210654.zip |
-add support for sending ICMP packets to service/internet
Diffstat (limited to 'src/vpn')
-rw-r--r-- | src/vpn/gnunet-service-vpn.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/src/vpn/gnunet-service-vpn.c b/src/vpn/gnunet-service-vpn.c index 8925c034f..47a6a7dc4 100644 --- a/src/vpn/gnunet-service-vpn.c +++ b/src/vpn/gnunet-service-vpn.c | |||
@@ -878,6 +878,7 @@ route_packet (struct DestinationEntry *destination, | |||
878 | int is_new; | 878 | int is_new; |
879 | const struct GNUNET_TUN_UdpHeader *udp; | 879 | const struct GNUNET_TUN_UdpHeader *udp; |
880 | const struct GNUNET_TUN_TcpHeader *tcp; | 880 | const struct GNUNET_TUN_TcpHeader *tcp; |
881 | const struct GNUNET_TUN_IcmpHeader *icmp; | ||
881 | uint16_t spt; | 882 | uint16_t spt; |
882 | uint16_t dpt; | 883 | uint16_t dpt; |
883 | 884 | ||
@@ -923,6 +924,26 @@ route_packet (struct DestinationEntry *destination, | |||
923 | &key); | 924 | &key); |
924 | } | 925 | } |
925 | break; | 926 | break; |
927 | case IPPROTO_ICMP: | ||
928 | { | ||
929 | if (payload_length < sizeof (struct GNUNET_TUN_IcmpHeader)) | ||
930 | { | ||
931 | /* blame kernel? */ | ||
932 | GNUNET_break (0); | ||
933 | return; | ||
934 | } | ||
935 | icmp = payload; | ||
936 | spt = 0; | ||
937 | dpt = 0; | ||
938 | get_tunnel_key_from_ips (af, | ||
939 | IPPROTO_ICMP, | ||
940 | source_ip, | ||
941 | 0, | ||
942 | destination_ip, | ||
943 | 0, | ||
944 | &key); | ||
945 | } | ||
946 | break; | ||
926 | default: | 947 | default: |
927 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 948 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
928 | _("Protocol %u not supported, dropping\n"), | 949 | _("Protocol %u not supported, dropping\n"), |
@@ -1204,6 +1225,80 @@ route_packet (struct DestinationEntry *destination, | |||
1204 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); | 1225 | payload_length - sizeof (struct GNUNET_TUN_TcpHeader)); |
1205 | } | 1226 | } |
1206 | break; | 1227 | break; |
1228 | case IPPROTO_ICMP: | ||
1229 | if (destination->is_service) | ||
1230 | { | ||
1231 | struct GNUNET_EXIT_IcmpServiceMessage *ism; | ||
1232 | |||
1233 | mlen = sizeof (struct GNUNET_EXIT_IcmpServiceMessage) + | ||
1234 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1235 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1236 | { | ||
1237 | GNUNET_break (0); | ||
1238 | return; | ||
1239 | } | ||
1240 | tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + mlen); | ||
1241 | tnq->len = mlen; | ||
1242 | tnq->msg = &tnq[1]; | ||
1243 | ism = (struct GNUNET_EXIT_IcmpServiceMessage *) &tnq[1]; | ||
1244 | ism->header.size = htons ((uint16_t) mlen); | ||
1245 | ism->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_SERVICE); | ||
1246 | ism->af = htonl (af); /* need to tell destination ICMP protocol family! */ | ||
1247 | ism->service_descriptor = destination->details.service_destination.service_descriptor; | ||
1248 | ism->icmp_header = *icmp; | ||
1249 | memcpy (&ism[1], | ||
1250 | &icmp[1], | ||
1251 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); | ||
1252 | } | ||
1253 | else | ||
1254 | { | ||
1255 | struct GNUNET_EXIT_IcmpInternetMessage *iim; | ||
1256 | struct in_addr *ip4dst; | ||
1257 | struct in6_addr *ip6dst; | ||
1258 | void *payload; | ||
1259 | |||
1260 | mlen = sizeof (struct GNUNET_EXIT_IcmpInternetMessage) + | ||
1261 | alen + payload_length - sizeof (struct GNUNET_TUN_IcmpHeader); | ||
1262 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | ||
1263 | { | ||
1264 | GNUNET_break (0); | ||
1265 | return; | ||
1266 | } | ||
1267 | tnq = GNUNET_malloc (sizeof (struct TunnelMessageQueueEntry) + | ||
1268 | mlen); | ||
1269 | tnq->len = mlen; | ||
1270 | tnq->msg = &tnq[1]; | ||
1271 | iim = (struct GNUNET_EXIT_IcmpInternetMessage *) &tnq[1]; | ||
1272 | iim->header.size = htons ((uint16_t) mlen); | ||
1273 | iim->header.type = htons (GNUNET_MESSAGE_TYPE_VPN_ICMP_TO_INTERNET); | ||
1274 | iim->af = htonl (af); /* need to tell destination ICMP protocol family! */ | ||
1275 | iim->icmp_header = *icmp; | ||
1276 | if (af != destination->details.exit_destination.af) | ||
1277 | { | ||
1278 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1279 | _("AF-translation for ICMP not implemented\n")); | ||
1280 | return; | ||
1281 | } | ||
1282 | switch (destination->details.exit_destination.af) | ||
1283 | { | ||
1284 | case AF_INET: | ||
1285 | ip4dst = (struct in_addr *) &iim[1]; | ||
1286 | *ip4dst = destination->details.exit_destination.ip.v4; | ||
1287 | payload = &ip4dst[1]; | ||
1288 | break; | ||
1289 | case AF_INET6: | ||
1290 | ip6dst = (struct in6_addr *) &iim[1]; | ||
1291 | *ip6dst = destination->details.exit_destination.ip.v6; | ||
1292 | payload = &ip6dst[1]; | ||
1293 | break; | ||
1294 | default: | ||
1295 | GNUNET_assert (0); | ||
1296 | } | ||
1297 | memcpy (payload, | ||
1298 | &icmp[1], | ||
1299 | payload_length - sizeof (struct GNUNET_TUN_IcmpHeader)); | ||
1300 | } | ||
1301 | break; | ||
1207 | default: | 1302 | default: |
1208 | /* not supported above, how can we get here !? */ | 1303 | /* not supported above, how can we get here !? */ |
1209 | GNUNET_assert (0); | 1304 | GNUNET_assert (0); |