summaryrefslogtreecommitdiffstats
path: root/translate.c
diff options
context:
space:
mode:
authorLorenzo Colitti <lorenzo@google.com>2014-02-13 12:53:35 +0900
committerLorenzo Colitti <lorenzo@google.com>2014-02-14 13:51:14 +0900
commitf9390605bacda7bbe8ea33aa0a39c1581ff6aea2 (patch)
tree3f93c576d9a91fa0bac223435bd69b240cbe84cf /translate.c
parent5a50c0283346a197cda7af19e68f611f14b8fe57 (diff)
downloadandroid_external_android-clat-f9390605bacda7bbe8ea33aa0a39c1581ff6aea2.tar.gz
android_external_android-clat-f9390605bacda7bbe8ea33aa0a39c1581ff6aea2.tar.bz2
android_external_android-clat-f9390605bacda7bbe8ea33aa0a39c1581ff6aea2.zip
Move translation entry point into translate.c.
The entry point to the translation code is currently called packet_handler and lives in clatd.c. Move it into translate.c and rename it to translate_packet, since that's what it does. Also get rid of some redundant includes. Bug: 11542311 Change-Id: I8529fb87f3a86ee6724fad54787c33a5e86c56ab
Diffstat (limited to 'translate.c')
-rw-r--r--translate.c61
1 files changed, 52 insertions, 9 deletions
diff --git a/translate.c b/translate.c
index 9a0f1b5..f7f09cb 100644
--- a/translate.c
+++ b/translate.c
@@ -16,15 +16,7 @@
* translate.c - CLAT functions / partial implementation of rfc6145
*/
#include <string.h>
-
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#include <netinet/udp.h>
-#include <netinet/tcp.h>
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
-#include <linux/icmp.h>
+#include <sys/uio.h>
#include "icmp.h"
#include "translate.h"
@@ -175,6 +167,7 @@ void fill_ip6_header(struct ip6_hdr *ip6, uint16_t payload_len, uint8_t protocol
ip6->ip6_dst = ipv4_addr_to_ipv6_addr(old_header->daddr);
}
+
/* function: icmp_to_icmp6
* translate ipv4 icmp to ipv6 icmp
* out - output packet
@@ -426,3 +419,53 @@ int tcp_translate(clat_packet out, int pos, const struct tcphdr *tcp, size_t hea
return CLAT_POS_PAYLOAD + 1;
}
+
+/* function: translate_packet
+ * takes a tun header and a packet and sends it down the stack
+ * tunnel - tun device data
+ * tun_header - tun header
+ * packet - packet
+ * packetsize - size of packet
+ */
+void translate_packet(const struct tun_data *tunnel, struct tun_pi *tun_header, const char *packet,
+ size_t packetsize) {
+ int fd;
+ int iov_len = 0;
+
+ // Allocate buffers for all packet headers.
+ struct tun_pi tun_targ;
+ char iphdr[sizeof(struct ip6_hdr)];
+ char transporthdr[MAX_TCP_HDR];
+ char icmp_iphdr[sizeof(struct ip6_hdr)];
+ char icmp_transporthdr[MAX_TCP_HDR];
+
+ // iovec of the packets we'll send. This gets passed down to the translation functions.
+ clat_packet out = {
+ { &tun_targ, sizeof(tun_targ) }, // Tunnel header.
+ { iphdr, 0 }, // IP header.
+ { transporthdr, 0 }, // Transport layer header.
+ { icmp_iphdr, 0 }, // ICMP error inner IP header.
+ { icmp_transporthdr, 0 }, // ICMP error transport layer header.
+ { NULL, 0 }, // Payload. No buffer, it's a pointer to the original payload.
+ };
+
+ if(tun_header->flags != 0) {
+ logmsg(ANDROID_LOG_WARN, "translate_packet: unexpected flags = %d", tun_header->flags);
+ }
+
+ if(ntohs(tun_header->proto) == ETH_P_IP) {
+ fd = tunnel->fd6;
+ fill_tun_header(&tun_targ, ETH_P_IPV6);
+ iov_len = ipv4_packet(out, CLAT_POS_IPHDR, packet, packetsize);
+ } else if(ntohs(tun_header->proto) == ETH_P_IPV6) {
+ fd = tunnel->fd4;
+ fill_tun_header(&tun_targ, ETH_P_IP);
+ iov_len = ipv6_packet(out, CLAT_POS_IPHDR, packet, packetsize);
+ } else {
+ logmsg(ANDROID_LOG_WARN, "translate_packet: unknown packet type = %x",tun_header->proto);
+ }
+
+ if (iov_len > 0) {
+ writev(fd, out, iov_len);
+ }
+}