summaryrefslogtreecommitdiffstats
path: root/clatd.c
diff options
context:
space:
mode:
Diffstat (limited to 'clatd.c')
-rw-r--r--clatd.c89
1 files changed, 16 insertions, 73 deletions
diff --git a/clatd.c b/clatd.c
index 063026d..a89c588 100644
--- a/clatd.c
+++ b/clatd.c
@@ -29,15 +29,6 @@
#include <arpa/inet.h>
#include <fcntl.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/capability.h>
#include <sys/uio.h>
#include <linux/prctl.h>
@@ -47,8 +38,6 @@
#include <private/android_filesystem_config.h>
-#include "ipv4.h"
-#include "ipv6.h"
#include "translate.h"
#include "clatd.h"
#include "config.h"
@@ -62,14 +51,12 @@
#define DEVICENAME6 "clat"
#define DEVICENAME4 "clat4"
+/* 40 bytes IPv6 header - 20 bytes IPv4 header + 8 bytes fragment header */
+#define MTU_DELTA 28
+
int forwarding_fd = -1;
volatile sig_atomic_t running = 1;
-struct tun_data {
- char device6[IFNAMSIZ], device4[IFNAMSIZ];
- int fd6, fd4;
-};
-
/* function: set_forwarding
* enables/disables ipv6 forwarding
*/
@@ -84,7 +71,7 @@ void set_forwarding(int fd, const char *setting) {
/* function: stop_loop
* signal handler: stop the event loop
*/
-void stop_loop(int signal) {
+void stop_loop() {
running = 0;
}
@@ -146,7 +133,6 @@ void deconfigure_tun_ipv6(const struct tun_data *tunnel) {
* tunnel - tun device data
*/
void configure_tun_ipv6(const struct tun_data *tunnel) {
- struct in6_addr local_nat64_prefix_6;
int status;
status = if_route(tunnel->device6, AF_INET6, &Global_Clatd_Config.ipv6_local_subnet,
@@ -205,6 +191,13 @@ void configure_tun_ip(const struct tun_data *tunnel) {
exit(1);
}
+ status = add_address(tunnel->device6, AF_INET6, &Global_Clatd_Config.ipv6_local_address,
+ 64, NULL);
+ if(status < 0) {
+ logmsg(ANDROID_LOG_FATAL,"configure_tun_ip/if_address(6) failed: %s",strerror(-status));
+ exit(1);
+ }
+
if((status = if_up(tunnel->device6, Global_Clatd_Config.mtu)) < 0) {
logmsg(ANDROID_LOG_FATAL,"configure_tun_ip/if_up(6) failed: %s",strerror(-status));
exit(1);
@@ -281,8 +274,9 @@ void configure_interface(const char *uplink_interface, const char *plat_prefix,
Global_Clatd_Config.mtu = 1280;
}
- if(Global_Clatd_Config.ipv4mtu <= 0 || (Global_Clatd_Config.ipv4mtu > Global_Clatd_Config.mtu - 20)) {
- Global_Clatd_Config.ipv4mtu = Global_Clatd_Config.mtu-20;
+ if(Global_Clatd_Config.ipv4mtu <= 0 ||
+ Global_Clatd_Config.ipv4mtu > Global_Clatd_Config.mtu - MTU_DELTA) {
+ Global_Clatd_Config.ipv4mtu = Global_Clatd_Config.mtu - MTU_DELTA;
logmsg(ANDROID_LOG_WARN,"ipv4mtu now set to = %d",Global_Clatd_Config.ipv4mtu);
}
@@ -301,56 +295,6 @@ void configure_interface(const char *uplink_interface, const char *plat_prefix,
configure_tun_ip(tunnel);
}
-/* function: packet_handler
- * 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 packet_handler(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,"packet_handler: 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,"packet_handler: unknown packet type = %x",tun_header->proto);
- }
-
- if (iov_len > 0) {
- writev(fd, out, iov_len);
- }
-}
-
/* function: read_packet
* reads a packet from the tunnel fd and passes it down the stack
* active_fd - tun file descriptor marked ready for reading
@@ -372,7 +316,6 @@ void read_packet(int active_fd, const struct tun_data *tunnel) {
logmsg(ANDROID_LOG_WARN,"read_packet/tun interface removed");
running = 0;
} else {
- struct tun_pi tun_header;
ssize_t header_size = sizeof(struct tun_pi);
if(readlen < header_size) {
@@ -380,7 +323,7 @@ void read_packet(int active_fd, const struct tun_data *tunnel) {
return;
}
- packet_handler(tunnel, (struct tun_pi *) packet, packet + header_size, readlen - header_size);
+ translate_packet(tunnel, (struct tun_pi *) packet, packet + header_size, readlen - header_size);
}
}
@@ -470,7 +413,7 @@ int main(int argc, char **argv) {
// open the tunnel device before dropping privs
tunnel.fd6 = tun_open();
if(tunnel.fd6 < 0) {
- logmsg(ANDROID_LOG_FATAL, "tun_open failed: %s", strerror(errno));
+ logmsg(ANDROID_LOG_FATAL, "tun_open6 failed: %s", strerror(errno));
exit(1);
}