aboutsummaryrefslogtreecommitdiff
path: root/src/vpn
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2012-01-21 15:11:58 +0000
committerChristian Grothoff <christian@grothoff.org>2012-01-21 15:11:58 +0000
commit57c6b46b6b90ca4d894cb032aff46567d5210654 (patch)
treea60d6186b28836a74a0f024bf38acbccc1ae7ee1 /src/vpn
parentc8964e3192015a9723ebcd0aed020f503287c9b0 (diff)
downloadgnunet-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.c95
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);