From f9390605bacda7bbe8ea33aa0a39c1581ff6aea2 Mon Sep 17 00:00:00 2001 From: Lorenzo Colitti Date: Thu, 13 Feb 2014 12:53:35 +0900 Subject: 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 --- translate.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 9 deletions(-) (limited to 'translate.c') 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 - -#include -#include -#include -#include -#include -#include -#include -#include +#include #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); + } +} -- cgit v1.2.3