diff options
author | junyulai <junyulai@google.com> | 2018-11-26 22:36:10 +0900 |
---|---|---|
committer | junyulai <junyulai@google.com> | 2018-12-11 10:12:47 +0800 |
commit | c4e591aa04552541a8ae63af00541baa9046858b (patch) | |
tree | 7f8d90d2ec6145679c647e8759bb47e509663d26 | |
parent | 3850bee1d5dd1eae3c28ce09f8e4bd0c7099c5a8 (diff) | |
download | platform_external_android-clat-c4e591aa04552541a8ae63af00541baa9046858b.tar.gz platform_external_android-clat-c4e591aa04552541a8ae63af00541baa9046858b.tar.bz2 platform_external_android-clat-c4e591aa04552541a8ae63af00541baa9046858b.zip |
Re-indent clatd code with clang-format
clang-format --style file -i *.{c,h,cpp}
Bug: 118848635
Test: 1. browse over ipv6-only network
2. atest clatd_test
3. clang-format --style file -i *.{c,h,cpp}
Change-Id: I7389426101df7745370d0ac5c55176cd8fe2b08b
-rw-r--r-- | checksum.c | 66 | ||||
-rw-r--r-- | checksum.h | 2 | ||||
-rw-r--r-- | clatd.c | 205 | ||||
-rw-r--r-- | clatd.h | 14 | ||||
-rw-r--r-- | clatd_microbenchmark.c | 287 | ||||
-rw-r--r-- | clatd_test.cpp | 236 | ||||
-rw-r--r-- | config.c | 261 | ||||
-rw-r--r-- | config.h | 4 | ||||
-rw-r--r-- | dns64.c | 21 | ||||
-rw-r--r-- | dump.c | 174 | ||||
-rw-r--r-- | dump.h | 26 | ||||
-rw-r--r-- | getaddr.c | 52 | ||||
-rw-r--r-- | icmp.c | 18 | ||||
-rw-r--r-- | ipv4.c | 40 | ||||
-rw-r--r-- | ipv6.c | 38 | ||||
-rw-r--r-- | logging.c | 4 | ||||
-rw-r--r-- | mtu.c | 12 | ||||
-rw-r--r-- | netlink_callbacks.c | 18 | ||||
-rw-r--r-- | netlink_msg.c | 47 | ||||
-rw-r--r-- | ring.c | 46 | ||||
-rw-r--r-- | setif.c | 44 | ||||
-rw-r--r-- | setif.h | 3 | ||||
-rw-r--r-- | translate.c | 150 | ||||
-rw-r--r-- | translate.h | 27 | ||||
-rw-r--r-- | tun.c | 18 |
25 files changed, 907 insertions, 906 deletions
@@ -15,33 +15,33 @@ * * checksum.c - ipv4/ipv6 checksum calculation */ +#include <netinet/icmp6.h> #include <netinet/in.h> #include <netinet/ip.h> +#include <netinet/ip6.h> #include <netinet/ip_icmp.h> -#include <netinet/udp.h> #include <netinet/tcp.h> -#include <netinet/ip6.h> -#include <netinet/icmp6.h> +#include <netinet/udp.h> #include "checksum.h" /* function: ip_checksum_add * adds data to a checksum * current - the current checksum (or 0 to start a new checksum) - * data - the data to add to the checksum - * len - length of data + * data - the data to add to the checksum + * len - length of data */ uint32_t ip_checksum_add(uint32_t current, const void *data, int len) { - uint32_t checksum = current; - int left = len; + uint32_t checksum = current; + int left = len; const uint16_t *data_16 = data; - while(left > 1) { + while (left > 1) { checksum += *data_16; data_16++; left -= 2; } - if(left) { + if (left) { checksum += *(uint8_t *)data_16; } @@ -50,49 +50,48 @@ uint32_t ip_checksum_add(uint32_t current, const void *data, int len) { /* function: ip_checksum_fold * folds a 32-bit partial checksum into 16 bits - * temp_sum - sum from ip_checksum_add - * returns: the folded checksum in network byte order + * temp_sum - sum from ip_checksum_add + * returns: the folded checksum in network byte order */ uint16_t ip_checksum_fold(uint32_t temp_sum) { - while(temp_sum > 0xffff) + while (temp_sum > 0xffff) { temp_sum = (temp_sum >> 16) + (temp_sum & 0xFFFF); - + } return temp_sum; } /* function: ip_checksum_finish * folds and closes the checksum - * temp_sum - sum from ip_checksum_add - * returns: a header checksum value in network byte order + * temp_sum - sum from ip_checksum_add + * returns: a header checksum value in network byte order */ -uint16_t ip_checksum_finish(uint32_t temp_sum) { - return ~ip_checksum_fold(temp_sum); -} +uint16_t ip_checksum_finish(uint32_t temp_sum) { return ~ip_checksum_fold(temp_sum); } /* function: ip_checksum * combined ip_checksum_add and ip_checksum_finish - * data - data to checksum - * len - length of data + * data - data to checksum + * len - length of data */ uint16_t ip_checksum(const void *data, int len) { uint32_t temp_sum; - temp_sum = ip_checksum_add(0,data,len); + temp_sum = ip_checksum_add(0, data, len); return ip_checksum_finish(temp_sum); } /* function: ipv6_pseudo_header_checksum * calculate the pseudo header checksum for use in tcp/udp/icmp headers - * ip6 - the ipv6 header - * len - the transport length (transport header + payload) - * protocol - the transport layer protocol, can be different from ip6->ip6_nxt for fragments + * ip6 - the ipv6 header + * len - the transport length (transport header + payload) + * protocol - the transport layer protocol, can be different from ip6->ip6_nxt for fragments */ uint32_t ipv6_pseudo_header_checksum(const struct ip6_hdr *ip6, uint16_t len, uint8_t protocol) { uint32_t checksum_len, checksum_next; - checksum_len = htonl((uint32_t) len); + checksum_len = htonl((uint32_t)len); checksum_next = htonl(protocol); uint32_t current = 0; + current = ip_checksum_add(current, &(ip6->ip6_src), sizeof(struct in6_addr)); current = ip_checksum_add(current, &(ip6->ip6_dst), sizeof(struct in6_addr)); current = ip_checksum_add(current, &checksum_len, sizeof(checksum_len)); @@ -103,16 +102,17 @@ uint32_t ipv6_pseudo_header_checksum(const struct ip6_hdr *ip6, uint16_t len, ui /* function: ipv4_pseudo_header_checksum * calculate the pseudo header checksum for use in tcp/udp headers - * ip - the ipv4 header - * len - the transport length (transport header + payload) + * ip - the ipv4 header + * len - the transport length (transport header + payload) */ uint32_t ipv4_pseudo_header_checksum(const struct iphdr *ip, uint16_t len) { uint16_t temp_protocol, temp_length; temp_protocol = htons(ip->protocol); - temp_length = htons(len); + temp_length = htons(len); uint32_t current = 0; + current = ip_checksum_add(current, &(ip->saddr), sizeof(uint32_t)); current = ip_checksum_add(current, &(ip->daddr), sizeof(uint32_t)); current = ip_checksum_add(current, &temp_protocol, sizeof(uint16_t)); @@ -123,15 +123,15 @@ uint32_t ipv4_pseudo_header_checksum(const struct iphdr *ip, uint16_t len) { /* function: ip_checksum_adjust * calculates a new checksum given a previous checksum and the old and new pseudo-header checksums - * checksum - the header checksum in the original packet in network byte order - * old_hdr_sum - the pseudo-header checksum of the original packet - * new_hdr_sum - the pseudo-header checksum of the translated packet - * returns: the new header checksum in network byte order + * checksum - the header checksum in the original packet in network byte order + * old_hdr_sum - the pseudo-header checksum of the original packet + * new_hdr_sum - the pseudo-header checksum of the translated packet + * returns: the new header checksum in network byte order */ uint16_t ip_checksum_adjust(uint16_t checksum, uint32_t old_hdr_sum, uint32_t new_hdr_sum) { // Algorithm suggested in RFC 1624. // http://tools.ietf.org/html/rfc1624#section-3 - checksum = ~checksum; + checksum = ~checksum; uint16_t folded_sum = ip_checksum_fold(checksum + new_hdr_sum); uint16_t folded_old = ip_checksum_fold(old_hdr_sum); if (folded_sum > folded_old) { @@ -18,9 +18,9 @@ #ifndef __CHECKSUM_H__ #define __CHECKSUM_H__ -#include <stdint.h> #include <netinet/ip.h> #include <netinet/ip6.h> +#include <stdint.h> uint32_t ip_checksum_add(uint32_t current, const void *data, int len); uint16_t ip_checksum_finish(uint32_t temp_sum); @@ -15,43 +15,43 @@ * * clatd.c - tun interface setup and main event loop */ +#include <arpa/inet.h> +#include <errno.h> +#include <fcntl.h> #include <poll.h> #include <signal.h> -#include <time.h> #include <stdio.h> -#include <sys/types.h> +#include <stdlib.h> +#include <string.h> #include <sys/ioctl.h> #include <sys/prctl.h> #include <sys/stat.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> +#include <sys/types.h> +#include <time.h> #include <unistd.h> -#include <arpa/inet.h> -#include <fcntl.h> -#include <sys/capability.h> -#include <sys/uio.h> #include <linux/filter.h> #include <linux/if.h> -#include <linux/if_tun.h> #include <linux/if_ether.h> #include <linux/if_packet.h> +#include <linux/if_tun.h> #include <net/if.h> +#include <sys/capability.h> +#include <sys/uio.h> #include <private/android_filesystem_config.h> -#include "translate.h" #include "clatd.h" #include "config.h" +#include "dump.h" +#include "getaddr.h" #include "logging.h" +#include "mtu.h" #include "resolv_netid.h" +#include "ring.h" #include "setif.h" -#include "mtu.h" -#include "getaddr.h" -#include "dump.h" +#include "translate.h" #include "tun.h" -#include "ring.h" #define DEVICEPREFIX "v4-" @@ -63,13 +63,11 @@ volatile sig_atomic_t running = 1; /* function: stop_loop * signal handler: stop the event loop */ -void stop_loop() { - running = 0; -} +void stop_loop() { running = 0; } /* function: configure_packet_socket * Binds the packet socket and attaches the receive filter to it. - * sock - the socket to configure + * sock - the socket to configure */ int configure_packet_socket(int sock) { struct sockaddr_ll sll = { @@ -78,12 +76,14 @@ int configure_packet_socket(int sock) { .sll_ifindex = if_nametoindex(Global_Clatd_Config.default_pdp_interface), .sll_pkttype = PACKET_OTHERHOST, // The 464xlat IPv6 address is not assigned to the kernel. }; - if (bind(sock, (struct sockaddr *) &sll, sizeof(sll))) { + if (bind(sock, (struct sockaddr *)&sll, sizeof(sll))) { logmsg(ANDROID_LOG_FATAL, "binding packet socket: %s", strerror(errno)); return 0; } uint32_t *ipv6 = Global_Clatd_Config.ipv6_local_subnet.s6_addr32; + + // clang-format off struct sock_filter filter_code[] = { // Load the first four bytes of the IPv6 destination address (starts 24 bytes in). // Compare it against the first four bytes of our IPv6 address, in host byte order (BPF loads @@ -99,12 +99,10 @@ int configure_packet_socket(int sock) { BPF_STMT(BPF_LD | BPF_W | BPF_ABS, 36), BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, htonl(ipv6[3]), 0, 1), BPF_STMT(BPF_RET | BPF_K, PACKETLEN), - BPF_STMT(BPF_RET | BPF_K, 0) - }; - struct sock_fprog filter = { - sizeof(filter_code) / sizeof(filter_code[0]), - filter_code + BPF_STMT(BPF_RET | BPF_K, 0), }; + // clang-format on + struct sock_fprog filter = { sizeof(filter_code) / sizeof(filter_code[0]), filter_code }; if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter))) { logmsg(ANDROID_LOG_FATAL, "attach packet filter failed: %s", strerror(errno)); @@ -116,7 +114,7 @@ int configure_packet_socket(int sock) { /* function: configure_tun_ip * configures the ipv4 and ipv6 addresses on the tunnel interface - * tunnel - tun device data + * tunnel - tun device data */ void configure_tun_ip(const struct tun_data *tunnel) { int status; @@ -130,7 +128,7 @@ void configure_tun_ip(const struct tun_data *tunnel) { in_addr_t localaddr = config_select_ipv4_address(&Global_Clatd_Config.ipv4_local_subnet, Global_Clatd_Config.ipv4_local_prefixlen); if (localaddr == INADDR_NONE) { - logmsg(ANDROID_LOG_FATAL,"No free IPv4 address in %s/%d", + logmsg(ANDROID_LOG_FATAL, "No free IPv4 address in %s/%d", inet_ntoa(Global_Clatd_Config.ipv4_local_subnet), Global_Clatd_Config.ipv4_local_prefixlen); exit(1); @@ -139,10 +137,10 @@ void configure_tun_ip(const struct tun_data *tunnel) { // Configure the interface before bringing it up. As soon as we bring the interface up, the // framework will be notified and will assume the interface's configuration has been finalized. - status = add_address(tunnel->device4, AF_INET, &Global_Clatd_Config.ipv4_local_subnet, - 32, &Global_Clatd_Config.ipv4_local_subnet); - if(status < 0) { - logmsg(ANDROID_LOG_FATAL,"configure_tun_ip/if_address(4) failed: %s",strerror(-status)); + status = add_address(tunnel->device4, AF_INET, &Global_Clatd_Config.ipv4_local_subnet, 32, + &Global_Clatd_Config.ipv4_local_subnet); + if (status < 0) { + logmsg(ANDROID_LOG_FATAL, "configure_tun_ip/if_address(4) failed: %s", strerror(-status)); exit(1); } @@ -150,8 +148,8 @@ void configure_tun_ip(const struct tun_data *tunnel) { inet_ntop(AF_INET, &Global_Clatd_Config.ipv4_local_subnet, addrstr, sizeof(addrstr)); logmsg(ANDROID_LOG_INFO, "Using IPv4 address %s on %s", addrstr, tunnel->device4); - if((status = if_up(tunnel->device4, Global_Clatd_Config.ipv4mtu)) < 0) { - logmsg(ANDROID_LOG_FATAL,"configure_tun_ip/if_up(4) failed: %s",strerror(-status)); + if ((status = if_up(tunnel->device4, Global_Clatd_Config.ipv4mtu)) < 0) { + logmsg(ANDROID_LOG_FATAL, "configure_tun_ip/if_up(4) failed: %s", strerror(-status)); exit(1); } } @@ -161,19 +159,19 @@ void configure_tun_ip(const struct tun_data *tunnel) { */ void drop_root() { gid_t groups[] = { AID_INET, AID_VPN }; - if(setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0) { - logmsg(ANDROID_LOG_FATAL,"drop_root/setgroups failed: %s",strerror(errno)); + if (setgroups(sizeof(groups) / sizeof(groups[0]), groups) < 0) { + logmsg(ANDROID_LOG_FATAL, "drop_root/setgroups failed: %s", strerror(errno)); exit(1); } prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); - if(setgid(AID_CLAT) < 0) { - logmsg(ANDROID_LOG_FATAL,"drop_root/setgid failed: %s",strerror(errno)); + if (setgid(AID_CLAT) < 0) { + logmsg(ANDROID_LOG_FATAL, "drop_root/setgid failed: %s", strerror(errno)); exit(1); } - if(setuid(AID_CLAT) < 0) { - logmsg(ANDROID_LOG_FATAL,"drop_root/setuid failed: %s",strerror(errno)); + if (setuid(AID_CLAT) < 0) { + logmsg(ANDROID_LOG_FATAL, "drop_root/setuid failed: %s", strerror(errno)); exit(1); } @@ -183,19 +181,19 @@ void drop_root() { memset(&cap, 0, sizeof(cap)); header.version = _LINUX_CAPABILITY_VERSION; - header.pid = 0; // 0 = change myself + header.pid = 0; // 0 = change myself cap.effective = cap.permitted = (1 << CAP_NET_ADMIN); - if(capset(&header, &cap) < 0) { - logmsg(ANDROID_LOG_FATAL,"drop_root/capset failed: %s",strerror(errno)); + if (capset(&header, &cap) < 0) { + logmsg(ANDROID_LOG_FATAL, "drop_root/capset failed: %s", strerror(errno)); exit(1); } } /* function: open_sockets * opens a packet socket to receive IPv6 packets and a raw socket to send them - * tunnel - tun device data - * mark - the socket mark to use for the sending raw socket + * tunnel - tun device data + * mark - the socket mark to use for the sending raw socket */ void open_sockets(struct tun_data *tunnel, uint32_t mark) { int rawsock = socket(AF_INET6, SOCK_RAW | SOCK_NONBLOCK, IPPROTO_RAW); @@ -222,9 +220,9 @@ void open_sockets(struct tun_data *tunnel, uint32_t mark) { /* function: update_clat_ipv6_address * picks the clat IPv6 address and configures packet translation to use it. - * tunnel - tun device data - * interface - uplink interface name - * returns: 1 on success, 0 on failure + * tunnel - tun device data + * interface - uplink interface name + * returns: 1 on success, 0 on failure */ int update_clat_ipv6_address(const struct tun_data *tunnel, const char *interface) { union anyip *interface_ip; @@ -266,9 +264,9 @@ int update_clat_ipv6_address(const struct tun_data *tunnel, const char *interfac // Update our packet socket filter to reflect the new 464xlat IP address. if (!configure_packet_socket(tunnel->read_fd6)) { - // Things aren't going to work. Bail out and hope we have better luck next time. - // We don't log an error here because configure_packet_socket has already done so. - exit(1); + // Things aren't going to work. Bail out and hope we have better luck next time. + // We don't log an error here because configure_packet_socket has already done so. + exit(1); } return 1; @@ -276,41 +274,42 @@ int update_clat_ipv6_address(const struct tun_data *tunnel, const char *interfac /* function: configure_interface * reads the configuration and applies it to the interface - * uplink_interface - network interface to use to reach the ipv6 internet - * plat_prefix - PLAT prefix to use - * tunnel - tun device data - * net_id - NetID to use, NETID_UNSET indicates use of default network + * uplink_interface - network interface to use to reach the ipv6 internet + * plat_prefix - PLAT prefix to use + * tunnel - tun device data + * net_id - NetID to use, NETID_UNSET indicates use of default network */ -void configure_interface(const char *uplink_interface, const char *plat_prefix, struct tun_data *tunnel, unsigned net_id) { +void configure_interface(const char *uplink_interface, const char *plat_prefix, + struct tun_data *tunnel, unsigned net_id) { int error; - if(!read_config("/system/etc/clatd.conf", uplink_interface, plat_prefix, net_id)) { - logmsg(ANDROID_LOG_FATAL,"read_config failed"); + if (!read_config("/system/etc/clatd.conf", uplink_interface, plat_prefix, net_id)) { + logmsg(ANDROID_LOG_FATAL, "read_config failed"); exit(1); } - if(Global_Clatd_Config.mtu > MAXMTU) { - logmsg(ANDROID_LOG_WARN,"Max MTU is %d, requested %d", MAXMTU, Global_Clatd_Config.mtu); + if (Global_Clatd_Config.mtu > MAXMTU) { + logmsg(ANDROID_LOG_WARN, "Max MTU is %d, requested %d", MAXMTU, Global_Clatd_Config.mtu); Global_Clatd_Config.mtu = MAXMTU; } - if(Global_Clatd_Config.mtu <= 0) { + if (Global_Clatd_Config.mtu <= 0) { Global_Clatd_Config.mtu = getifmtu(Global_Clatd_Config.default_pdp_interface); - logmsg(ANDROID_LOG_WARN,"ifmtu=%d",Global_Clatd_Config.mtu); + logmsg(ANDROID_LOG_WARN, "ifmtu=%d", Global_Clatd_Config.mtu); } - if(Global_Clatd_Config.mtu < 1280) { - logmsg(ANDROID_LOG_WARN,"mtu too small = %d", Global_Clatd_Config.mtu); + if (Global_Clatd_Config.mtu < 1280) { + logmsg(ANDROID_LOG_WARN, "mtu too small = %d", Global_Clatd_Config.mtu); Global_Clatd_Config.mtu = 1280; } - if(Global_Clatd_Config.ipv4mtu <= 0 || - Global_Clatd_Config.ipv4mtu > Global_Clatd_Config.mtu - MTU_DELTA) { + 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); + logmsg(ANDROID_LOG_WARN, "ipv4mtu now set to = %d", Global_Clatd_Config.ipv4mtu); } error = tun_alloc(tunnel->device4, tunnel->fd4); - if(error < 0) { - logmsg(ANDROID_LOG_FATAL,"tun_alloc/4 failed: %s",strerror(errno)); + if (error < 0) { + logmsg(ANDROID_LOG_FATAL, "tun_alloc/4 failed: %s", strerror(errno)); exit(1); } @@ -325,9 +324,9 @@ void configure_interface(const char *uplink_interface, const char *plat_prefix, /* function: read_packet * reads a packet from the tunnel fd and translates it - * read_fd - file descriptor to read original packet from - * write_fd - file descriptor to write translated packet to - * to_ipv6 - whether the packet is to be translated to ipv6 or ipv4 + * read_fd - file descriptor to read original packet from + * write_fd - file descriptor to write translated packet to + * to_ipv6 - whether the packet is to be translated to ipv6 or ipv4 */ void read_packet(int read_fd, int write_fd, int to_ipv6) { ssize_t readlen; @@ -335,20 +334,20 @@ void read_packet(int read_fd, int write_fd, int to_ipv6) { readlen = read(read_fd, buf, PACKETLEN); - if(readlen < 0) { + if (readlen < 0) { if (errno != EAGAIN) { - logmsg(ANDROID_LOG_WARN,"read_packet/read error: %s", strerror(errno)); + logmsg(ANDROID_LOG_WARN, "read_packet/read error: %s", strerror(errno)); } return; - } else if(readlen == 0) { - logmsg(ANDROID_LOG_WARN,"read_packet/tun interface removed"); + } else if (readlen == 0) { + logmsg(ANDROID_LOG_WARN, "read_packet/tun interface removed"); running = 0; return; } - struct tun_pi *tun_header = (struct tun_pi *) buf; - if (readlen < (ssize_t) sizeof(*tun_header)) { - logmsg(ANDROID_LOG_WARN,"read_packet/short read: got %ld bytes", readlen); + struct tun_pi *tun_header = (struct tun_pi *)buf; + if (readlen < (ssize_t)sizeof(*tun_header)) { + logmsg(ANDROID_LOG_WARN, "read_packet/short read: got %ld bytes", readlen); return; } @@ -358,18 +357,18 @@ void read_packet(int read_fd, int write_fd, int to_ipv6) { return; } - if(tun_header->flags != 0) { + if (tun_header->flags != 0) { logmsg(ANDROID_LOG_WARN, "%s: unexpected flags = %d", __func__, tun_header->flags); } - packet = (uint8_t *) (tun_header + 1); + packet = (uint8_t *)(tun_header + 1); readlen -= sizeof(*tun_header); translate_packet(write_fd, to_ipv6, packet, readlen); } /* function: event_loop * reads packets from the tun network interface and passes them down the stack - * tunnel - tun device data + * tunnel - tun device data */ void event_loop(struct tun_data *tunnel) { time_t last_interface_poll; @@ -381,11 +380,10 @@ void event_loop(struct tun_data *tunnel) { // start the poll timer last_interface_poll = time(NULL); - while(running) { - if (poll(wait_fd, ARRAY_SIZE(wait_fd), - NO_TRAFFIC_INTERFACE_POLL_FREQUENCY * 1000) == -1) { + while (running) { + if (poll(wait_fd, ARRAY_SIZE(wait_fd), NO_TRAFFIC_INTERFACE_POLL_FREQUENCY * 1000) == -1) { if (errno != EINTR) { - logmsg(ANDROID_LOG_WARN,"event_loop/poll returned an error: %s", strerror(errno)); + logmsg(ANDROID_LOG_WARN, "event_loop/poll returned an error: %s", strerror(errno)); } } else { if (wait_fd[0].revents & POLLIN) { @@ -395,8 +393,7 @@ void event_loop(struct tun_data *tunnel) { if (wait_fd[0].revents & ~POLLIN) { // ring_read doesn't clear the error indication on the socket. recv(tunnel->read_fd6, NULL, 0, MSG_PEEK); - logmsg(ANDROID_LOG_WARN, "event_loop: clearing error on read_fd6: %s", - strerror(errno)); + logmsg(ANDROID_LOG_WARN, "event_loop: clearing error on read_fd6: %s", strerror(errno)); } // Call read_packet if the socket has data to be read, but also if an @@ -410,7 +407,7 @@ void event_loop(struct tun_data *tunnel) { } time_t now = time(NULL); - if(last_interface_poll < (now - INTERFACE_POLL_FREQUENCY)) { + if (last_interface_poll < (now - INTERFACE_POLL_FREQUENCY)) { update_clat_ipv6_address(tunnel, Global_Clatd_Config.default_pdp_interface); last_interface_poll = now; } @@ -430,13 +427,13 @@ void print_help() { /* function: parse_unsigned * parses a string as a decimal/hex/octal unsigned integer - * str - the string to parse - * out - the unsigned integer to write to, gets clobbered on failure + * str - the string to parse + * out - the unsigned integer to write to, gets clobbered on failure */ int parse_unsigned(const char *str, unsigned *out) { - char *end_ptr; - *out = strtoul(str, &end_ptr, 0); - return *str && !*end_ptr; + char *end_ptr; + *out = strtoul(str, &end_ptr, 0); + return *str && !*end_ptr; } /* function: main @@ -447,11 +444,11 @@ int main(int argc, char **argv) { int opt; char *uplink_interface = NULL, *plat_prefix = NULL, *net_id_str = NULL, *mark_str = NULL; unsigned net_id = NETID_UNSET; - uint32_t mark = MARK_UNSET; + uint32_t mark = MARK_UNSET; unsigned len; - while((opt = getopt(argc, argv, "i:p:n:m:h")) != -1) { - switch(opt) { + while ((opt = getopt(argc, argv, "i:p:n:m:h")) != -1) { + switch (opt) { case 'i': uplink_interface = optarg; break; @@ -468,12 +465,12 @@ int main(int argc, char **argv) { print_help(); exit(0); default: - logmsg(ANDROID_LOG_FATAL, "Unknown option -%c. Exiting.", (char) optopt); + logmsg(ANDROID_LOG_FATAL, "Unknown option -%c. Exiting.", (char)optopt); exit(1); } } - if(uplink_interface == NULL) { + if (uplink_interface == NULL) { logmsg(ANDROID_LOG_FATAL, "clatd called without an interface"); exit(1); } @@ -494,10 +491,8 @@ int main(int argc, char **argv) { exit(1); } - logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s netid=%s mark=%s", - CLATD_VERSION, uplink_interface, - net_id_str ? net_id_str : "(none)", - mark_str ? mark_str : "(none)"); + logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s netid=%s mark=%s", CLATD_VERSION, + uplink_interface, net_id_str ? net_id_str : "(none)", mark_str ? mark_str : "(none)"); // open our raw sockets before dropping privs open_sockets(&tunnel, mark); @@ -507,7 +502,7 @@ int main(int argc, char **argv) { // we can create tun devices as non-root because we're in the VPN group. tunnel.fd4 = tun_open(); - if(tunnel.fd4 < 0) { + if (tunnel.fd4 < 0) { logmsg(ANDROID_LOG_FATAL, "tun_open4 failed: %s", strerror(errno)); exit(1); } @@ -522,14 +517,14 @@ int main(int argc, char **argv) { update_clat_ipv6_address(&tunnel, uplink_interface); // Loop until someone sends us a signal or brings down the tun interface. - if(signal(SIGTERM, stop_loop) == SIG_ERR) { + if (signal(SIGTERM, stop_loop) == SIG_ERR) { logmsg(ANDROID_LOG_FATAL, "sigterm handler failed: %s", strerror(errno)); exit(1); } event_loop(&tunnel); - logmsg(ANDROID_LOG_INFO,"Shutting down clat on %s", uplink_interface); + logmsg(ANDROID_LOG_INFO, "Shutting down clat on %s", uplink_interface); del_anycast_address(tunnel.write_fd6, &Global_Clatd_Config.ipv6_local_subnet); return 0; @@ -21,7 +21,7 @@ #include <sys/uio.h> #define MAXMTU 1500 -#define PACKETLEN (MAXMTU+sizeof(struct tun_pi)) +#define PACKETLEN (MAXMTU + sizeof(struct tun_pi)) #define CLATD_VERSION "1.4" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) @@ -37,9 +37,15 @@ // specific parts of the packet. The packet_* functions operate on all the packet segments past a // given position. typedef enum { - CLAT_POS_TUNHDR, CLAT_POS_IPHDR, CLAT_POS_FRAGHDR, CLAT_POS_TRANSPORTHDR, - CLAT_POS_ICMPERR_IPHDR, CLAT_POS_ICMPERR_FRAGHDR, CLAT_POS_ICMPERR_TRANSPORTHDR, - CLAT_POS_PAYLOAD, CLAT_POS_MAX + CLAT_POS_TUNHDR, + CLAT_POS_IPHDR, + CLAT_POS_FRAGHDR, + CLAT_POS_TRANSPORTHDR, + CLAT_POS_ICMPERR_IPHDR, + CLAT_POS_ICMPERR_FRAGHDR, + CLAT_POS_ICMPERR_TRANSPORTHDR, + CLAT_POS_PAYLOAD, + CLAT_POS_MAX } clat_packet_index; typedef struct iovec clat_packet[CLAT_POS_MAX]; diff --git a/clatd_microbenchmark.c b/clatd_microbenchmark.c index fed3100..83be006 100644 --- a/clatd_microbenchmark.c +++ b/clatd_microbenchmark.c @@ -21,25 +21,25 @@ * adb shell /data/nativetest/clatd_microbenchmark/clatd_microbenchmark * */ +#include <arpa/inet.h> #include <errno.h> #include <fcntl.h> -#include <string.h> +#include <linux/if.h> +#include <linux/if_tun.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/ip6.h> +#include <netinet/udp.h> #include <stdio.h> #include <stdlib.h> -#include <time.h> -#include <unistd.h> +#include <string.h> #include <sys/ioctl.h> #include <sys/socket.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/uio.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netinet/ip6.h> -#include <netinet/udp.h> -#include <arpa/inet.h> -#include <linux/if.h> -#include <linux/if_tun.h> +#include <time.h> +#include <unistd.h> #include "checksum.h" #include "tun.h" @@ -52,163 +52,162 @@ #define SEC_TO_NANOSEC (1000 * 1000 * 1000) void init_sockaddr_in(struct sockaddr_in *sin, const char *addr) { - sin->sin_family = AF_INET; - sin->sin_port = 0; - sin->sin_addr.s_addr = inet_addr(addr); + sin->sin_family = AF_INET; + sin->sin_port = 0; + sin->sin_addr.s_addr = inet_addr(addr); } void die(const char *str) { - perror(str); - exit(1); + perror(str); + exit(1); } int setup_tun() { - int fd = tun_open(); - if (fd == -1) die("tun_open"); - - char dev[IFNAMSIZ] = DEVICENAME; - int ret = tun_alloc(dev, fd); - if (ret == -1) die("tun_alloc"); - struct ifreq ifr = { - .ifr_name = DEVICENAME, - }; - - int s = socket(AF_INET, SOCK_DGRAM, 0); - init_sockaddr_in((struct sockaddr_in *) &ifr.ifr_addr, "192.0.0.4"); - if (ioctl(s, SIOCSIFADDR, &ifr) < 0) die("SIOCSIFADDR"); - init_sockaddr_in((struct sockaddr_in *) &ifr.ifr_addr, "255.255.255.248"); - if (ioctl(s, SIOCSIFNETMASK, &ifr) < 0) die("SIOCSIFNETMASK"); - if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) die("SIOCGIFFLAGS"); - ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); - if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) die("SIOCSIFFLAGS"); - return fd; + int fd = tun_open(); + if (fd == -1) die("tun_open"); + + char dev[IFNAMSIZ] = DEVICENAME; + int ret = tun_alloc(dev, fd); + if (ret == -1) die("tun_alloc"); + struct ifreq ifr = { + .ifr_name = DEVICENAME, + }; + + int s = socket(AF_INET, SOCK_DGRAM, 0); + init_sockaddr_in((struct sockaddr_in *)&ifr.ifr_addr, "192.0.0.4"); + if (ioctl(s, SIOCSIFADDR, &ifr) < 0) die("SIOCSIFADDR"); + init_sockaddr_in((struct sockaddr_in *)&ifr.ifr_addr, "255.255.255.248"); + if (ioctl(s, SIOCSIFNETMASK, &ifr) < 0) die("SIOCSIFNETMASK"); + if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) die("SIOCGIFFLAGS"); + ifr.ifr_flags |= (IFF_UP | IFF_RUNNING); + if (ioctl(s, SIOCSIFFLAGS, &ifr) < 0) die("SIOCSIFFLAGS"); + return fd; } int send_packet(int fd, uint8_t payload[], int len, uint32_t payload_checksum) { - struct tun_pi tun = { 0, htons(ETH_P_IP) }; - struct udphdr udp = { - .source = htons(1234), - .dest = htons(PORT), - .len = htons(len + sizeof(udp)), - .check = 0, - }; - struct iphdr ip = { - .version = 4, - .ihl = 5, - .tot_len = htons(len + sizeof(ip) + sizeof(udp)), - .frag_off = htons(IP_DF), - .ttl = 55, - .protocol = IPPROTO_UDP, - .saddr = htonl(0xc0000006), // 192.0.0.6 - .daddr = htonl(0xc0000004), // 192.0.0.4 - }; - clat_packet out = { - { &tun, sizeof(tun) }, // tun header - { &ip, sizeof(ip) }, // IP header - { NULL, 0 }, // Fragment header - { &udp, sizeof(udp) }, // Transport header - { NULL, 0 }, // ICMP error IP header - { NULL, 0 }, // ICMP error fragment header - { NULL, 0 }, // ICMP error transport header - { payload, len }, // Payload - }; - - ip.check = ip_checksum(&ip, sizeof(ip)); - - uint32_t sum; - sum = ipv4_pseudo_header_checksum(&ip, ntohs(udp.len)); - sum = ip_checksum_add(sum, &udp, sizeof(udp)); - sum += payload_checksum; - udp.check = ip_checksum_finish(sum); - - return send_tun(fd, out, sizeof(out) / sizeof(out[0])); + struct tun_pi tun = { 0, htons(ETH_P_IP) }; + struct udphdr udp = { + .source = htons(1234), + .dest = htons(PORT), + .len = htons(len + sizeof(udp)), + .check = 0, + }; + struct iphdr ip = { + .version = 4, + .ihl = 5, + .tot_len = htons(len + sizeof(ip) + sizeof(udp)), + .frag_off = htons(IP_DF), + .ttl = 55, + .protocol = IPPROTO_UDP, + .saddr = htonl(0xc0000006), // 192.0.0.6 + .daddr = htonl(0xc0000004), // 192.0.0.4 + }; + clat_packet out = { + { &tun, sizeof(tun) }, // tun header + { &ip, sizeof(ip) }, // IP header + { NULL, 0 }, // Fragment header + { &udp, sizeof(udp) }, // Transport header + { NULL, 0 }, // ICMP error IP header + { NULL, 0 }, // ICMP error fragment header + { NULL, 0 }, // ICMP error transport header + { payload, len }, // Payload + }; + + ip.check = ip_checksum(&ip, sizeof(ip)); + + uint32_t sum; + sum = ipv4_pseudo_header_checksum(&ip, ntohs(udp.len)); + sum = ip_checksum_add(sum, &udp, sizeof(udp)); + sum += payload_checksum; + udp.check = ip_checksum_finish(sum); + + return send_tun(fd, out, sizeof(out) / sizeof(out[0])); } double timedelta(const struct timespec tv1, const struct timespec tv2) { - struct timespec end = tv2; - if (end.tv_nsec < tv1.tv_nsec) { - end.tv_sec -= 1; - end.tv_nsec += SEC_TO_NANOSEC; - } - double seconds = (end.tv_sec - tv1.tv_sec); - seconds += (((double) (end.tv_nsec - tv1.tv_nsec)) / SEC_TO_NANOSEC); - return seconds; + struct timespec end = tv2; + if (end.tv_nsec < tv1.tv_nsec) { + end.tv_sec -= 1; + end.tv_nsec += SEC_TO_NANOSEC; + } + double seconds = (end.tv_sec - tv1.tv_sec); + seconds += (((double)(end.tv_nsec - tv1.tv_nsec)) / SEC_TO_NANOSEC); + return seconds; } -void benchmark(const char *name, int fd, int s, int num, int do_read, - uint8_t payload[], int len, uint32_t payload_sum) { - int i; - char buf[4096]; - struct timespec tv1, tv2; - int write_err = 0, read_err = 0; - clock_gettime(CLOCK_MONOTONIC, &tv1); - for (i = 0; i < num; i++) { - if (send_packet(fd, payload, len, payload_sum) == -1) write_err++; - if (do_read && recvfrom(s, buf, sizeof(buf), 0, NULL, NULL) == -1) { - read_err++; - if (errno == ETIMEDOUT) { - printf("Timed out after %d packets!\n", i); - break; - } - } +void benchmark(const char *name, int fd, int s, int num, int do_read, uint8_t payload[], int len, + uint32_t payload_sum) { + int i; + char buf[4096]; + struct timespec tv1, tv2; + int write_err = 0, read_err = 0; + clock_gettime(CLOCK_MONOTONIC, &tv1); + for (i = 0; i < num; i++) { + if (send_packet(fd, payload, len, payload_sum) == -1) write_err++; + if (do_read && recvfrom(s, buf, sizeof(buf), 0, NULL, NULL) == -1) { + read_err++; + if (errno == ETIMEDOUT) { + printf("Timed out after %d packets!\n", i); + break; + } } - clock_gettime(CLOCK_MONOTONIC, &tv2); - double seconds = timedelta(tv1, tv2); - int pps = (int) (i / seconds); - double mbps = (i * PAYLOADSIZE / 1000000 * 8 / seconds); - printf("%s: %d packets in %.2fs (%d pps, %.2f Mbps), ", name, i, seconds, pps, mbps); - printf("read err %d (%.2f%%), write err %d (%.2f%%)\n", - read_err, (float) read_err / i * 100, - write_err, (float) write_err / i * 100); + } + clock_gettime(CLOCK_MONOTONIC, &tv2); + double seconds = timedelta(tv1, tv2); + int pps = (int)(i / seconds); + double mbps = (i * PAYLOADSIZE / 1000000 * 8 / seconds); + printf("%s: %d packets in %.2fs (%d pps, %.2f Mbps), ", name, i, seconds, pps, mbps); + printf("read err %d (%.2f%%), write err %d (%.2f%%)\n", read_err, (float)read_err / i * 100, + write_err, (float)write_err / i * 100); } int open_socket() { - int sock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP); + int sock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, IPPROTO_UDP); - int on = 1; - if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) die("SO_REUSEADDR"); + int on = 1; + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) die("SO_REUSEADDR"); - struct timeval tv = { 1, 0 }; - if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) die("SO_RCVTIMEO"); + struct timeval tv = { 1, 0 }; + if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) == -1) die("SO_RCVTIMEO"); - struct sockaddr_in addr = { - .sin_family = AF_INET, - .sin_port = ntohs(PORT), - .sin_addr = { INADDR_ANY } - }; - if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) die ("bind"); + struct sockaddr_in addr = { + .sin_family = AF_INET, + .sin_port = ntohs(PORT), + .sin_addr = { INADDR_ANY }, + }; + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1) die("bind"); - return sock; + return sock; } int main() { - int fd = setup_tun(); - int sock = open_socket(); - - int i; - uint8_t payload[PAYLOADSIZE]; - for (i = 0; i < (int) sizeof(payload); i++) { - payload[i] = (uint8_t) i; - } - uint32_t payload_sum = ip_checksum_add(0, payload, sizeof(payload)); - - // Check things are working. - char buf[4096]; - if (send_packet(fd, payload, sizeof(payload), payload_sum) == -1) die("send_packet"); - if (recvfrom(sock, buf, sizeof(buf), 0, NULL, NULL) == -1) die("recvfrom"); - - benchmark("Blocking", fd, sock, NUMPACKETS, 1, payload, sizeof(payload), payload_sum); - close(fd); - - fd = setup_tun(); - set_nonblocking(fd); - benchmark("No read", fd, sock, NUMPACKETS, 0, payload, sizeof(payload), payload_sum); - close(fd); - - fd = setup_tun(); - set_nonblocking(fd); - benchmark("Nonblocking", fd, sock, NUMPACKETS, 1, payload, sizeof(payload), payload_sum); - close(fd); - - return 0; + int fd = setup_tun(); + int sock = open_socket(); + + int i; + uint8_t payload[PAYLOADSIZE]; + for (i = 0; i < (int)sizeof(payload); i++) { + payload[i] = (uint8_t)i; + } + uint32_t payload_sum = ip_checksum_add(0, payload, sizeof(payload)); + + // Check things are working. + char buf[4096]; + if (send_packet(fd, payload, sizeof(payload), payload_sum) == -1) die("send_packet"); + if (recvfrom(sock, buf, sizeof(buf), 0, NULL, NULL) == -1) die("recvfrom"); + + benchmark("Blocking", fd, sock, NUMPACKETS, 1, payload, sizeof(payload), payload_sum); + close(fd); + + fd = setup_tun(); + set_nonblocking(fd); + benchmark("No read", fd, sock, NUMPACKETS, 0, payload, sizeof(payload), payload_sum); + close(fd); + + fd = setup_tun(); + set_nonblocking(fd); + benchmark("Nonblocking", fd, sock, NUMPACKETS, 1, payload, sizeof(payload), payload_sum); + close(fd); + + return 0; } diff --git a/clatd_test.cpp b/clatd_test.cpp index b901c30..2a10101 100644 --- a/clatd_test.cpp +++ b/clatd_test.cpp @@ -18,28 +18,29 @@ #include <iostream> -#include <stdio.h> #include <arpa/inet.h> #include <netinet/in6.h> +#include <stdio.h> #include <sys/uio.h> #include <gtest/gtest.h> extern "C" { #include "checksum.h" -#include "translate.h" -#include "config.h" #include "clatd.h" +#include "config.h" +#include "translate.h" } // For convenience. #define ARRAYSIZE(x) sizeof((x)) / sizeof((x)[0]) // Default translation parameters. -static const char kIPv4LocalAddr[] = "192.0.0.4"; -static const char kIPv6LocalAddr[] = "2001:db8:0:b11::464"; +static const char kIPv4LocalAddr[] = "192.0.0.4"; +static const char kIPv6LocalAddr[] = "2001:db8:0:b11::464"; static const char kIPv6PlatSubnet[] = "64:ff9b::"; +// clang-format off // Test packet portions. Defined as macros because it's easy to concatenate them to make packets. #define IPV4_HEADER(p, c1, c2) \ 0x45, 0x00, 0, 41, /* Version=4, IHL=5, ToS=0x80, len=41 */ \ @@ -164,6 +165,7 @@ static const uint8_t kReassembledIPv4[] = { 0x6c, 0x65, 0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, 0x01 }; +// clang-format on // Expected checksums. static const uint32_t kUdpPartialChecksum = 0xd5c8; @@ -185,9 +187,9 @@ int is_ipv6_fragment(struct ip6_hdr *ip6, size_t len) { if (ip6->ip6_nxt != IPPROTO_FRAGMENT) { return 0; } - struct ip6_frag *frag = (struct ip6_frag *) (ip6 + 1); + struct ip6_frag *frag = (struct ip6_frag *)(ip6 + 1); return len >= sizeof(*ip6) + sizeof(*frag) && - (frag->ip6f_offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG)); + (frag->ip6f_offlg & (IP6F_OFF_MASK | IP6F_MORE_FRAG)); } int ipv4_fragment_offset(struct iphdr *ip) { @@ -200,50 +202,50 @@ int ipv6_fragment_offset(struct ip6_frag *frag) { void check_packet(const uint8_t *packet, size_t len, const char *msg) { void *payload; - size_t payload_length = 0; + size_t payload_length = 0; uint32_t pseudo_checksum = 0; - uint8_t protocol = 0; - int version = ip_version(packet); + uint8_t protocol = 0; + int version = ip_version(packet); switch (version) { case 4: { - struct iphdr *ip = (struct iphdr *) packet; + struct iphdr *ip = (struct iphdr *)packet; ASSERT_GE(len, sizeof(*ip)) << msg << ": IPv4 packet shorter than IPv4 header\n"; EXPECT_EQ(5, ip->ihl) << msg << ": Unsupported IP header length\n"; EXPECT_EQ(len, ntohs(ip->tot_len)) << msg << ": Incorrect IPv4 length\n"; EXPECT_EQ(0, ip_checksum(ip, sizeof(*ip))) << msg << ": Incorrect IP checksum\n"; protocol = ip->protocol; - payload = ip + 1; + payload = ip + 1; if (!is_ipv4_fragment(ip)) { - payload_length = len - sizeof(*ip); + payload_length = len - sizeof(*ip); pseudo_checksum = ipv4_pseudo_header_checksum(ip, payload_length); } ASSERT_TRUE(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP || protocol == IPPROTO_ICMP) - << msg << ": Unsupported IPv4 protocol " << protocol << "\n"; + << msg << ": Unsupported IPv4 protocol " << protocol << "\n"; break; } case 6: { - struct ip6_hdr *ip6 = (struct ip6_hdr *) packet; + struct ip6_hdr *ip6 = (struct ip6_hdr *)packet; ASSERT_GE(len, sizeof(*ip6)) << msg << ": IPv6 packet shorter than IPv6 header\n"; EXPECT_EQ(len - sizeof(*ip6), htons(ip6->ip6_plen)) << msg << ": Incorrect IPv6 length\n"; if (ip6->ip6_nxt == IPPROTO_FRAGMENT) { - struct ip6_frag *frag = (struct ip6_frag *) (ip6 + 1); + struct ip6_frag *frag = (struct ip6_frag *)(ip6 + 1); ASSERT_GE(len, sizeof(*ip6) + sizeof(*frag)) - << msg << ": IPv6 fragment: short fragment header\n"; + << msg << ": IPv6 fragment: short fragment header\n"; protocol = frag->ip6f_nxt; - payload = frag + 1; + payload = frag + 1; // Even though the packet has a Fragment header, it might not be a fragment. if (!is_ipv6_fragment(ip6, len)) { payload_length = len - sizeof(*ip6) - sizeof(*frag); } } else { // Since there are no extension headers except Fragment, this must be the payload. - protocol = ip6->ip6_nxt; - payload = ip6 + 1; + protocol = ip6->ip6_nxt; + payload = ip6 + 1; payload_length = len - sizeof(*ip6); } ASSERT_TRUE(protocol == IPPROTO_TCP || protocol == IPPROTO_UDP || protocol == IPPROTO_ICMPV6) - << msg << ": Unsupported IPv6 next header " << protocol; + << msg << ": Unsupported IPv6 next header " << protocol; if (payload_length) { pseudo_checksum = ipv6_pseudo_header_checksum(ip6, payload_length, protocol); } @@ -257,7 +259,7 @@ void check_packet(const uint8_t *packet, size_t len, const char *msg) { // If we understand the payload, verify the checksum. if (payload_length) { uint16_t checksum; - switch(protocol) { + switch (protocol) { case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_ICMPV6: @@ -274,7 +276,7 @@ void check_packet(const uint8_t *packet, size_t len, const char *msg) { } if (protocol == IPPROTO_UDP) { - struct udphdr *udp = (struct udphdr *) payload; + struct udphdr *udp = (struct udphdr *)payload; EXPECT_NE(0, udp->check) << msg << ": UDP checksum 0 should be 0xffff"; // If this is not a fragment, check the UDP length field. if (payload_length) { @@ -285,15 +287,15 @@ void check_packet(const uint8_t *packet, size_t len, const char *msg) { void reassemble_packet(const uint8_t **fragments, const size_t lengths[], int numpackets, uint8_t *reassembled, size_t *reassembled_len, const char *msg) { - struct iphdr *ip = NULL; + struct iphdr *ip = NULL; struct ip6_hdr *ip6 = NULL; - size_t total_length, pos = 0; + size_t total_length, pos = 0; uint8_t protocol = 0; - uint8_t version = ip_version(fragments[0]); + uint8_t version = ip_version(fragments[0]); for (int i = 0; i < numpackets; i++) { const uint8_t *packet = fragments[i]; - int len = lengths[i]; + int len = lengths[i]; int headersize, payload_offset; ASSERT_EQ(ip_version(packet), version) << msg << ": Inconsistent fragment versions\n"; @@ -301,32 +303,32 @@ void reassemble_packet(const uint8_t **fragments, const size_t lengths[], int nu switch (version) { case 4: { - struct iphdr *ip_orig = (struct iphdr *) packet; - headersize = sizeof(*ip_orig); + struct iphdr *ip_orig = (struct iphdr *)packet; + headersize = sizeof(*ip_orig); ASSERT_TRUE(is_ipv4_fragment(ip_orig)) - << msg << ": IPv4 fragment #" << i + 1 << " not a fragment\n"; - ASSERT_EQ(pos, ipv4_fragment_offset(ip_orig) * 8 + ((i != 0) ? sizeof(*ip): 0)) - << msg << ": IPv4 fragment #" << i + 1 << ": inconsistent offset\n"; + << msg << ": IPv4 fragment #" << i + 1 << " not a fragment\n"; + ASSERT_EQ(pos, ipv4_fragment_offset(ip_orig) * 8 + ((i != 0) ? sizeof(*ip) : 0)) + << msg << ": IPv4 fragment #" << i + 1 << ": inconsistent offset\n"; - headersize = sizeof(*ip_orig); + headersize = sizeof(*ip_orig); payload_offset = headersize; if (pos == 0) { - ip = (struct iphdr *) reassembled; + ip = (struct iphdr *)reassembled; } break; } case 6: { - struct ip6_hdr *ip6_orig = (struct ip6_hdr *) packet; - struct ip6_frag *frag = (struct ip6_frag *) (ip6_orig + 1); + struct ip6_hdr *ip6_orig = (struct ip6_hdr *)packet; + struct ip6_frag *frag = (struct ip6_frag *)(ip6_orig + 1); ASSERT_TRUE(is_ipv6_fragment(ip6_orig, len)) - << msg << ": IPv6 fragment #" << i + 1 << " not a fragment\n"; - ASSERT_EQ(pos, ipv6_fragment_offset(frag) * 8 + ((i != 0) ? sizeof(*ip6): 0)) - << msg << ": IPv6 fragment #" << i + 1 << ": inconsistent offset\n"; + << msg << ": IPv6 fragment #" << i + 1 << " not a fragment\n"; + ASSERT_EQ(pos, ipv6_fragment_offset(frag) * 8 + ((i != 0) ? sizeof(*ip6) : 0)) + << msg << ": IPv6 fragment #" << i + 1 << ": inconsistent offset\n"; - headersize = sizeof(*ip6_orig); + headersize = sizeof(*ip6_orig); payload_offset = sizeof(*ip6_orig) + sizeof(*frag); if (pos == 0) { - ip6 = (struct ip6_hdr *) reassembled; + ip6 = (struct ip6_hdr *)reassembled; protocol = frag->ip6f_nxt; } break; @@ -337,7 +339,7 @@ void reassemble_packet(const uint8_t **fragments, const size_t lengths[], int nu // If this is the first fragment, copy the header. if (pos == 0) { - ASSERT_LT(headersize, (int) *reassembled_len) << msg << ": Reassembly buffer too small\n"; + ASSERT_LT(headersize, (int)*reassembled_len) << msg << ": Reassembly buffer too small\n"; memcpy(reassembled, packet, headersize); total_length = headersize; pos += headersize; @@ -351,21 +353,20 @@ void reassemble_packet(const uint8_t **fragments, const size_t lengths[], int nu pos += payload_length; } - // Fix up the reassembled headers to reflect fragmentation and length (and IPv4 checksum). ASSERT_EQ(total_length, pos) << msg << ": Reassembled packet length incorrect\n"; if (ip) { ip->frag_off &= ~htons(IP_MF); ip->tot_len = htons(total_length); - ip->check = 0; - ip->check = ip_checksum(ip, sizeof(*ip)); + ip->check = 0; + ip->check = ip_checksum(ip, sizeof(*ip)); ASSERT_FALSE(is_ipv4_fragment(ip)) << msg << ": reassembled IPv4 packet is a fragment!\n"; } if (ip6) { - ip6->ip6_nxt = protocol; + ip6->ip6_nxt = protocol; ip6->ip6_plen = htons(total_length - sizeof(*ip6)); ASSERT_FALSE(is_ipv6_fragment(ip6, ip6->ip6_plen)) - << msg << ": reassembled IPv6 packet is a fragment!\n"; + << msg << ": reassembled IPv6 packet is a fragment!\n"; } *reassembled_len = total_length; @@ -383,8 +384,8 @@ void check_data_matches(const void *expected, const void *actual, size_t len, co snprintf(actual_hexdump + pos, hexdump_len - pos, "\n "); pos += 4; } - snprintf(expected_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *) expected)[i]); - snprintf(actual_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *) actual)[i]); + snprintf(expected_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *)expected)[i]); + snprintf(actual_hexdump + pos, hexdump_len - pos, " %02x", ((uint8_t *)actual)[i]); pos += 3; } FAIL() << msg << ": Data doesn't match" @@ -393,27 +394,27 @@ void check_data_matches(const void *expected, const void *actual, size_t len, co } } -void fix_udp_checksum(uint8_t* packet) { +void fix_udp_checksum(uint8_t *packet) { uint32_t pseudo_checksum; uint8_t version = ip_version(packet); struct udphdr *udp; switch (version) { case 4: { - struct iphdr *ip = (struct iphdr *) packet; - udp = (struct udphdr *) (ip + 1); - pseudo_checksum = ipv4_pseudo_header_checksum(ip, ntohs(udp->len)); + struct iphdr *ip = (struct iphdr *)packet; + udp = (struct udphdr *)(ip + 1); + pseudo_checksum = ipv4_pseudo_header_checksum(ip, ntohs(udp->len)); break; } case 6: { - struct ip6_hdr *ip6 = (struct ip6_hdr *) packet; - udp = (struct udphdr *) (ip6 + 1); - pseudo_checksum = ipv6_pseudo_header_checksum(ip6, ntohs(udp->len), IPPROTO_UDP); + struct ip6_hdr *ip6 = (struct ip6_hdr *)packet; + udp = (struct udphdr *)(ip6 + 1); + pseudo_checksum = ipv6_pseudo_header_checksum(ip6, ntohs(udp->len), IPPROTO_UDP); break; } default: FAIL() << "unsupported IP version" << version << "\n"; return; - } + } udp->check = 0; udp->check = ip_checksum_finish(ip_checksum_add(pseudo_checksum, udp, ntohs(udp->len))); @@ -422,9 +423,7 @@ void fix_udp_checksum(uint8_t* packet) { // Testing stub for send_rawv6. The real version uses sendmsg() with a // destination IPv6 address, and attempting to call that on our test socketpair // fd results in EINVAL. -extern "C" void send_rawv6(int fd, clat_packet out, int iov_len) { - writev(fd, out, iov_len); -} +extern "C" void send_rawv6(int fd, clat_packet out, int iov_len) { writev(fd, out, iov_len); } void do_translate_packet(const uint8_t *original, size_t original_len, uint8_t *out, size_t *outlen, const char *msg) { @@ -443,13 +442,13 @@ void do_translate_packet(const uint8_t *original, size_t original_len, uint8_t * switch (version) { case 4: expected_proto = htons(ETH_P_IPV6); - read_fd = fds[1]; - write_fd = fds[0]; + read_fd = fds[1]; + write_fd = fds[0]; break; case 6: expected_proto = htons(ETH_P_IP); - read_fd = fds[0]; - write_fd = fds[1]; + read_fd = fds[0]; + write_fd = fds[1]; break; default: FAIL() << msg << ": Unsupported IP version " << version << "\n"; @@ -464,11 +463,12 @@ void do_translate_packet(const uint8_t *original, size_t original_len, uint8_t * struct tun_pi new_tun_header; struct iovec iov[] = { { &new_tun_header, sizeof(new_tun_header) }, - { out, *outlen } + { out, *outlen }, }; + int len = readv(read_fd, iov, 2); - if (len > (int) sizeof(new_tun_header)) { - ASSERT_LT((size_t) len, *outlen) << msg << ": Translated packet buffer too small\n"; + if (len > (int)sizeof(new_tun_header)) { + ASSERT_LT((size_t)len, *outlen) << msg << ": Translated packet buffer too small\n"; EXPECT_EQ(expected_proto, new_tun_header.proto) << msg << "Unexpected tun proto\n"; *outlen = len - sizeof(new_tun_header); check_packet(out, *outlen, msg); @@ -483,8 +483,8 @@ void do_translate_packet(const uint8_t *original, size_t original_len, uint8_t * } } -void check_translated_packet(const uint8_t *original, size_t original_len, - const uint8_t *expected, size_t expected_len, const char *msg) { +void check_translated_packet(const uint8_t *original, size_t original_len, const uint8_t *expected, + size_t expected_len, const char *msg) { uint8_t translated[MAXMTU]; size_t translated_len = sizeof(translated); do_translate_packet(original, original_len, translated, &translated_len, msg); @@ -499,8 +499,8 @@ void check_fragment_translation(const uint8_t *original[], const size_t original // Check that each of the fragments translates as expected. char frag_msg[512]; snprintf(frag_msg, sizeof(frag_msg), "%s: fragment #%d", msg, i + 1); - check_translated_packet(original[i], original_lengths[i], - expected[i], expected_lengths[i], frag_msg); + check_translated_packet(original[i], original_lengths[i], expected[i], expected_lengths[i], + frag_msg); } // Sanity check that reassembling the original and translated fragments produces valid packets. @@ -524,17 +524,17 @@ int get_transport_checksum(const uint8_t *packet) { int version = ip_version(packet); switch (version) { case 4: - ip = (struct iphdr *) packet; + ip = (struct iphdr *)packet; if (is_ipv4_fragment(ip)) { - return -1; + return -1; } protocol = ip->protocol; - payload = ip + 1; + payload = ip + 1; break; case 6: - ip6 = (struct ip6_hdr *) packet; + ip6 = (struct ip6_hdr *)packet; protocol = ip6->ip6_nxt; - payload = ip6 + 1; + payload = ip6 + 1; break; default: return -1; @@ -542,10 +542,10 @@ int get_transport_checksum(const uint8_t *packet) { switch (protocol) { case IPPROTO_UDP: - return ((struct udphdr *) payload)->check; + return ((struct udphdr *)payload)->check; case IPPROTO_TCP: - return ((struct tcphdr *) payload)->check; + return ((struct tcphdr *)payload)->check; case IPPROTO_FRAGMENT: default: @@ -561,7 +561,7 @@ class ClatdTest : public ::testing::Test { inet_pton(AF_INET, kIPv4LocalAddr, &Global_Clatd_Config.ipv4_local_subnet); inet_pton(AF_INET6, kIPv6PlatSubnet, &Global_Clatd_Config.plat_subnet); inet_pton(AF_INET6, kIPv6LocalAddr, &Global_Clatd_Config.ipv6_local_subnet); - Global_Clatd_Config.ipv6_host_id = in6addr_any; + Global_Clatd_Config.ipv6_host_id = in6addr_any; Global_Clatd_Config.use_dynamic_iid = 1; } }; @@ -597,7 +597,7 @@ TEST_F(ClatdTest, TestIPv6PrefixEqual) { int count_onebits(const void *data, size_t size) { int onebits = 0; for (size_t pos = 0; pos < size; pos++) { - uint8_t *byte = ((uint8_t*) data) + pos; + uint8_t *byte = ((uint8_t *)data) + pos; for (int shift = 0; shift < 8; shift++) { onebits += (*byte >> shift) & 1; } @@ -611,7 +611,7 @@ TEST_F(ClatdTest, TestCountOnebits) { ASSERT_EQ(1, count_onebits(&i, sizeof(i))); i <<= 61; ASSERT_EQ(1, count_onebits(&i, sizeof(i))); - i |= ((uint64_t) 1 << 33); + i |= ((uint64_t)1 << 33); ASSERT_EQ(2, count_onebits(&i, sizeof(i))); i = 0xf1000202020000f0; ASSERT_EQ(5 + 1 + 1 + 1 + 4, count_onebits(&i, sizeof(i))); @@ -637,10 +637,10 @@ TEST_F(ClatdTest, TestGenIIDRandom) { Global_Clatd_Config.ipv6_host_id = in6addr_any; // Generate a boatload of random IIDs. - int onebits = 0; + int onebits = 0; uint64_t prev_iid = 0; for (int i = 0; i < 100000; i++) { - struct in6_addr myaddr = interface_ipv6; + struct in6_addr myaddr = interface_ipv6; config_generate_local_ipv6_subnet(&myaddr); @@ -648,7 +648,7 @@ TEST_F(ClatdTest, TestGenIIDRandom) { EXPECT_TRUE(ipv6_prefix_equal(&interface_ipv6, &myaddr)); // Check that consecutive IIDs are not the same. - uint64_t iid = * (uint64_t*) (&myaddr.s6_addr[8]); + uint64_t iid = *(uint64_t *)(&myaddr.s6_addr[8]); ASSERT_TRUE(iid != prev_iid) << "Two consecutive random IIDs are the same: " << std::showbase << std::hex @@ -657,7 +657,7 @@ TEST_F(ClatdTest, TestGenIIDRandom) { // Check that the IID is checksum-neutral with the NAT64 prefix and the // local prefix. - struct in_addr *ipv4addr = &Global_Clatd_Config.ipv4_local_subnet; + struct in_addr *ipv4addr = &Global_Clatd_Config.ipv4_local_subnet; struct in6_addr *plat_subnet = &Global_Clatd_Config.plat_subnet; uint16_t c1 = ip_checksum_finish(ip_checksum_add(0, ipv4addr, sizeof(*ipv4addr))); @@ -732,7 +732,7 @@ TEST_F(ClatdTest, SelectIPv4Address) { // Now try using the real function which sees if IP addresses are free using bind(). // Assume that the machine running the test has the address 127.0.0.1, but not 8.8.8.8. config_is_ipv4_address_free = orig_config_is_ipv4_address_free; - addr.s_addr = inet_addr("8.8.8.8"); + addr.s_addr = inet_addr("8.8.8.8"); EXPECT_EQ(inet_addr("8.8.8.8"), config_select_ipv4_address(&addr, 29)); addr.s_addr = inet_addr("127.0.0.1"); @@ -753,13 +753,13 @@ TEST_F(ClatdTest, DataSanitycheck) { // Sanity checks check_packet. struct udphdr *udp; uint8_t v4_udp_packet[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD }; - udp = (struct udphdr *) (v4_udp_packet + sizeof(struct iphdr)); + udp = (struct udphdr *)(v4_udp_packet + sizeof(struct iphdr)); fix_udp_checksum(v4_udp_packet); ASSERT_EQ(kUdpV4Checksum, udp->check) << "UDP/IPv4 packet checksum sanity check\n"; check_packet(v4_udp_packet, sizeof(v4_udp_packet), "UDP/IPv4 packet sanity check"); uint8_t v6_udp_packet[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD }; - udp = (struct udphdr *) (v6_udp_packet + sizeof(struct ip6_hdr)); + udp = (struct udphdr *)(v6_udp_packet + sizeof(struct ip6_hdr)); fix_udp_checksum(v6_udp_packet); ASSERT_EQ(kUdpV6Checksum, udp->check) << "UDP/IPv6 packet checksum sanity check\n"; check_packet(v6_udp_packet, sizeof(v6_udp_packet), "UDP/IPv6 packet sanity check"); @@ -773,53 +773,53 @@ TEST_F(ClatdTest, DataSanitycheck) { // Sanity checks reassemble_packet. uint8_t reassembled[MAXMTU]; size_t total_length = sizeof(reassembled); - reassemble_packet(kIPv4Fragments, kIPv4FragLengths, ARRAYSIZE(kIPv4Fragments), - reassembled, &total_length, "Reassembly sanity check"); + reassemble_packet(kIPv4Fragments, kIPv4FragLengths, ARRAYSIZE(kIPv4Fragments), reassembled, + &total_length, "Reassembly sanity check"); check_packet(reassembled, total_length, "IPv4 Reassembled packet is valid"); ASSERT_EQ(sizeof(kReassembledIPv4), total_length) << "IPv4 reassembly sanity check: length\n"; - ASSERT_TRUE(!is_ipv4_fragment((struct iphdr *) reassembled)) - << "Sanity check: reassembled packet is a fragment!\n"; + ASSERT_TRUE(!is_ipv4_fragment((struct iphdr *)reassembled)) + << "Sanity check: reassembled packet is a fragment!\n"; check_data_matches(kReassembledIPv4, reassembled, total_length, "IPv4 reassembly sanity check"); total_length = sizeof(reassembled); - reassemble_packet(kIPv6Fragments, kIPv6FragLengths, ARRAYSIZE(kIPv6Fragments), - reassembled, &total_length, "IPv6 reassembly sanity check"); - ASSERT_TRUE(!is_ipv6_fragment((struct ip6_hdr *) reassembled, total_length)) - << "Sanity check: reassembled packet is a fragment!\n"; + reassemble_packet(kIPv6Fragments, kIPv6FragLengths, ARRAYSIZE(kIPv6Fragments), reassembled, + &total_length, "IPv6 reassembly sanity check"); + ASSERT_TRUE(!is_ipv6_fragment((struct ip6_hdr *)reassembled, total_length)) + << "Sanity check: reassembled packet is a fragment!\n"; check_packet(reassembled, total_length, "IPv6 Reassembled packet is valid"); } TEST_F(ClatdTest, PseudoChecksum) { uint32_t pseudo_checksum; - uint8_t v4_header[] = { IPV4_UDP_HEADER }; + uint8_t v4_header[] = { IPV4_UDP_HEADER }; uint8_t v4_pseudo_header[] = { IPV4_PSEUDOHEADER(v4_header, UDP_LEN) }; - pseudo_checksum = ipv4_pseudo_header_checksum((struct iphdr *) v4_header, UDP_LEN); + pseudo_checksum = ipv4_pseudo_header_checksum((struct iphdr *)v4_header, UDP_LEN); EXPECT_EQ(ip_checksum_finish(pseudo_checksum), ip_checksum(v4_pseudo_header, sizeof(v4_pseudo_header))) - << "ipv4_pseudo_header_checksum incorrect\n"; + << "ipv4_pseudo_header_checksum incorrect\n"; - uint8_t v6_header[] = { IPV6_UDP_HEADER }; + uint8_t v6_header[] = { IPV6_UDP_HEADER }; uint8_t v6_pseudo_header[] = { IPV6_PSEUDOHEADER(v6_header, IPPROTO_UDP, UDP_LEN) }; - pseudo_checksum = ipv6_pseudo_header_checksum((struct ip6_hdr *) v6_header, UDP_LEN, IPPROTO_UDP); + pseudo_checksum = ipv6_pseudo_header_checksum((struct ip6_hdr *)v6_header, UDP_LEN, IPPROTO_UDP); EXPECT_EQ(ip_checksum_finish(pseudo_checksum), ip_checksum(v6_pseudo_header, sizeof(v6_pseudo_header))) - << "ipv6_pseudo_header_checksum incorrect\n"; + << "ipv6_pseudo_header_checksum incorrect\n"; } TEST_F(ClatdTest, TransportChecksum) { - uint8_t udphdr[] = { UDP_HEADER }; + uint8_t udphdr[] = { UDP_HEADER }; uint8_t payload[] = { PAYLOAD }; EXPECT_EQ(kUdpPartialChecksum, ip_checksum_add(0, udphdr, sizeof(udphdr))) - << "UDP partial checksum\n"; + << "UDP partial checksum\n"; EXPECT_EQ(kPayloadPartialChecksum, ip_checksum_add(0, payload, sizeof(payload))) - << "Payload partial checksum\n"; + << "Payload partial checksum\n"; - uint8_t ip[] = { IPV4_UDP_HEADER }; - uint8_t ip6[] = { IPV6_UDP_HEADER }; - uint32_t ipv4_pseudo_sum = ipv4_pseudo_header_checksum((struct iphdr *) ip, UDP_LEN); - uint32_t ipv6_pseudo_sum = ipv6_pseudo_header_checksum((struct ip6_hdr *) ip6, UDP_LEN, - IPPROTO_UDP); + uint8_t ip[] = { IPV4_UDP_HEADER }; + uint8_t ip6[] = { IPV6_UDP_HEADER }; + uint32_t ipv4_pseudo_sum = ipv4_pseudo_header_checksum((struct iphdr *)ip, UDP_LEN); + uint32_t ipv6_pseudo_sum = + ipv6_pseudo_header_checksum((struct ip6_hdr *)ip6, UDP_LEN, IPPROTO_UDP); EXPECT_EQ(0x3ad0U, ipv4_pseudo_sum) << "IPv4 pseudo-checksum sanity check\n"; EXPECT_EQ(0x2644bU, ipv6_pseudo_sum) << "IPv6 pseudo-checksum sanity check\n"; @@ -886,12 +886,10 @@ TEST_F(ClatdTest, Translate) { } TEST_F(ClatdTest, Fragmentation) { - check_fragment_translation(kIPv4Fragments, kIPv4FragLengths, - kIPv6Fragments, kIPv6FragLengths, + check_fragment_translation(kIPv4Fragments, kIPv4FragLengths, kIPv6Fragments, kIPv6FragLengths, ARRAYSIZE(kIPv4Fragments), "IPv4->IPv6 fragment translation"); - check_fragment_translation(kIPv6Fragments, kIPv6FragLengths, - kIPv4Fragments, kIPv4FragLengths, + check_fragment_translation(kIPv6Fragments, kIPv6FragLengths, kIPv4Fragments, kIPv4FragLengths, ARRAYSIZE(kIPv6Fragments), "IPv6->IPv4 fragment translation"); } @@ -902,12 +900,12 @@ void check_translate_checksum_neutral(const uint8_t *original, size_t original_l do_translate_packet(original, original_len, translated, &translated_len, msg); EXPECT_EQ(expected_len, translated_len) << msg << ": Translated packet length incorrect\n"; // do_translate_packet already checks packets for validity and verifies the checksum. - int original_check = get_transport_checksum(original); + int original_check = get_transport_checksum(original); int translated_check = get_transport_checksum(translated); ASSERT_NE(-1, original_check); ASSERT_NE(-1, translated_check); ASSERT_EQ(original_check, translated_check) - << "Not checksum neutral: original and translated checksums differ\n"; + << "Not checksum neutral: original and translated checksums differ\n"; } TEST_F(ClatdTest, TranslateChecksumNeutral) { @@ -916,8 +914,8 @@ TEST_F(ClatdTest, TranslateChecksumNeutral) { ASSERT_TRUE(inet_pton(AF_INET6, "2001:db8:1:2:f076:ae99:124e:aa54", &Global_Clatd_Config.ipv6_local_subnet)); config_generate_local_ipv6_subnet(&Global_Clatd_Config.ipv6_local_subnet); - ASSERT_NE((uint32_t) 0x00000464, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]); - ASSERT_NE((uint32_t) 0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]); + ASSERT_NE((uint32_t)0x00000464, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]); + ASSERT_NE((uint32_t)0, Global_Clatd_Config.ipv6_local_subnet.s6_addr32[3]); // Check that translating UDP packets is checksum-neutral. First, IPv4. uint8_t udp_ipv4[] = { IPV4_UDP_HEADER UDP_HEADER PAYLOAD }; @@ -928,7 +926,7 @@ TEST_F(ClatdTest, TranslateChecksumNeutral) { // Now try IPv6. uint8_t udp_ipv6[] = { IPV6_UDP_HEADER UDP_HEADER PAYLOAD }; // The test packet uses the static IID, not the random IID. Fix up the source address. - struct ip6_hdr *ip6 = (struct ip6_hdr *) udp_ipv6; + struct ip6_hdr *ip6 = (struct ip6_hdr *)udp_ipv6; memcpy(&ip6->ip6_src, &Global_Clatd_Config.ipv6_local_subnet, sizeof(ip6->ip6_src)); fix_udp_checksum(udp_ipv6); check_translate_checksum_neutral(udp_ipv4, sizeof(udp_ipv4), sizeof(udp_ipv4) + 20, @@ -16,75 +16,80 @@ * config.c - configuration settings */ -#include <string.h> -#include <stdlib.h> #include <arpa/inet.h> -#include <stdio.h> -#include <limits.h> #include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> #include <unistd.h> #include <cutils/config_utils.h> #include <netutils/ifc.h> +#include "checksum.h" +#include "clatd.h" #include "config.h" #include "dns64.h" -#include "logging.h" #include "getaddr.h" -#include "clatd.h" -#include "checksum.h" +#include "logging.h" struct clat_config Global_Clatd_Config; /* function: config_item_str - * locates the config item and returns the pointer to a string, or NULL on failure. Caller frees pointer - * root - parsed configuration - * item_name - name of config item to locate - * defaultvar - value to use if config item isn't present + * locates the config item and returns the pointer to a string, or NULL on failure. Caller frees + * pointer + * root - parsed configuration + * item_name - name of config item to locate + * defaultvar - value to use if config item isn't present */ char *config_item_str(cnode *root, const char *item_name, const char *defaultvar) { const char *tmp; - if(!(tmp = config_str(root, item_name, defaultvar))) { - logmsg(ANDROID_LOG_FATAL,"%s config item needed",item_name); + if (!(tmp = config_str(root, item_name, defaultvar))) { + logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name); return NULL; } return strdup(tmp); } /* function: config_item_int16_t - * locates the config item, parses the integer, and returns the pointer ret_val_ptr, or NULL on failure - * root - parsed configuration - * item_name - name of config item to locate - * defaultvar - value to use if config item isn't present - * ret_val_ptr - pointer for return value storage + * locates the config item, parses the integer, and returns the pointer ret_val_ptr, or NULL on + * failure + * root - parsed configuration + * item_name - name of config item to locate + * defaultvar - value to use if config item isn't present + * ret_val_ptr - pointer for return value storage */ -int16_t *config_item_int16_t(cnode *root, const char *item_name, const char *defaultvar, int16_t *ret_val_ptr) { +int16_t *config_item_int16_t(cnode *root, const char *item_name, const char *defaultvar, + int16_t *ret_val_ptr) { const char *tmp; char *endptr; long int conf_int; - if(!(tmp = config_str(root, item_name, defaultvar))) { - logmsg(ANDROID_LOG_FATAL,"%s config item needed",item_name); + if (!(tmp = config_str(root, item_name, defaultvar))) { + logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name); return NULL; } - errno = 0; - conf_int = strtol(tmp,&endptr,10); - if(errno > 0) { - logmsg(ANDROID_LOG_FATAL,"%s config item is not numeric: %s (error=%s)",item_name,tmp,strerror(errno)); + errno = 0; + conf_int = strtol(tmp, &endptr, 10); + if (errno > 0) { + logmsg(ANDROID_LOG_FATAL, "%s config item is not numeric: %s (error=%s)", item_name, tmp, + strerror(errno)); return NULL; } - if(endptr == tmp || *tmp == '\0') { - logmsg(ANDROID_LOG_FATAL,"%s config item is not numeric: %s",item_name,tmp); + if (endptr == tmp || *tmp == '\0') { + logmsg(ANDROID_LOG_FATAL, "%s config item is not numeric: %s", item_name, tmp); return NULL; } - if(*endptr != '\0') { - logmsg(ANDROID_LOG_FATAL,"%s config item contains non-numeric characters: %s",item_name,endptr); + if (*endptr != '\0') { + logmsg(ANDROID_LOG_FATAL, "%s config item contains non-numeric characters: %s", item_name, + endptr); return NULL; } - if(conf_int > INT16_MAX || conf_int < INT16_MIN) { - logmsg(ANDROID_LOG_FATAL,"%s config item is too big/small: %d",item_name,conf_int); + if (conf_int > INT16_MAX || conf_int < INT16_MIN) { + logmsg(ANDROID_LOG_FATAL, "%s config item is too big/small: %d", item_name, conf_int); return NULL; } *ret_val_ptr = conf_int; @@ -92,24 +97,26 @@ int16_t *config_item_int16_t(cnode *root, const char *item_name, const char *def } /* function: config_item_ip - * locates the config item, parses the ipv4 address, and returns the pointer ret_val_ptr, or NULL on failure - * root - parsed configuration - * item_name - name of config item to locate - * defaultvar - value to use if config item isn't present - * ret_val_ptr - pointer for return value storage + * locates the config item, parses the ipv4 address, and returns the pointer ret_val_ptr, or NULL on + * failure + * root - parsed configuration + * item_name - name of config item to locate + * defaultvar - value to use if config item isn't present + * ret_val_ptr - pointer for return value storage */ -struct in_addr *config_item_ip(cnode *root, const char *item_name, const char *defaultvar, struct in_addr *ret_val_ptr) { +struct in_addr *config_item_ip(cnode *root, const char *item_name, const char *defaultvar, + struct in_addr *ret_val_ptr) { const char *tmp; int status; - if(!(tmp = config_str(root, item_name, defaultvar))) { - logmsg(ANDROID_LOG_FATAL,"%s config item needed",item_name); + if (!(tmp = config_str(root, item_name, defaultvar))) { + logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name); return NULL; } status = inet_pton(AF_INET, tmp, ret_val_ptr); - if(status <= 0) { - logmsg(ANDROID_LOG_FATAL,"invalid IPv4 address specified for %s: %s", item_name, tmp); + if (status <= 0) { + logmsg(ANDROID_LOG_FATAL, "invalid IPv4 address specified for %s: %s", item_name, tmp); return NULL; } @@ -117,24 +124,26 @@ struct in_addr *config_item_ip(cnode *root, const char *item_name, const char *d } /* function: config_item_ip6 - * locates the config item, parses the ipv6 address, and returns the pointer ret_val_ptr, or NULL on failure - * root - parsed configuration - * item_name - name of config item to locate - * defaultvar - value to use if config item isn't present - * ret_val_ptr - pointer for return value storage + * locates the config item, parses the ipv6 address, and returns the pointer ret_val_ptr, or NULL on + * failure + * root - parsed configuration + * item_name - name of config item to locate + * defaultvar - value to use if config item isn't present + * ret_val_ptr - pointer for return value storage */ -struct in6_addr *config_item_ip6(cnode *root, const char *item_name, const char *defaultvar, struct in6_addr *ret_val_ptr) { +struct in6_addr *config_item_ip6(cnode *root, const char *item_name, const char *defaultvar, + struct in6_addr *ret_val_ptr) { const char *tmp; int status; - if(!(tmp = config_str(root, item_name, defaultvar))) { - logmsg(ANDROID_LOG_FATAL,"%s config item needed",item_name); + if (!(tmp = config_str(root, item_name, defaultvar))) { + logmsg(ANDROID_LOG_FATAL, "%s config item needed", item_name); return NULL; } status = inet_pton(AF_INET6, tmp, ret_val_ptr); - if(status <= 0) { - logmsg(ANDROID_LOG_FATAL,"invalid IPv6 address specified for %s: %s", item_name, tmp); + if (status <= 0) { + logmsg(ANDROID_LOG_FATAL, "invalid IPv6 address specified for %s: %s", item_name, tmp); return NULL; } @@ -145,7 +154,7 @@ struct in6_addr *config_item_ip6(cnode *root, const char *item_name, const char * frees the memory used by the global config variable */ void free_config() { - if(Global_Clatd_Config.plat_from_dns64_hostname) { + if (Global_Clatd_Config.plat_from_dns64_hostname) { free(Global_Clatd_Config.plat_from_dns64_hostname); Global_Clatd_Config.plat_from_dns64_hostname = NULL; } @@ -153,17 +162,16 @@ void free_config() { /* function: ipv6_prefix_equal * compares the prefixes two ipv6 addresses. assumes the prefix lengths are both /64. - * a1 - first address - * a2 - second address - * returns: 0 if the subnets are different, 1 if they are the same. + * a1 - first address + * a2 - second address + * returns: 0 if the subnets are different, 1 if they are the same. */ -int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2) { - return !memcmp(a1, a2, 8); -} +int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2) { return !memcmp(a1, a2, 8); } /* function: dns64_detection - * does dns lookups to set the plat subnet or exits on failure, waits forever for a dns response with a query backoff timer - * net_id - (optional) netId to use, NETID_UNSET indicates use of default network + * does dns lookups to set the plat subnet or exits on failure, waits forever for a dns response + * with a query backoff timer + * net_id - (optional) netId to use, NETID_UNSET indicates use of default network */ void dns64_detection(unsigned net_id) { int backoff_sleep, status; @@ -171,16 +179,16 @@ void dns64_detection(unsigned net_id) { backoff_sleep = 1; - while(1) { - status = plat_prefix(Global_Clatd_Config.plat_from_dns64_hostname,net_id,&tmp_ptr); - if(status > 0) { + while (1) { + status = plat_prefix(Global_Clatd_Config.plat_from_dns64_hostname, net_id, &tmp_ptr); + if (status > 0) { memcpy(&Global_Clatd_Config.plat_subnet, &tmp_ptr, sizeof(struct in6_addr)); return; } logmsg(ANDROID_LOG_WARN, "dns64_detection -- error, sleeping for %d seconds", backoff_sleep); sleep(backoff_sleep); backoff_sleep *= 2; - if(backoff_sleep >= 1800) { + if (backoff_sleep >= 1800) { // Scale down to one DNS query per half hour. Unnecessary DNS queries waste power, and the // benefit is minimal (basically, only limited to the case where a network goes from IPv6-only // to IPv6 with NAT64). @@ -191,9 +199,9 @@ void dns64_detection(unsigned net_id) { /* function: gen_random_iid * picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix - * myaddr - IPv6 address to write to - * ipv4_local_subnet - clat IPv4 address - * plat_subnet - NAT64 prefix + * myaddr - IPv6 address to write to + * ipv4_local_subnet - clat IPv4 address + * plat_subnet - NAT64 prefix */ void gen_random_iid(struct in6_addr *myaddr, struct in_addr *ipv4_local_subnet, struct in6_addr *plat_subnet) { @@ -212,7 +220,7 @@ void gen_random_iid(struct in6_addr *myaddr, struct in_addr *ipv4_local_subnet, uint32_t c2 = ip_checksum_add(0, plat_subnet, sizeof(*plat_subnet)) + ip_checksum_add(0, myaddr, sizeof(*myaddr)); - uint16_t delta = ip_checksum_adjust(middlebytes, c1, c2); + uint16_t delta = ip_checksum_adjust(middlebytes, c1, c2); myaddr->s6_addr[11] = delta >> 8; myaddr->s6_addr[12] = delta & 0xff; } @@ -227,10 +235,9 @@ int connect_is_ipv4_address_free(in_addr_t addr) { // Attempt to connect to the address. If the connection succeeds and getsockname returns the same // the address then the address is already assigned to the system and we can't use it. struct sockaddr_in sin = { .sin_family = AF_INET, .sin_addr = { addr }, .sin_port = 53 }; - socklen_t len = sizeof(sin); - int inuse = connect(s, (struct sockaddr *) &sin, sizeof(sin)) == 0 && - getsockname(s, (struct sockaddr *) &sin, &len) == 0 && - (size_t) len >= sizeof(sin) && + socklen_t len = sizeof(sin); + int inuse = connect(s, (struct sockaddr *)&sin, sizeof(sin)) == 0 && + getsockname(s, (struct sockaddr *)&sin, &len) == 0 && (size_t)len >= sizeof(sin) && sin.sin_addr.s_addr == addr; close(s); @@ -241,127 +248,123 @@ addr_free_func config_is_ipv4_address_free = connect_is_ipv4_address_free; /* function: config_select_ipv4_address * picks a free IPv4 address, starting from ip and trying all addresses in the prefix in order - * ip - the IP address from the configuration file - * prefixlen - the length of the prefix from which addresses may be selected. - * returns: the IPv4 address, or INADDR_NONE if no addresses were available + * ip - the IP address from the configuration file + * prefixlen - the length of the prefix from which addresses may be selected. + * returns: the IPv4 address, or INADDR_NONE if no addresses were available */ in_addr_t config_select_ipv4_address(const struct in_addr *ip, int16_t prefixlen) { in_addr_t chosen = INADDR_NONE; // Don't accept prefixes that are too large because we scan addresses one by one. if (prefixlen < 16 || prefixlen > 32) { - return chosen; + return chosen; } // All these are in host byte order. - in_addr_t mask = 0xffffffff >> (32 - prefixlen) << (32 - prefixlen); - in_addr_t ipv4 = ntohl(ip->s_addr); + in_addr_t mask = 0xffffffff >> (32 - prefixlen) << (32 - prefixlen); + in_addr_t ipv4 = ntohl(ip->s_addr); in_addr_t first_ipv4 = ipv4; - in_addr_t prefix = ipv4 & mask; + in_addr_t prefix = ipv4 & mask; // Pick the first IPv4 address in the pool, wrapping around if necessary. // So, for example, 192.0.0.4 -> 192.0.0.5 -> 192.0.0.6 -> 192.0.0.7 -> 192.0.0.0. do { - if (config_is_ipv4_address_free(htonl(ipv4))) { - chosen = htonl(ipv4); - break; - } - ipv4 = prefix | ((ipv4 + 1) & ~mask); + if (config_is_ipv4_address_free(htonl(ipv4))) { + chosen = htonl(ipv4); + break; + } + ipv4 = prefix | ((ipv4 + 1) & ~mask); } while (ipv4 != first_ipv4); return chosen; } /* function: config_generate_local_ipv6_subnet - * generates the local ipv6 subnet when given the interface ip - * requires config.ipv6_host_id - * interface_ip - in: interface ip, out: local ipv6 host address + * generates the local ipv6 subnet when given the interface ip requires config.ipv6_host_id + * interface_ip - in: interface ip, out: local ipv6 host address */ void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip) { int i; if (Global_Clatd_Config.use_dynamic_iid) { /* Generate a random interface ID. */ - gen_random_iid(interface_ip, - &Global_Clatd_Config.ipv4_local_subnet, + gen_random_iid(interface_ip, &Global_Clatd_Config.ipv4_local_subnet, &Global_Clatd_Config.plat_subnet); } else { /* Use the specified interface ID. */ - for(i = 2; i < 4; i++) { + for (i = 2; i < 4; i++) { interface_ip->s6_addr32[i] = Global_Clatd_Config.ipv6_host_id.s6_addr32[i]; } } } /* function: read_config - * reads the config file and parses it into the global variable Global_Clatd_Config. returns 0 on failure, 1 on success - * file - filename to parse - * uplink_interface - interface to use to reach the internet and supplier of address space - * plat_prefix - (optional) plat prefix to use, otherwise follow config file - * net_id - (optional) netId to use, NETID_UNSET indicates use of default network + * reads the config file and parses it into the global variable Global_Clatd_Config. returns 0 on + * failure, 1 on success + * file - filename to parse + * uplink_interface - interface to use to reach the internet and supplier of address space + * plat_prefix - (optional) plat prefix to use, otherwise follow config file + * net_id - (optional) netId to use, NETID_UNSET indicates use of default network */ int read_config(const char *file, const char *uplink_interface, const char *plat_prefix, - unsigned net_id) { - cnode *root = config_node("", ""); + unsigned net_id) { + cnode *root = config_node("", ""); void *tmp_ptr = NULL; unsigned flags; - if(!root) { - logmsg(ANDROID_LOG_FATAL,"out of memory"); + if (!root) { + logmsg(ANDROID_LOG_FATAL, "out of memory"); return 0; } memset(&Global_Clatd_Config, '\0', sizeof(Global_Clatd_Config)); config_load_file(root, file); - if(root->first_child == NULL) { - logmsg(ANDROID_LOG_FATAL,"Could not read config file %s", file); + if (root->first_child == NULL) { + logmsg(ANDROID_LOG_FATAL, "Could not read config file %s", file); goto failed; } Global_Clatd_Config.default_pdp_interface = strdup(uplink_interface); - if (!Global_Clatd_Config.default_pdp_interface) - goto failed; + if (!Global_Clatd_Config.default_pdp_interface) goto failed; - if(!config_item_int16_t(root, "mtu", "-1", &Global_Clatd_Config.mtu)) - goto failed; + if (!config_item_int16_t(root, "mtu", "-1", &Global_Clatd_Config.mtu)) goto failed; - if(!config_item_int16_t(root, "ipv4mtu", "-1", &Global_Clatd_Config.ipv4mtu)) - goto failed; + if (!config_item_int16_t(root, "ipv4mtu", "-1", &Global_Clatd_Config.ipv4mtu)) goto failed; - if(!config_item_ip(root, "ipv4_local_subnet", DEFAULT_IPV4_LOCAL_SUBNET, - &Global_Clatd_Config.ipv4_local_subnet)) + if (!config_item_ip(root, "ipv4_local_subnet", DEFAULT_IPV4_LOCAL_SUBNET, + &Global_Clatd_Config.ipv4_local_subnet)) goto failed; - if(!config_item_int16_t(root, "ipv4_local_prefixlen", DEFAULT_IPV4_LOCAL_PREFIXLEN, - &Global_Clatd_Config.ipv4_local_prefixlen)) + if (!config_item_int16_t(root, "ipv4_local_prefixlen", DEFAULT_IPV4_LOCAL_PREFIXLEN, + &Global_Clatd_Config.ipv4_local_prefixlen)) goto failed; - if(plat_prefix) { // plat subnet is coming from the command line - if(inet_pton(AF_INET6, plat_prefix, &Global_Clatd_Config.plat_subnet) <= 0) { - logmsg(ANDROID_LOG_FATAL,"invalid IPv6 address specified for plat prefix: %s", plat_prefix); + if (plat_prefix) { // plat subnet is coming from the command line + if (inet_pton(AF_INET6, plat_prefix, &Global_Clatd_Config.plat_subnet) <= 0) { + logmsg(ANDROID_LOG_FATAL, "invalid IPv6 address specified for plat prefix: %s", plat_prefix); goto failed; } } else { tmp_ptr = (void *)config_item_str(root, "plat_from_dns64", "yes"); - if(!tmp_ptr || strcmp(tmp_ptr, "no") == 0) { + if (!tmp_ptr || strcmp(tmp_ptr, "no") == 0) { free(tmp_ptr); - if(!config_item_ip6(root, "plat_subnet", NULL, &Global_Clatd_Config.plat_subnet)) { + if (!config_item_ip6(root, "plat_subnet", NULL, &Global_Clatd_Config.plat_subnet)) { logmsg(ANDROID_LOG_FATAL, "plat_from_dns64 disabled, but no plat_subnet specified"); goto failed; } } else { free(tmp_ptr); - if(!(Global_Clatd_Config.plat_from_dns64_hostname = config_item_str(root, "plat_from_dns64_hostname", DEFAULT_DNS64_DETECTION_HOSTNAME))) + if (!(Global_Clatd_Config.plat_from_dns64_hostname = + config_item_str(root, "plat_from_dns64_hostname", DEFAULT_DNS64_DETECTION_HOSTNAME))) goto failed; dns64_detection(net_id); } } - if (!config_item_ip6(root, "ipv6_host_id", "::", &Global_Clatd_Config.ipv6_host_id)) - goto failed; + if (!config_item_ip6(root, "ipv6_host_id", "::", &Global_Clatd_Config.ipv6_host_id)) goto failed; /* In order to prevent multiple devices attempting to use the same clat address, never use a statically-configured interface ID on a broadcast interface such as wifi. */ @@ -388,11 +391,17 @@ failed: void dump_config() { char charbuffer[INET6_ADDRSTRLEN]; - logmsg(ANDROID_LOG_DEBUG,"mtu = %d",Global_Clatd_Config.mtu); - logmsg(ANDROID_LOG_DEBUG,"ipv4mtu = %d",Global_Clatd_Config.ipv4mtu); - logmsg(ANDROID_LOG_DEBUG,"ipv6_local_subnet = %s",inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, charbuffer, sizeof(charbuffer))); - logmsg(ANDROID_LOG_DEBUG,"ipv4_local_subnet = %s",inet_ntop(AF_INET, &Global_Clatd_Config.ipv4_local_subnet, charbuffer, sizeof(charbuffer))); - logmsg(ANDROID_LOG_DEBUG,"ipv4_local_prefixlen = %d", Global_Clatd_Config.ipv4_local_prefixlen); - logmsg(ANDROID_LOG_DEBUG,"plat_subnet = %s",inet_ntop(AF_INET6, &Global_Clatd_Config.plat_subnet, charbuffer, sizeof(charbuffer))); - logmsg(ANDROID_LOG_DEBUG,"default_pdp_interface = %s",Global_Clatd_Config.default_pdp_interface); + logmsg(ANDROID_LOG_DEBUG, "mtu = %d", Global_Clatd_Config.mtu); + logmsg(ANDROID_LOG_DEBUG, "ipv4mtu = %d", Global_Clatd_Config.ipv4mtu); + logmsg( + ANDROID_LOG_DEBUG, "ipv6_local_subnet = %s", + inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, charbuffer, sizeof(charbuffer))); + logmsg( + ANDROID_LOG_DEBUG, "ipv4_local_subnet = %s", + inet_ntop(AF_INET, &Global_Clatd_Config.ipv4_local_subnet, charbuffer, sizeof(charbuffer))); + logmsg(ANDROID_LOG_DEBUG, "ipv4_local_prefixlen = %d", Global_Clatd_Config.ipv4_local_prefixlen); + logmsg(ANDROID_LOG_DEBUG, "plat_subnet = %s", + inet_ntop(AF_INET6, &Global_Clatd_Config.plat_subnet, charbuffer, sizeof(charbuffer))); + logmsg(ANDROID_LOG_DEBUG, "default_pdp_interface = %s", + Global_Clatd_Config.default_pdp_interface); } @@ -18,8 +18,8 @@ #ifndef __CONFIG_H__ #define __CONFIG_H__ -#include <netinet/in.h> #include <linux/if.h> +#include <netinet/in.h> #define DEFAULT_IPV4_LOCAL_SUBNET "192.0.0.4" #define DEFAULT_IPV4_LOCAL_PREFIXLEN "29" @@ -40,7 +40,7 @@ struct clat_config { extern struct clat_config Global_Clatd_Config; int read_config(const char *file, const char *uplink_interface, const char *plat_prefix, - unsigned net_id); + unsigned net_id); void config_generate_local_ipv6_subnet(struct in6_addr *interface_ip); in_addr_t config_select_ipv4_address(const struct in_addr *ip, int16_t prefixlen); int ipv6_prefix_equal(struct in6_addr *a1, struct in6_addr *a2); @@ -16,25 +16,26 @@ * dns64.c - find the nat64 prefix with a dns64 lookup */ -#include <sys/socket.h> -#include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> -#include <strings.h> +#include <netinet/in.h> #include <stdio.h> #include <stdlib.h> +#include <strings.h> +#include <sys/socket.h> #include <unistd.h> +#include "NetdClient.h" #include "dns64.h" #include "logging.h" -#include "NetdClient.h" #include "resolv_netid.h" /* function: plat_prefix - * looks up an ipv4-only hostname and looks for a nat64 /96 prefix, returns 1 on success, 0 on failure - * ipv4_name - name to lookup - * net_id - (optional) netId to use, NETID_UNSET indicates use of default network - * prefix - the plat /96 prefix + * looks up an ipv4-only hostname and looks for a nat64 /96 prefix, returns 1 on success, 0 on + * failure + * ipv4_name - name to lookup + * net_id - (optional) netId to use, NETID_UNSET indicates use of default network + * prefix - the plat /96 prefix */ int plat_prefix(const char *ipv4_name, unsigned net_id, struct in6_addr *prefix) { const struct addrinfo hints = { @@ -54,8 +55,8 @@ int plat_prefix(const char *ipv4_name, unsigned net_id, struct in6_addr *prefix) status = android_getaddrinfofornet(ipv4_name, NULL, &hints, net_id, MARK_UNSET, &result); if (status != 0 || result == NULL) { - logmsg(ANDROID_LOG_ERROR, "plat_prefix/dns(%s) status = %d/%s", - ipv4_name, status, gai_strerror(status)); + logmsg(ANDROID_LOG_ERROR, "plat_prefix/dns(%s) status = %d/%s", ipv4_name, status, + gai_strerror(status)); return 0; } @@ -15,23 +15,23 @@ * * dump.c - print various headers for debugging */ -#include <stdio.h> #include <stdint.h> +#include <stdio.h> #include <stdlib.h> #include <arpa/inet.h> +#include <linux/icmp.h> +#include <netinet/icmp6.h> #include <netinet/in.h> #include <netinet/ip.h> +#include <netinet/ip6.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 <netinet/udp.h> -#include "debug.h" #include "checksum.h" #include "clatd.h" +#include "debug.h" #include "logging.h" #if CLAT_DEBUG @@ -44,29 +44,29 @@ void dump_ip(struct iphdr *header) { frag_flags = ntohs(header->frag_off); printf("IP packet\n"); - printf("header_len = %x\n",header->ihl); - printf("version = %x\n",header->version); - printf("tos = %x\n",header->tos); - printf("tot_len = %x\n",ntohs(header->tot_len)); - printf("id = %x\n",ntohs(header->id)); + printf("header_len = %x\n", header->ihl); + printf("version = %x\n", header->version); + printf("tos = %x\n", header->tos); + printf("tot_len = %x\n", ntohs(header->tot_len)); + printf("id = %x\n", ntohs(header->id)); printf("frag: "); - if(frag_flags & IP_RF) { + if (frag_flags & IP_RF) { printf("(RF) "); } - if(frag_flags & IP_DF) { + if (frag_flags & IP_DF) { printf("DF "); } - if(frag_flags & IP_MF) { + if (frag_flags & IP_MF) { printf("MF "); } - printf("offset = %x\n",frag_flags & IP_OFFMASK); - printf("ttl = %x\n",header->ttl); - printf("protocol = %x\n",header->protocol); - printf("checksum = %x\n",ntohs(header->check)); + printf("offset = %x\n", frag_flags & IP_OFFMASK); + printf("ttl = %x\n", header->ttl); + printf("protocol = %x\n", header->protocol); + printf("checksum = %x\n", ntohs(header->check)); inet_ntop(AF_INET, &header->saddr, addrstr, sizeof(addrstr)); - printf("saddr = %s\n",addrstr); + printf("saddr = %s\n", addrstr); inet_ntop(AF_INET, &header->daddr, addrstr, sizeof(addrstr)); - printf("daddr = %s\n",addrstr); + printf("daddr = %s\n", addrstr); } /* print ip6 header */ @@ -74,138 +74,138 @@ void dump_ip6(struct ip6_hdr *header) { char addrstr[INET6_ADDRSTRLEN]; printf("ipv6\n"); - printf("version = %x\n",header->ip6_vfc >> 4); - printf("traffic class = %x\n",header->ip6_flow >> 20); - printf("flow label = %x\n",ntohl(header->ip6_flow & 0x000fffff)); - printf("payload len = %x\n",ntohs(header->ip6_plen)); - printf("next header = %x\n",header->ip6_nxt); - printf("hop limit = %x\n",header->ip6_hlim); + printf("version = %x\n", header->ip6_vfc >> 4); + printf("traffic class = %x\n", header->ip6_flow >> 20); + printf("flow label = %x\n", ntohl(header->ip6_flow & 0x000fffff)); + printf("payload len = %x\n", ntohs(header->ip6_plen)); + printf("next header = %x\n", header->ip6_nxt); + printf("hop limit = %x\n", header->ip6_hlim); inet_ntop(AF_INET6, &header->ip6_src, addrstr, sizeof(addrstr)); - printf("source = %s\n",addrstr); + printf("source = %s\n", addrstr); inet_ntop(AF_INET6, &header->ip6_dst, addrstr, sizeof(addrstr)); - printf("dest = %s\n",addrstr); + printf("dest = %s\n", addrstr); } /* print icmp header */ void dump_icmp(struct icmphdr *icmp) { printf("ICMP\n"); - printf("icmp.type = %x ",icmp->type); - if(icmp->type == ICMP_ECHOREPLY) { + printf("icmp.type = %x ", icmp->type); + if (icmp->type == ICMP_ECHOREPLY) { printf("echo reply"); - } else if(icmp->type == ICMP_ECHO) { + } else if (icmp->type == ICMP_ECHO) { printf("echo request"); } else { printf("other"); } printf("\n"); - printf("icmp.code = %x\n",icmp->code); - printf("icmp.checksum = %x\n",ntohs(icmp->checksum)); - if(icmp->type == ICMP_ECHOREPLY || icmp->type == ICMP_ECHO) { - printf("icmp.un.echo.id = %x\n",ntohs(icmp->un.echo.id)); - printf("icmp.un.echo.sequence = %x\n",ntohs(icmp->un.echo.sequence)); + printf("icmp.code = %x\n", icmp->code); + printf("icmp.checksum = %x\n", ntohs(icmp->checksum)); + if (icmp->type == ICMP_ECHOREPLY || icmp->type == ICMP_ECHO) { + printf("icmp.un.echo.id = %x\n", ntohs(icmp->un.echo.id)); + printf("icmp.un.echo.sequence = %x\n", ntohs(icmp->un.echo.sequence)); } } /* print icmp6 header */ void dump_icmp6(struct icmp6_hdr *icmp6) { printf("ICMP6\n"); - printf("type = %x",icmp6->icmp6_type); - if(icmp6->icmp6_type == ICMP6_ECHO_REQUEST) { + printf("type = %x", icmp6->icmp6_type); + if (icmp6->icmp6_type == ICMP6_ECHO_REQUEST) { printf("(echo request)"); - } else if(icmp6->icmp6_type == ICMP6_ECHO_REPLY) { + } else if (icmp6->icmp6_type == ICMP6_ECHO_REPLY) { printf("(echo reply)"); } printf("\n"); - printf("code = %x\n",icmp6->icmp6_code); + printf("code = %x\n", icmp6->icmp6_code); - printf("checksum = %x\n",icmp6->icmp6_cksum); + printf("checksum = %x\n", icmp6->icmp6_cksum); - if((icmp6->icmp6_type == ICMP6_ECHO_REQUEST) || (icmp6->icmp6_type == ICMP6_ECHO_REPLY)) { - printf("icmp6_id = %x\n",icmp6->icmp6_id); - printf("icmp6_seq = %x\n",icmp6->icmp6_seq); + if ((icmp6->icmp6_type == ICMP6_ECHO_REQUEST) || (icmp6->icmp6_type == ICMP6_ECHO_REPLY)) { + printf("icmp6_id = %x\n", icmp6->icmp6_id); + printf("icmp6_seq = %x\n", icmp6->icmp6_seq); } } /* print udp header */ -void dump_udp_generic(const struct udphdr *udp, uint32_t temp_checksum, - const uint8_t *payload, size_t payload_size) { +void dump_udp_generic(const struct udphdr *udp, uint32_t temp_checksum, const uint8_t *payload, + size_t payload_size) { uint16_t my_checksum; temp_checksum = ip_checksum_add(temp_checksum, udp, sizeof(struct udphdr)); temp_checksum = ip_checksum_add(temp_checksum, payload, payload_size); - my_checksum = ip_checksum_finish(temp_checksum); + my_checksum = ip_checksum_finish(temp_checksum); printf("UDP\n"); - printf("source = %x\n",ntohs(udp->source)); - printf("dest = %x\n",ntohs(udp->dest)); - printf("len = %x\n",ntohs(udp->len)); - printf("check = %x (mine %x)\n",udp->check,my_checksum); + printf("source = %x\n", ntohs(udp->source)); + printf("dest = %x\n", ntohs(udp->dest)); + printf("len = %x\n", ntohs(udp->len)); + printf("check = %x (mine %x)\n", udp->check, my_checksum); } /* print ipv4/udp header */ -void dump_udp(const struct udphdr *udp, const struct iphdr *ip, - const uint8_t *payload, size_t payload_size) { +void dump_udp(const struct udphdr *udp, const struct iphdr *ip, const uint8_t *payload, + size_t payload_size) { uint32_t temp_checksum; temp_checksum = ipv4_pseudo_header_checksum(ip, sizeof(*udp) + payload_size); dump_udp_generic(udp, temp_checksum, payload, payload_size); } /* print ipv6/udp header */ -void dump_udp6(const struct udphdr *udp, const struct ip6_hdr *ip6, - const uint8_t *payload, size_t payload_size) { +void dump_udp6(const struct udphdr *udp, const struct ip6_hdr *ip6, const uint8_t *payload, + size_t payload_size) { uint32_t temp_checksum; temp_checksum = ipv6_pseudo_header_checksum(ip6, sizeof(*udp) + payload_size, IPPROTO_UDP); dump_udp_generic(udp, temp_checksum, payload, payload_size); } /* print tcp header */ -void dump_tcp_generic(const struct tcphdr *tcp, const uint8_t *options, size_t options_size, uint32_t temp_checksum, const uint8_t *payload, size_t payload_size) { +void dump_tcp_generic(const struct tcphdr *tcp, const uint8_t *options, size_t options_size, + uint32_t temp_checksum, const uint8_t *payload, size_t payload_size) { uint16_t my_checksum; temp_checksum = ip_checksum_add(temp_checksum, tcp, sizeof(struct tcphdr)); - if(options) { + if (options) { temp_checksum = ip_checksum_add(temp_checksum, options, options_size); } temp_checksum = ip_checksum_add(temp_checksum, payload, payload_size); - my_checksum = ip_checksum_finish(temp_checksum); + my_checksum = ip_checksum_finish(temp_checksum); printf("TCP\n"); - printf("source = %x\n",ntohs(tcp->source)); - printf("dest = %x\n",ntohs(tcp->dest)); - printf("seq = %x\n",ntohl(tcp->seq)); - printf("ack = %x\n",ntohl(tcp->ack_seq)); - printf("d_off = %x\n",tcp->doff); - printf("res1 = %x\n",tcp->res1); + printf("source = %x\n", ntohs(tcp->source)); + printf("dest = %x\n", ntohs(tcp->dest)); + printf("seq = %x\n", ntohl(tcp->seq)); + printf("ack = %x\n", ntohl(tcp->ack_seq)); + printf("d_off = %x\n", tcp->doff); + printf("res1 = %x\n", tcp->res1); #ifdef __BIONIC__ - printf("CWR = %x\n",tcp->cwr); - printf("ECE = %x\n",tcp->ece); + printf("CWR = %x\n", tcp->cwr); + printf("ECE = %x\n", tcp->ece); #else - printf("CWR/ECE = %x\n",tcp->res2); + printf("CWR/ECE = %x\n", tcp->res2); #endif - printf("urg = %x ack = %x psh = %x rst = %x syn = %x fin = %x\n", - tcp->urg, tcp->ack, tcp->psh, tcp->rst, tcp->syn, tcp->fin); - printf("window = %x\n",ntohs(tcp->window)); - printf("check = %x [mine %x]\n",tcp->check,my_checksum); - printf("urgent = %x\n",tcp->urg_ptr); + printf("urg = %x ack = %x psh = %x rst = %x syn = %x fin = %x\n", tcp->urg, tcp->ack, + tcp->psh, tcp->rst, tcp->syn, tcp->fin); + printf("window = %x\n", ntohs(tcp->window)); + printf("check = %x [mine %x]\n", tcp->check, my_checksum); + printf("urgent = %x\n", tcp->urg_ptr); - if(options) { + if (options) { size_t i; printf("options: "); - for(i=0; i<options_size; i++) { - printf("%x ",*(options+i)); + for (i = 0; i < options_size; i++) { + printf("%x ", *(options + i)); } printf("\n"); } } /* print ipv4/tcp header */ -void dump_tcp(const struct tcphdr *tcp, const struct iphdr *ip, - const uint8_t *payload, size_t payload_size, - const uint8_t *options, size_t options_size) { +void dump_tcp(const struct tcphdr *tcp, const struct iphdr *ip, const uint8_t *payload, + size_t payload_size, const uint8_t *options, size_t options_size) { uint32_t temp_checksum; temp_checksum = ipv4_pseudo_header_checksum(ip, sizeof(*tcp) + options_size + payload_size); @@ -213,27 +213,27 @@ void dump_tcp(const struct tcphdr *tcp, const struct iphdr *ip, } /* print ipv6/tcp header */ -void dump_tcp6(const struct tcphdr *tcp, const struct ip6_hdr *ip6, - const uint8_t *payload, size_t payload_size, - const uint8_t *options, size_t options_size) { +void dump_tcp6(const struct tcphdr *tcp, const struct ip6_hdr *ip6, const uint8_t *payload, + size_t payload_size, const uint8_t *options, size_t options_size) { uint32_t temp_checksum; - temp_checksum = ipv6_pseudo_header_checksum(ip6, sizeof(*tcp) + options_size + payload_size, IPPROTO_TCP); + temp_checksum = + ipv6_pseudo_header_checksum(ip6, sizeof(*tcp) + options_size + payload_size, IPPROTO_TCP); dump_tcp_generic(tcp, options, options_size, temp_checksum, payload, payload_size); } /* generic hex dump */ void logcat_hexdump(const char *info, const uint8_t *data, size_t len) { - char output[PACKETLEN*3+2]; + char output[PACKETLEN * 3 + 2]; size_t i; output[0] = '\0'; - for(i = 0; i < len && i < PACKETLEN; i++) { - snprintf(output + i*3, 4, " %02x", data[i]); + for (i = 0; i < len && i < PACKETLEN; i++) { + snprintf(output + i * 3, 4, " %02x", data[i]); } - output[len*3+3] = '\0'; + output[len * 3 + 3] = '\0'; - logmsg(ANDROID_LOG_WARN,"info %s len %d data%s", info, len, output); + logmsg(ANDROID_LOG_WARN, "info %s len %d data%s", info, len, output); } void dump_iovec(const struct iovec *iov, int iov_len) { @@ -18,21 +18,27 @@ #ifndef __DUMP_H__ #define __DUMP_H__ +#include <netinet/icmp6.h> +#include <netinet/in.h> +#include <netinet/ip.h> +#include <netinet/ip6.h> +#include <netinet/ip_icmp.h> +#include <netinet/tcp.h> +#include <netinet/udp.h> + void dump_ip(struct iphdr *header); void dump_icmp(struct icmphdr *icmp); -void dump_udp(const struct udphdr *udp, const struct iphdr *ip, - const uint8_t *payload, size_t payload_size); -void dump_tcp(const struct tcphdr *tcp, const struct iphdr *ip, - const uint8_t *payload, size_t payload_size, - const char *options, size_t options_size); +void dump_udp(const struct udphdr *udp, const struct iphdr *ip, const uint8_t *payload, + size_t payload_size); +void dump_tcp(const struct tcphdr *tcp, const struct iphdr *ip, const uint8_t *payload, + size_t payload_size, const char *options, size_t options_size); void dump_ip6(struct ip6_hdr *header); void dump_icmp6(struct icmp6_hdr *icmp6); -void dump_udp6(const struct udphdr *udp, const struct ip6_hdr *ip6, - const uint8_t *payload, size_t payload_size); -void dump_tcp6(const struct tcphdr *tcp, const struct ip6_hdr *ip6, - const uint8_t *payload, size_t payload_size, - const char *options, size_t options_size); +void dump_udp6(const struct udphdr *udp, const struct ip6_hdr *ip6, const uint8_t *payload, + size_t payload_size); +void dump_tcp6(const struct tcphdr *tcp, const struct ip6_hdr *ip6, const uint8_t *payload, + size_t payload_size, const char *options, size_t options_size); void logcat_hexdump(const char *info, const uint8_t *data, size_t len); void dump_iovec(const struct iovec *iov, int iov_len); @@ -15,10 +15,10 @@ * * getaddr.c - get a locally configured address */ +#include <net/if.h> #include <netinet/in.h> -#include <strings.h> #include <string.h> -#include <net/if.h> +#include <strings.h> #include <linux/if_addr.h> #include <linux/rtnetlink.h> @@ -26,8 +26,8 @@ #include <netlink/msg.h> #include "getaddr.h" -#include "netlink_msg.h" #include "logging.h" +#include "netlink_msg.h" // shared state between getinterface_ip and getaddr_cb struct target { @@ -39,8 +39,8 @@ struct target { /* function: getaddr_cb * callback for getinterface_ip - * msg - netlink message - * data - (struct target) info for which address we're looking for + * msg - netlink message + * data - (struct target) info for which address we're looking for */ static int getaddr_cb(struct nl_msg *msg, void *data) { struct ifaddrmsg *ifa_p; @@ -51,24 +51,22 @@ static int getaddr_cb(struct nl_msg *msg, void *data) { ifa_p = (struct ifaddrmsg *)nlmsg_data(nlmsg_hdr(msg)); rta_p = (struct rtattr *)IFA_RTA(ifa_p); - if(ifa_p->ifa_index != targ_p->ifindex) - return NL_OK; + if (ifa_p->ifa_index != targ_p->ifindex) return NL_OK; - if(ifa_p->ifa_scope != RT_SCOPE_UNIVERSE) - return NL_OK; + if (ifa_p->ifa_scope != RT_SCOPE_UNIVERSE) return NL_OK; rta_len = RTM_PAYLOAD(nlmsg_hdr(msg)); for (; RTA_OK(rta_p, rta_len); rta_p = RTA_NEXT(rta_p, rta_len)) { - switch(rta_p->rta_type) { + switch (rta_p->rta_type) { case IFA_ADDRESS: - if((targ_p->family == AF_INET6) && !(ifa_p->ifa_flags & IFA_F_SECONDARY)) { + if ((targ_p->family == AF_INET6) && !(ifa_p->ifa_flags & IFA_F_SECONDARY)) { memcpy(&targ_p->ip.ip6, RTA_DATA(rta_p), rta_p->rta_len - sizeof(struct rtattr)); targ_p->foundip = 1; return NL_OK; } break; case IFA_LOCAL: - if(targ_p->family == AF_INET) { + if (targ_p->family == AF_INET) { memcpy(&targ_p->ip.ip4, RTA_DATA(rta_p), rta_p->rta_len - sizeof(struct rtattr)); targ_p->foundip = 1; return NL_OK; @@ -82,9 +80,9 @@ static int getaddr_cb(struct nl_msg *msg, void *data) { /* function: error_handler * error callback for getinterface_ip - * nla - source of the error message - * err - netlink message - * arg - (struct target) info for which address we're looking for + * nla - source of the error message + * err - netlink message + * arg - (struct target) info for which address we're looking for */ static int error_handler(__attribute__((unused)) struct sockaddr_nl *nla, __attribute__((unused)) struct nlmsgerr *err, @@ -93,9 +91,10 @@ static int error_handler(__attribute__((unused)) struct sockaddr_nl *nla, } /* function: getinterface_ip - * finds the first global non-privacy IP of the given family for the given interface, or returns NULL. caller frees pointer - * interface - interface to look for - * family - family + * finds the first global non-privacy IP of the given family for the given interface, or returns + * NULL. caller frees pointer + * interface - interface to look for + * family - family */ union anyip *getinterface_ip(const char *interface, int family) { struct ifaddrmsg ifa; @@ -103,18 +102,18 @@ union anyip *getinterface_ip(const char *interface, int family) { struct target targ; union anyip *retval = NULL; - targ.family = family; + targ.family = family; targ.foundip = 0; targ.ifindex = if_nametoindex(interface); - if(targ.ifindex == 0) { - return NULL; // interface not found + if (targ.ifindex == 0) { + return NULL; // interface not found } memset(&ifa, 0, sizeof(ifa)); ifa.ifa_family = targ.family; callbacks = nl_cb_alloc(NL_CB_DEFAULT); - if(!callbacks) { + if (!callbacks) { goto cleanup; } nl_cb_set(callbacks, NL_CB_VALID, NL_CB_CUSTOM, getaddr_cb, &targ); @@ -123,18 +122,17 @@ union anyip *getinterface_ip(const char *interface, int family) { // sends message and waits for a response send_ifaddrmsg(RTM_GETADDR, NLM_F_REQUEST | NLM_F_ROOT, &ifa, callbacks); - if(targ.foundip) { + if (targ.foundip) { retval = malloc(sizeof(union anyip)); - if(!retval) { - logmsg(ANDROID_LOG_FATAL,"getinterface_ip/out of memory"); + if (!retval) { + logmsg(ANDROID_LOG_FATAL, "getinterface_ip/out of memory"); goto cleanup; } memcpy(retval, &targ.ip, sizeof(union anyip)); } cleanup: - if(callbacks) - nl_cb_put(callbacks); + if (callbacks) nl_cb_put(callbacks); return retval; } @@ -16,13 +16,13 @@ * icmp.c - convenience functions for translating ICMP and ICMPv6 packets. */ +#include <linux/icmp.h> +#include <netinet/icmp6.h> #include <netinet/in.h> #include <netinet/ip_icmp.h> -#include <netinet/icmp6.h> -#include <linux/icmp.h> -#include "logging.h" #include "icmp.h" +#include "logging.h" /* function: icmp_guess_ttl * Guesses the number of hops a received packet has traversed based on its TTL. @@ -44,17 +44,13 @@ uint8_t icmp_guess_ttl(uint8_t ttl) { * Determines whether an ICMP type is an error message. * type: the ICMP type */ -int is_icmp_error(uint8_t type) { - return type == 3 || type == 11 || type == 12; -} +int is_icmp_error(uint8_t type) { return type == 3 || type == 11 || type == 12; } /* function: is_icmp6_error * Determines whether an ICMPv6 type is an error message. * type: the ICMPv6 type */ -int is_icmp6_error(uint8_t type) { - return type < 128; -} +int is_icmp6_error(uint8_t type) { return type < 128; } /* function: icmp_to_icmp6_type * Maps ICMP types to ICMPv6 types. Partial implementation of RFC 6145, section 4.2. @@ -112,7 +108,7 @@ uint8_t icmp_to_icmp6_code(uint8_t type, uint8_t code) { case ICMP_UNREACH_PRECEDENCE_CUTOFF: return ICMP6_DST_UNREACH_ADMIN; - // Otherwise, we don't understand this ICMP type/code combination. Fall through. + // Otherwise, we don't understand this ICMP type/code combination. Fall through. } } logmsg_dbg(ANDROID_LOG_DEBUG, "icmp_to_icmp6_code: unhandled ICMP type/code %d/%d", type, code); @@ -172,7 +168,7 @@ uint8_t icmp6_to_icmp_code(uint8_t type, uint8_t code) { case ICMP6_DST_UNREACH_NOPORT: return ICMP_UNREACH_PORT; - // Otherwise, we don't understand this ICMPv6 type/code combination. Fall through. + // Otherwise, we don't understand this ICMPv6 type/code combination. Fall through. } } @@ -17,11 +17,11 @@ */ #include <string.h> -#include "translate.h" #include "checksum.h" -#include "logging.h" #include "debug.h" #include "dump.h" +#include "logging.h" +#include "translate.h" /* function: icmp_packet * translates an icmp packet @@ -36,12 +36,12 @@ int icmp_packet(clat_packet out, clat_packet_index pos, const struct icmphdr *ic const uint8_t *payload; size_t payload_size; - if(len < sizeof(struct icmphdr)) { + if (len < sizeof(struct icmphdr)) { logmsg_dbg(ANDROID_LOG_ERROR, "icmp_packet/(too small)"); return 0; } - payload = (const uint8_t *) (icmp + 1); + payload = (const uint8_t *)(icmp + 1); payload_size = len - sizeof(struct icmphdr); return icmp_to_icmp6(out, pos, icmp, checksum, payload, payload_size); @@ -55,8 +55,8 @@ int icmp_packet(clat_packet out, clat_packet_index pos, const struct icmphdr *ic * returns: the highest position in the output clat_packet that's filled in */ int ipv4_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, size_t len) { - const struct iphdr *header = (struct iphdr *) packet; - struct ip6_hdr *ip6_targ = (struct ip6_hdr *) out[pos].iov_base; + const struct iphdr *header = (struct iphdr *)packet; + struct ip6_hdr *ip6_targ = (struct ip6_hdr *)out[pos].iov_base; struct ip6_frag *frag_hdr; size_t frag_hdr_len; uint8_t nxthdr; @@ -65,22 +65,22 @@ int ipv4_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, s uint32_t old_sum, new_sum; int iov_len; - if(len < sizeof(struct iphdr)) { + if (len < sizeof(struct iphdr)) { logmsg_dbg(ANDROID_LOG_ERROR, "ip_packet/too short for an ip header"); return 0; } - if(header->ihl < 5) { + if (header->ihl < 5) { logmsg_dbg(ANDROID_LOG_ERROR, "ip_packet/ip header length set to less than 5: %x", header->ihl); return 0; } - if((size_t) header->ihl * 4 > len) { // ip header length larger than entire packet + if ((size_t)header->ihl * 4 > len) { // ip header length larger than entire packet logmsg_dbg(ANDROID_LOG_ERROR, "ip_packet/ip header length set too large: %x", header->ihl); return 0; } - if(header->version != 4) { + if (header->version != 4) { logmsg_dbg(ANDROID_LOG_ERROR, "ip_packet/ip header version not 4: %x", header->version); return 0; } @@ -90,8 +90,8 @@ int ipv4_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, s * translate the options. */ - next_header = packet + header->ihl*4; - len_left = len - header->ihl * 4; + next_header = packet + header->ihl * 4; + len_left = len - header->ihl * 4; nxthdr = header->protocol; if (nxthdr == IPPROTO_ICMP) { @@ -115,26 +115,26 @@ int ipv4_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, s new_sum = ipv6_pseudo_header_checksum(ip6_targ, len_left, nxthdr); // If the IPv4 packet is fragmented, add a Fragment header. - frag_hdr = (struct ip6_frag *) out[pos + 1].iov_base; - frag_hdr_len = maybe_fill_frag_header(frag_hdr, ip6_targ, header); + frag_hdr = (struct ip6_frag *)out[pos + 1].iov_base; + frag_hdr_len = maybe_fill_frag_header(frag_hdr, ip6_targ, header); out[pos + 1].iov_len = frag_hdr_len; if (frag_hdr_len && frag_hdr->ip6f_offlg & IP6F_OFF_MASK) { // Non-first fragment. Copy the rest of the packet as is. iov_len = generic_packet(out, pos + 2, next_header, len_left); } else if (nxthdr == IPPROTO_ICMPV6) { - iov_len = icmp_packet(out, pos + 2, (const struct icmphdr *) next_header, new_sum, len_left); + iov_len = icmp_packet(out, pos + 2, (const struct icmphdr *)next_header, new_sum, len_left); } else if (nxthdr == IPPROTO_TCP) { - iov_len = tcp_packet(out, pos + 2, (const struct tcphdr *) next_header, old_sum, new_sum, - len_left); + iov_len = + tcp_packet(out, pos + 2, (const struct tcphdr *)next_header, old_sum, new_sum, len_left); } else if (nxthdr == IPPROTO_UDP) { - iov_len = udp_packet(out, pos + 2, (const struct udphdr *) next_header, old_sum, new_sum, - len_left); + iov_len = + udp_packet(out, pos + 2, (const struct udphdr *)next_header, old_sum, new_sum, len_left); } else if (nxthdr == IPPROTO_GRE) { iov_len = generic_packet(out, pos + 2, next_header, len_left); } else { #if CLAT_DEBUG - logmsg_dbg(ANDROID_LOG_ERROR, "ip_packet/unknown protocol: %x",header->protocol); + logmsg_dbg(ANDROID_LOG_ERROR, "ip_packet/unknown protocol: %x", header->protocol); logcat_hexdump("ipv4/protocol", packet, len); #endif return 0; @@ -19,12 +19,12 @@ #include <arpa/inet.h> -#include "translate.h" #include "checksum.h" -#include "logging.h" -#include "dump.h" #include "config.h" #include "debug.h" +#include "dump.h" +#include "logging.h" +#include "translate.h" /* function: icmp6_packet * takes an icmp6 packet and sets it up for translation @@ -39,12 +39,12 @@ int icmp6_packet(clat_packet out, clat_packet_index pos, const struct icmp6_hdr const uint8_t *payload; size_t payload_size; - if(len < sizeof(struct icmp6_hdr)) { + if (len < sizeof(struct icmp6_hdr)) { logmsg_dbg(ANDROID_LOG_ERROR, "icmp6_packet/(too small)"); return 0; } - payload = (const uint8_t *) (icmp6 + 1); + payload = (const uint8_t *)(icmp6 + 1); payload_size = len - sizeof(struct icmp6_hdr); return icmp6_to_icmp(out, pos, icmp6, payload, payload_size); @@ -76,8 +76,8 @@ void log_bad_address(const char *fmt, const struct in6_addr *src, const struct i * returns: the highest position in the output clat_packet that's filled in */ int ipv6_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, size_t len) { - const struct ip6_hdr *ip6 = (struct ip6_hdr *) packet; - struct iphdr *ip_targ = (struct iphdr *) out[pos].iov_base; + const struct ip6_hdr *ip6 = (struct ip6_hdr *)packet; + struct iphdr *ip_targ = (struct iphdr *)out[pos].iov_base; struct ip6_frag *frag_hdr = NULL; uint8_t protocol; const uint8_t *next_header; @@ -85,14 +85,14 @@ int ipv6_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, s uint32_t old_sum, new_sum; int iov_len; - if(len < sizeof(struct ip6_hdr)) { + if (len < sizeof(struct ip6_hdr)) { logmsg_dbg(ANDROID_LOG_ERROR, "ipv6_packet/too short for an ip6 header: %d", len); return 0; } - if(IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { + if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) { log_bad_address("ipv6_packet/multicast %s->%s", &ip6->ip6_src, &ip6->ip6_dst); - return 0; // silently ignore + return 0; // silently ignore } // If the packet is not from the plat subnet to the local subnet, or vice versa, drop it, unless @@ -111,7 +111,7 @@ int ipv6_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, s } next_header = packet + sizeof(struct ip6_hdr); - len_left = len - sizeof(struct ip6_hdr); + len_left = len - sizeof(struct ip6_hdr); protocol = ip6->ip6_nxt; @@ -125,7 +125,7 @@ int ipv6_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, s // If there's a Fragment header, parse it and decide what the next header is. // Do this before calculating the pseudo-header checksum because it updates the next header value. if (protocol == IPPROTO_FRAGMENT) { - frag_hdr = (struct ip6_frag *) next_header; + frag_hdr = (struct ip6_frag *)next_header; if (len_left < sizeof(*frag_hdr)) { logmsg_dbg(ANDROID_LOG_ERROR, "ipv6_packet/too short for fragment header: %d", len); return 0; @@ -139,7 +139,7 @@ int ipv6_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, s // ICMP and ICMPv6 have different protocol numbers. if (protocol == IPPROTO_ICMPV6) { - protocol = IPPROTO_ICMP; + protocol = IPPROTO_ICMP; ip_targ->protocol = IPPROTO_ICMP; } @@ -155,13 +155,13 @@ int ipv6_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, s if (frag_hdr && (frag_hdr->ip6f_offlg & IP6F_OFF_MASK)) { iov_len = generic_packet(out, pos + 2, next_header, len_left); } else if (protocol == IPPROTO_ICMP) { - iov_len = icmp6_packet(out, pos + 2, (const struct icmp6_hdr *) next_header, len_left); + iov_len = icmp6_packet(out, pos + 2, (const struct icmp6_hdr *)next_header, len_left); } else if (protocol == IPPROTO_TCP) { - iov_len = tcp_packet(out, pos + 2, (const struct tcphdr *) next_header, old_sum, new_sum, - len_left); + iov_len = + tcp_packet(out, pos + 2, (const struct tcphdr *)next_header, old_sum, new_sum, len_left); } else if (protocol == IPPROTO_UDP) { - iov_len = udp_packet(out, pos + 2, (const struct udphdr *) next_header, old_sum, new_sum, - len_left); + iov_len = + udp_packet(out, pos + 2, (const struct udphdr *)next_header, old_sum, new_sum, len_left); } else if (protocol == IPPROTO_GRE) { iov_len = generic_packet(out, pos + 2, next_header, len_left); } else { @@ -174,6 +174,6 @@ int ipv6_packet(clat_packet out, clat_packet_index pos, const uint8_t *packet, s // Set the length and calculate the checksum. ip_targ->tot_len = htons(ntohs(ip_targ->tot_len) + packet_length(out, pos)); - ip_targ->check = ip_checksum(ip_targ, sizeof(struct iphdr)); + ip_targ->check = ip_checksum(ip_targ, sizeof(struct iphdr)); return iov_len; } @@ -16,11 +16,11 @@ * logging.c - print a log message */ -#include <stdarg.h> #include <android/log.h> +#include <stdarg.h> -#include "logging.h" #include "debug.h" +#include "logging.h" /* function: logmsg * prints a log message to android's log buffer @@ -16,12 +16,12 @@ * mtu.c - get interface mtu */ -#include <string.h> +#include <net/if.h> #include <stdlib.h> -#include <sys/types.h> -#include <sys/socket.h> +#include <string.h> #include <sys/ioctl.h> -#include <net/if.h> +#include <sys/socket.h> +#include <sys/types.h> #include "mtu.h" @@ -34,12 +34,12 @@ int getifmtu(const char *ifname) { struct ifreq if_mtu; fd = socket(AF_INET, SOCK_STREAM, 0); - if(fd < 0) { + if (fd < 0) { return -1; } strncpy(if_mtu.ifr_name, ifname, IFNAMSIZ); if_mtu.ifr_name[IFNAMSIZ - 1] = '\0'; - if(ioctl(fd, SIOCGIFMTU, &if_mtu) < 0) { + if (ioctl(fd, SIOCGIFMTU, &if_mtu) < 0) { return -1; } return if_mtu.ifr_mtu; diff --git a/netlink_callbacks.c b/netlink_callbacks.c index a79aa76..804976d 100644 --- a/netlink_callbacks.c +++ b/netlink_callbacks.c @@ -15,8 +15,8 @@ * * netlink_callbacks.c - generic callbacks for netlink responses */ -#include <netinet/in.h> #include <net/if.h> +#include <netinet/in.h> #include <linux/rtnetlink.h> #include <netlink/handlers.h> @@ -29,7 +29,7 @@ */ static int ack_handler(__attribute__((unused)) struct nl_msg *msg, void *data) { int *retval = data; - *retval = 0; + *retval = 0; return NL_OK; } @@ -39,26 +39,26 @@ static int ack_handler(__attribute__((unused)) struct nl_msg *msg, void *data) { * err - netlink error message * arg - pointer to an int, stores the error code */ -static int error_handler(__attribute__((unused)) struct sockaddr_nl *nla, - struct nlmsgerr *err, void *arg) { +static int error_handler(__attribute__((unused)) struct sockaddr_nl *nla, struct nlmsgerr *err, + void *arg) { int *retval = arg; - if(err->error < 0) { + if (err->error < 0) { *retval = err->error; } else { - *retval = 0; // NLMSG_ERROR used as reply type on no error + *retval = 0; // NLMSG_ERROR used as reply type on no error } return NL_OK; } /* function: alloc_ack_callbacks - * allocates a set of netlink callbacks. returns NULL on failure. callbacks will modify retval with <0 meaning failure - * retval - shared state between caller and callback functions + * allocates a set of netlink callbacks. returns NULL on failure. callbacks will modify retval + * with <0 meaning failure retval - shared state between caller and callback functions */ struct nl_cb *alloc_ack_callbacks(int *retval) { struct nl_cb *callbacks; callbacks = nl_cb_alloc(NL_CB_DEFAULT); - if(!callbacks) { + if (!callbacks) { return NULL; } nl_cb_set(callbacks, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, retval); diff --git a/netlink_msg.c b/netlink_msg.c index 13906f4..be76ecd 100644 --- a/netlink_msg.c +++ b/netlink_msg.c @@ -16,29 +16,29 @@ * netlink_msg.c - send an ifaddrmsg/ifinfomsg/rtmsg via netlink */ -#include <netinet/in.h> +#include <errno.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> +#include <netinet/in.h> #include <string.h> -#include <errno.h> #include <netlink-private/object-api.h> #include <netlink-private/types.h> -#include <netlink/socket.h> -#include <netlink/netlink.h> #include <netlink/msg.h> +#include <netlink/netlink.h> +#include <netlink/socket.h> -#include "netlink_msg.h" #include "netlink_callbacks.h" +#include "netlink_msg.h" /* function: family_size * returns the size of the address structure for the given family, or 0 on error * family - AF_INET or AF_INET6 */ size_t inet_family_size(int family) { - if(family == AF_INET) { + if (family == AF_INET) { return sizeof(struct in_addr); - } else if(family == AF_INET6) { + } else if (family == AF_INET6) { return sizeof(struct in6_addr); } else { return 0; @@ -52,11 +52,12 @@ size_t inet_family_size(int family) { * payload_struct - pointer to a struct to add to netlink message * payload_len - bytelength of structure */ -struct nl_msg *nlmsg_alloc_generic(uint16_t type, uint16_t flags, void *payload_struct, size_t payload_len) { +struct nl_msg *nlmsg_alloc_generic(uint16_t type, uint16_t flags, void *payload_struct, + size_t payload_len) { struct nl_msg *msg; msg = nlmsg_alloc(); - if(!msg) { + if (!msg) { return NULL; } @@ -65,9 +66,9 @@ struct nl_msg *nlmsg_alloc_generic(uint16_t type, uint16_t flags, void *payload_ return NULL; } - msg->nm_nlh->nlmsg_len = NLMSG_LENGTH(payload_len); + msg->nm_nlh->nlmsg_len = NLMSG_LENGTH(payload_len); msg->nm_nlh->nlmsg_flags = flags; - msg->nm_nlh->nlmsg_type = type; + msg->nm_nlh->nlmsg_type = type; memcpy(nlmsg_data(msg->nm_nlh), payload_struct, payload_len); @@ -116,7 +117,7 @@ int netlink_set_kernel_only(struct nl_sock *nl_sk) { } int sockfd = nl_socket_get_fd(nl_sk); - return connect(sockfd, (struct sockaddr *) &addr, sizeof(addr)); + return connect(sockfd, (struct sockaddr *)&addr, sizeof(addr)); } /* function: send_netlink_msg @@ -128,23 +129,18 @@ void send_netlink_msg(struct nl_msg *msg, struct nl_cb *callbacks) { struct nl_sock *nl_sk; nl_sk = nl_socket_alloc(); - if(!nl_sk) - goto cleanup; + if (!nl_sk) goto cleanup; - if(nl_connect(nl_sk, NETLINK_ROUTE) != 0) - goto cleanup; + if (nl_connect(nl_sk, NETLINK_ROUTE) != 0) goto cleanup; - if(nl_send_auto_complete(nl_sk, msg) < 0) - goto cleanup; + if (nl_send_auto_complete(nl_sk, msg) < 0) goto cleanup; - if(netlink_set_kernel_only(nl_sk) < 0) - goto cleanup; + if (netlink_set_kernel_only(nl_sk) < 0) goto cleanup; nl_recvmsgs(nl_sk, callbacks); cleanup: - if(nl_sk) - nl_socket_free(nl_sk); + if (nl_sk) nl_socket_free(nl_sk); } /* function: send_ifaddrmsg @@ -158,8 +154,7 @@ void send_ifaddrmsg(uint16_t type, uint16_t flags, struct ifaddrmsg *ifa, struct struct nl_msg *msg = NULL; msg = nlmsg_alloc_ifaddr(type, flags, ifa); - if(!msg) - return; + if (!msg) return; send_netlink_msg(msg, callbacks); @@ -172,10 +167,10 @@ void send_ifaddrmsg(uint16_t type, uint16_t flags, struct ifaddrmsg *ifa, struct */ int netlink_sendrecv(struct nl_msg *msg) { struct nl_cb *callbacks = NULL; - int retval = -EIO; + int retval = -EIO; callbacks = alloc_ack_callbacks(&retval); - if(!callbacks) { + if (!callbacks) { return -ENOMEM; } @@ -16,13 +16,13 @@ * ring.c - packet ring buffer functions */ -#include <errno.h> -#include <string.h> #include <arpa/inet.h> -#include <sys/socket.h> -#include <sys/mman.h> +#include <errno.h> #include <linux/if.h> #include <linux/if_packet.h> +#include <string.h> +#include <sys/mman.h> +#include <sys/socket.h> #include "logging.h" #include "ring.h" @@ -37,26 +37,26 @@ int ring_create(struct tun_data *tunnel) { } int ver = TPACKET_V2; - if (setsockopt(packetsock, SOL_PACKET, PACKET_VERSION, (void *) &ver, sizeof(ver))) { + if (setsockopt(packetsock, SOL_PACKET, PACKET_VERSION, (void *)&ver, sizeof(ver))) { logmsg(ANDROID_LOG_FATAL, "setsockopt(PACKET_VERSION, %d) failed: %s", ver, strerror(errno)); return -1; } int on = 1; - if (setsockopt(packetsock, SOL_PACKET, PACKET_LOSS, (void *) &on, sizeof(on))) { + if (setsockopt(packetsock, SOL_PACKET, PACKET_LOSS, (void *)&on, sizeof(on))) { logmsg(ANDROID_LOG_WARN, "PACKET_LOSS failed: %s", strerror(errno)); } struct packet_ring *ring = &tunnel->ring; - ring->numblocks = TP_NUM_BLOCKS; + ring->numblocks = TP_NUM_BLOCKS; int total_frames = TP_FRAMES * ring->numblocks; struct tpacket_req req = { - .tp_frame_size = TP_FRAME_SIZE, // Frame size. - .tp_block_size = TP_BLOCK_SIZE, // Frames per block. - .tp_block_nr = ring->numblocks, // Number of blocks. - .tp_frame_nr = total_frames, // Total frames. + .tp_frame_size = TP_FRAME_SIZE, // Frame size. + .tp_block_size = TP_BLOCK_SIZE, // Frames per block. + .tp_block_nr = ring->numblocks, // Number of blocks. + .tp_frame_nr = total_frames, // Total frames. }; if (setsockopt(packetsock, SOL_PACKET, PACKET_RX_RING, &req, sizeof(req)) < 0) { @@ -65,20 +65,20 @@ int ring_create(struct tun_data *tunnel) { } size_t buflen = TP_BLOCK_SIZE * ring->numblocks; - ring->base = mmap(NULL, buflen, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_LOCKED|MAP_POPULATE, + ring->base = mmap(NULL, buflen, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED | MAP_POPULATE, packetsock, 0); if (ring->base == MAP_FAILED) { logmsg(ANDROID_LOG_FATAL, "mmap %lu failed: %s", buflen, strerror(errno)); return -1; } - ring->block = 0; - ring->slot = 0; + ring->block = 0; + ring->slot = 0; ring->numslots = TP_BLOCK_SIZE / TP_FRAME_SIZE; - ring->next = (struct tpacket2_hdr *) ring->base; + ring->next = (struct tpacket2_hdr *)ring->base; - logmsg(ANDROID_LOG_INFO, "Using ring buffer with %d frames (%d bytes) at %p", - total_frames, buflen, ring->base); + logmsg(ANDROID_LOG_INFO, "Using ring buffer with %d frames (%d bytes) at %p", total_frames, + buflen, ring->base); return packetsock; } @@ -87,8 +87,8 @@ int ring_create(struct tun_data *tunnel) { * advances to the next position in the packet ring * ring - packet ring buffer */ -static struct tpacket2_hdr* ring_advance(struct packet_ring *ring) { - uint8_t *next = (uint8_t *) ring->next; +static struct tpacket2_hdr *ring_advance(struct packet_ring *ring) { + uint8_t *next = (uint8_t *)ring->next; ring->slot++; next += TP_FRAME_SIZE; @@ -101,11 +101,11 @@ static struct tpacket2_hdr* ring_advance(struct packet_ring *ring) { next += TP_FRAME_GAP; } else { ring->block = 0; - next = (uint8_t *) ring->base; + next = (uint8_t *)ring->base; } } - ring->next = (struct tpacket2_hdr *) next; + ring->next = (struct tpacket2_hdr *)next; return ring->next; } @@ -118,9 +118,9 @@ static struct tpacket2_hdr* ring_advance(struct packet_ring *ring) { void ring_read(struct packet_ring *ring, int write_fd, int to_ipv6) { struct tpacket2_hdr *tp = ring->next; if (tp->tp_status & TP_STATUS_USER) { - uint8_t *packet = ((uint8_t *) tp) + tp->tp_net; + uint8_t *packet = ((uint8_t *)tp) + tp->tp_net; translate_packet(write_fd, to_ipv6, packet, tp->tp_len); tp->tp_status = TP_STATUS_KERNEL; - tp = ring_advance(ring); + tp = ring_advance(ring); } } @@ -16,8 +16,8 @@ * setif.c - network interface configuration */ #include <errno.h> -#include <netinet/in.h> #include <net/if.h> +#include <netinet/in.h> #include <linux/rtnetlink.h> #include <netlink/handlers.h> @@ -26,7 +26,11 @@ #include "logging.h" #include "netlink_msg.h" -#define DEBUG_OPTNAME(a) case (a): { optname = #a; break; } +#define DEBUG_OPTNAME(a) \ + case (a): { \ + optname = #a; \ + break; \ + } /* function: add_address * adds an IP address to/from an interface, returns 0 on success and <0 on failure @@ -36,14 +40,15 @@ * prefixlen - bitlength of network (example: 24 for AF_INET's 255.255.255.0) * broadcast - broadcast address (only for AF_INET, ignored for AF_INET6) */ -int add_address(const char *ifname, int family, const void *address, int prefixlen, const void *broadcast) { +int add_address(const char *ifname, int family, const void *address, int prefixlen, + const void *broadcast) { int retval; size_t addr_size; struct ifaddrmsg ifa; struct nl_msg *msg = NULL; addr_size = inet_family_size(family); - if(addr_size == 0) { + if (addr_size == 0) { retval = -EAFNOSUPPORT; goto cleanup; } @@ -53,29 +58,30 @@ int add_address(const char *ifname, int family, const void *address, int prefixl retval = -ENODEV; goto cleanup; } - ifa.ifa_family = family; + ifa.ifa_family = family; ifa.ifa_prefixlen = prefixlen; - ifa.ifa_scope = RT_SCOPE_UNIVERSE; + ifa.ifa_scope = RT_SCOPE_UNIVERSE; - msg = nlmsg_alloc_ifaddr(RTM_NEWADDR, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE, &ifa); - if(!msg) { + msg = + nlmsg_alloc_ifaddr(RTM_NEWADDR, NLM_F_ACK | NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE, &ifa); + if (!msg) { retval = -ENOMEM; goto cleanup; } - if(nla_put(msg, IFA_LOCAL, addr_size, address) < 0) { + if (nla_put(msg, IFA_LOCAL, addr_size, address) < 0) { retval = -ENOMEM; goto cleanup; } - if(family == AF_INET6) { + if (family == AF_INET6) { // AF_INET6 gets IFA_LOCAL + IFA_ADDRESS - if(nla_put(msg, IFA_ADDRESS, addr_size, address) < 0) { + if (nla_put(msg, IFA_ADDRESS, addr_size, address) < 0) { retval = -ENOMEM; goto cleanup; } - } else if(family == AF_INET) { + } else if (family == AF_INET) { // AF_INET gets IFA_LOCAL + IFA_BROADCAST - if(nla_put(msg, IFA_BROADCAST, addr_size, broadcast) < 0) { + if (nla_put(msg, IFA_BROADCAST, addr_size, broadcast) < 0) { retval = -ENOMEM; goto cleanup; } @@ -87,8 +93,7 @@ int add_address(const char *ifname, int family, const void *address, int prefixl retval = netlink_sendrecv(msg); cleanup: - if(msg) - nlmsg_free(msg); + if (msg) nlmsg_free(msg); return retval; } @@ -109,15 +114,15 @@ int if_up(const char *ifname, int mtu) { goto cleanup; } ifi.ifi_change = IFF_UP; - ifi.ifi_flags = IFF_UP; + ifi.ifi_flags = IFF_UP; msg = nlmsg_alloc_ifinfo(RTM_SETLINK, NLM_F_ACK | NLM_F_REQUEST | NLM_F_ROOT, &ifi); - if(!msg) { + if (!msg) { retval = -ENOMEM; goto cleanup; } - if(nla_put(msg, IFLA_MTU, 4, &mtu) < 0) { + if (nla_put(msg, IFLA_MTU, 4, &mtu) < 0) { retval = -ENOMEM; goto cleanup; } @@ -125,8 +130,7 @@ int if_up(const char *ifname, int mtu) { retval = netlink_sendrecv(msg); cleanup: - if(msg) - nlmsg_free(msg); + if (msg) nlmsg_free(msg); return retval; } @@ -18,7 +18,8 @@ #ifndef __SETIF_H__ #define __SETIF_H__ -int add_address(const char *ifname, int family, const void *address, int cidr, const void *broadcast); +int add_address(const char *ifname, int family, const void *address, int cidr, + const void *broadcast); int if_up(const char *ifname, int mtu); int add_anycast_address(int sock, const struct in6_addr *addr, const char *interface); diff --git a/translate.c b/translate.c index ddc9bac..58a7e9d 100644 --- a/translate.c +++ b/translate.c @@ -17,13 +17,13 @@ */ #include <string.h> -#include "icmp.h" -#include "translate.h" #include "checksum.h" #include "clatd.h" #include "config.h" -#include "logging.h" #include "debug.h" +#include "icmp.h" +#include "logging.h" +#include "translate.h" #include "tun.h" /* function: packet_checksum @@ -97,7 +97,7 @@ struct in6_addr ipv4_addr_to_ipv6_addr(uint32_t addr4) { return Global_Clatd_Config.ipv6_local_subnet; } else { // Assumes a /96 plat subnet. - addr6 = Global_Clatd_Config.plat_subnet; + addr6 = Global_Clatd_Config.plat_subnet; addr6.s6_addr32[3] = addr4; return addr6; } @@ -125,15 +125,15 @@ void fill_ip_header(struct iphdr *ip, uint16_t payload_len, uint8_t protocol, int ttl_guess; memset(ip, 0, sizeof(struct iphdr)); - ip->ihl = 5; - ip->version = 4; - ip->tos = 0; - ip->tot_len = htons(sizeof(struct iphdr) + payload_len); - ip->id = 0; + ip->ihl = 5; + ip->version = 4; + ip->tos = 0; + ip->tot_len = htons(sizeof(struct iphdr) + payload_len); + ip->id = 0; ip->frag_off = htons(IP_DF); - ip->ttl = old_header->ip6_hlim; + ip->ttl = old_header->ip6_hlim; ip->protocol = protocol; - ip->check = 0; + ip->check = 0; ip->saddr = ipv6_addr_to_ipv4_addr(&old_header->ip6_src); ip->daddr = ipv6_addr_to_ipv4_addr(&old_header->ip6_dst); @@ -141,7 +141,7 @@ void fill_ip_header(struct iphdr *ip, uint16_t payload_len, uint8_t protocol, // Third-party ICMPv6 message. This may have been originated by an native IPv6 address. // In that case, the source IPv6 address can't be translated and we need to make up an IPv4 // source address. For now, use 255.0.0.<ttl>, which at least looks useful in traceroute. - if ((uint32_t) ip->saddr == INADDR_NONE) { + if ((uint32_t)ip->saddr == INADDR_NONE) { ttl_guess = icmp_guess_ttl(old_header->ip6_hlim); ip->saddr = htonl((0xff << 24) + ttl_guess); } @@ -158,9 +158,9 @@ void fill_ip6_header(struct ip6_hdr *ip6, uint16_t payload_len, uint8_t protocol const struct iphdr *old_header) { memset(ip6, 0, sizeof(struct ip6_hdr)); - ip6->ip6_vfc = 6 << 4; + ip6->ip6_vfc = 6 << 4; ip6->ip6_plen = htons(payload_len); - ip6->ip6_nxt = protocol; + ip6->ip6_nxt = protocol; ip6->ip6_hlim = old_header->ttl; ip6->ip6_src = ipv4_addr_to_ipv6_addr(old_header->saddr); @@ -178,13 +178,13 @@ void fill_ip6_header(struct ip6_hdr *ip6, uint16_t payload_len, uint8_t protocol size_t maybe_fill_frag_header(struct ip6_frag *frag_hdr, struct ip6_hdr *ip6_targ, const struct iphdr *old_header) { uint16_t frag_flags = ntohs(old_header->frag_off); - uint16_t frag_off = frag_flags & IP_OFFMASK; + uint16_t frag_off = frag_flags & IP_OFFMASK; if (frag_off == 0 && (frag_flags & IP_MF) == 0) { // Not a fragment. return 0; } - frag_hdr->ip6f_nxt = ip6_targ->ip6_nxt; + frag_hdr->ip6f_nxt = ip6_targ->ip6_nxt; frag_hdr->ip6f_reserved = 0; // In IPv4, the offset is the bottom 13 bits; in IPv6 it's the top 13 bits. frag_hdr->ip6f_offlg = htons(frag_off << 3); @@ -192,7 +192,7 @@ size_t maybe_fill_frag_header(struct ip6_frag *frag_hdr, struct ip6_hdr *ip6_tar frag_hdr->ip6f_offlg |= IP6F_MORE_FRAG; } frag_hdr->ip6f_ident = htonl(ntohs(old_header->id)); - ip6_targ->ip6_nxt = IPPROTO_FRAGMENT; + ip6_targ->ip6_nxt = IPPROTO_FRAGMENT; return sizeof(*frag_hdr); } @@ -210,7 +210,7 @@ uint8_t parse_frag_header(const struct ip6_frag *frag_hdr, struct iphdr *ip_targ frag_off |= IP_MF; } ip_targ->frag_off = htons(frag_off); - ip_targ->id = htons(ntohl(frag_hdr->ip6f_ident) & 0xffff); + ip_targ->id = htons(ntohl(frag_hdr->ip6f_ident) & 0xffff); ip_targ->protocol = frag_hdr->ip6f_nxt; return frag_hdr->ip6f_nxt; } @@ -232,15 +232,13 @@ int icmp_to_icmp6(clat_packet out, clat_packet_index pos, const struct icmphdr * memset(icmp6_targ, 0, sizeof(struct icmp6_hdr)); - icmp6_type = icmp_to_icmp6_type(icmp->type, icmp->code); + icmp6_type = icmp_to_icmp6_type(icmp->type, icmp->code); icmp6_targ->icmp6_type = icmp6_type; icmp6_targ->icmp6_code = icmp_to_icmp6_code(icmp->type, icmp->code); out[pos].iov_len = sizeof(struct icmp6_hdr); - if (pos == CLAT_POS_TRANSPORTHDR && - is_icmp_error(icmp->type) && - icmp6_type != ICMP6_PARAM_PROB) { + if (pos == CLAT_POS_TRANSPORTHDR && is_icmp_error(icmp->type) && icmp6_type != ICMP6_PARAM_PROB) { // An ICMP error we understand, one level deep. // Translate the nested packet (the one that caused the error). clat_packet_len = ipv4_packet(out, pos + 1, payload, payload_size); @@ -254,11 +252,11 @@ int icmp_to_icmp6(clat_packet out, clat_packet_index pos, const struct icmphdr * checksum = checksum + htons(20); } else if (icmp6_type == ICMP6_ECHO_REQUEST || icmp6_type == ICMP6_ECHO_REPLY) { // Ping packet. - icmp6_targ->icmp6_id = icmp->un.echo.id; - icmp6_targ->icmp6_seq = icmp->un.echo.sequence; - out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *) payload; - out[CLAT_POS_PAYLOAD].iov_len = payload_size; - clat_packet_len = CLAT_POS_PAYLOAD + 1; + icmp6_targ->icmp6_id = icmp->un.echo.id; + icmp6_targ->icmp6_seq = icmp->un.echo.sequence; + out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *)payload; + out[CLAT_POS_PAYLOAD].iov_len = payload_size; + clat_packet_len = CLAT_POS_PAYLOAD + 1; } else { // Unknown type/code. The type/code conversion functions have already logged an error. return 0; @@ -286,27 +284,26 @@ int icmp6_to_icmp(clat_packet out, clat_packet_index pos, const struct icmp6_hdr memset(icmp_targ, 0, sizeof(struct icmphdr)); - icmp_type = icmp6_to_icmp_type(icmp6->icmp6_type, icmp6->icmp6_code); + icmp_type = icmp6_to_icmp_type(icmp6->icmp6_type, icmp6->icmp6_code); icmp_targ->type = icmp_type; icmp_targ->code = icmp6_to_icmp_code(icmp6->icmp6_type, icmp6->icmp6_code); out[pos].iov_len = sizeof(struct icmphdr); - if (pos == CLAT_POS_TRANSPORTHDR && - is_icmp6_error(icmp6->icmp6_type) && + if (pos == CLAT_POS_TRANSPORTHDR && is_icmp6_error(icmp6->icmp6_type) && icmp_type != ICMP_PARAMETERPROB) { // An ICMPv6 error we understand, one level deep. // Translate the nested packet (the one that caused the error). clat_packet_len = ipv6_packet(out, pos + 1, payload, payload_size); } else if (icmp_type == ICMP_ECHO || icmp_type == ICMP_ECHOREPLY) { // Ping packet. - icmp_targ->un.echo.id = icmp6->icmp6_id; - icmp_targ->un.echo.sequence = icmp6->icmp6_seq; - out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *) payload; - out[CLAT_POS_PAYLOAD].iov_len = payload_size; - clat_packet_len = CLAT_POS_PAYLOAD + 1; + icmp_targ->un.echo.id = icmp6->icmp6_id; + icmp_targ->un.echo.sequence = icmp6->icmp6_seq; + out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *)payload; + out[CLAT_POS_PAYLOAD].iov_len = payload_size; + clat_packet_len = CLAT_POS_PAYLOAD + 1; } else { - // Unknown type/code. The type/code conversion functions have already logged an error. + // Unknown type/code. The type/code conversion functions have already logged an error. return 0; } @@ -325,9 +322,9 @@ int icmp6_to_icmp(clat_packet out, clat_packet_index pos, const struct icmp6_hdr * returns: the highest position in the output clat_packet that's filled in */ int generic_packet(clat_packet out, clat_packet_index pos, const uint8_t *payload, size_t len) { - out[pos].iov_len = 0; - out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *) payload; - out[CLAT_POS_PAYLOAD].iov_len = len; + out[pos].iov_len = 0; + out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *)payload; + out[CLAT_POS_PAYLOAD].iov_len = len; return CLAT_POS_PAYLOAD + 1; } @@ -340,17 +337,17 @@ int generic_packet(clat_packet out, clat_packet_index pos, const uint8_t *payloa * new_sum - pseudo-header checksum of new header * len - size of ip payload */ -int udp_packet(clat_packet out, clat_packet_index pos, const struct udphdr *udp, - uint32_t old_sum, uint32_t new_sum, size_t len) { +int udp_packet(clat_packet out, clat_packet_index pos, const struct udphdr *udp, uint32_t old_sum, + uint32_t new_sum, size_t len) { const uint8_t *payload; size_t payload_size; - if(len < sizeof(struct udphdr)) { - logmsg_dbg(ANDROID_LOG_ERROR,"udp_packet/(too small)"); + if (len < sizeof(struct udphdr)) { + logmsg_dbg(ANDROID_LOG_ERROR, "udp_packet/(too small)"); return 0; } - payload = (const uint8_t *) (udp + 1); + payload = (const uint8_t *)(udp + 1); payload_size = len - sizeof(struct udphdr); return udp_translate(out, pos, udp, old_sum, new_sum, payload, payload_size); @@ -364,28 +361,28 @@ int udp_packet(clat_packet out, clat_packet_index pos, const struct udphdr *udp, * len - size of ip payload * returns: the highest position in the output clat_packet that's filled in */ -int tcp_packet(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp, - uint32_t old_sum, uint32_t new_sum, size_t len) { +int tcp_packet(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp, uint32_t old_sum, + uint32_t new_sum, size_t len) { const uint8_t *payload; size_t payload_size, header_size; - if(len < sizeof(struct tcphdr)) { - logmsg_dbg(ANDROID_LOG_ERROR,"tcp_packet/(too small)"); + if (len < sizeof(struct tcphdr)) { + logmsg_dbg(ANDROID_LOG_ERROR, "tcp_packet/(too small)"); return 0; } - if(tcp->doff < 5) { - logmsg_dbg(ANDROID_LOG_ERROR,"tcp_packet/tcp header length set to less than 5: %x", tcp->doff); + if (tcp->doff < 5) { + logmsg_dbg(ANDROID_LOG_ERROR, "tcp_packet/tcp header length set to less than 5: %x", tcp->doff); return 0; } - if((size_t) tcp->doff*4 > len) { - logmsg_dbg(ANDROID_LOG_ERROR,"tcp_packet/tcp header length set too large: %x", tcp->doff); + if ((size_t)tcp->doff * 4 > len) { + logmsg_dbg(ANDROID_LOG_ERROR, "tcp_packet/tcp header length set too large: %x", tcp->doff); return 0; } - header_size = tcp->doff * 4; - payload = ((const uint8_t *) tcp) + header_size; + header_size = tcp->doff * 4; + payload = ((const uint8_t *)tcp) + header_size; payload_size = len - header_size; return tcp_translate(out, pos, tcp, header_size, old_sum, new_sum, payload, payload_size); @@ -407,9 +404,9 @@ int udp_translate(clat_packet out, clat_packet_index pos, const struct udphdr *u memcpy(udp_targ, udp, sizeof(struct udphdr)); - out[pos].iov_len = sizeof(struct udphdr); - out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *) payload; - out[CLAT_POS_PAYLOAD].iov_len = payload_size; + out[pos].iov_len = sizeof(struct udphdr); + out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *)payload; + out[CLAT_POS_PAYLOAD].iov_len = payload_size; if (udp_targ->check) { udp_targ->check = ip_checksum_adjust(udp->check, old_sum, new_sum); @@ -442,23 +439,23 @@ int udp_translate(clat_packet out, clat_packet_index pos, const struct udphdr *u * returns: the highest position in the output clat_packet that's filled in */ int tcp_translate(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp, - size_t header_size, uint32_t old_sum, uint32_t new_sum, - const uint8_t *payload, size_t payload_size) { + size_t header_size, uint32_t old_sum, uint32_t new_sum, const uint8_t *payload, + size_t payload_size) { struct tcphdr *tcp_targ = out[pos].iov_base; - out[pos].iov_len = header_size; + out[pos].iov_len = header_size; if (header_size > MAX_TCP_HDR) { // A TCP header cannot be more than MAX_TCP_HDR bytes long because it's a 4-bit field that // counts in 4-byte words. So this can never happen unless there is a bug in the caller. - logmsg(ANDROID_LOG_ERROR, "tcp_translate: header too long %d > %d, truncating", - header_size, MAX_TCP_HDR); + logmsg(ANDROID_LOG_ERROR, "tcp_translate: header too long %d > %d, truncating", header_size, + MAX_TCP_HDR); header_size = MAX_TCP_HDR; } memcpy(tcp_targ, tcp, header_size); - out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *) payload; - out[CLAT_POS_PAYLOAD].iov_len = payload_size; + out[CLAT_POS_PAYLOAD].iov_base = (uint8_t *)payload; + out[CLAT_POS_PAYLOAD].iov_len = payload_size; tcp_targ->check = ip_checksum_adjust(tcp->check, old_sum, new_sum); @@ -474,14 +471,13 @@ void send_rawv6(int fd, clat_packet out, int iov_len) { // destination address in the packet header only affects what appears on the wire, not where the // packet is sent to. static struct sockaddr_in6 sin6 = { AF_INET6, 0, 0, { { { 0, 0, 0, 0 } } }, 0 }; - static struct msghdr msg = { - .msg_name = &sin6, + static struct msghdr msg = { + .msg_name = &sin6, .msg_namelen = sizeof(sin6), }; - msg.msg_iov = out, - msg.msg_iovlen = iov_len, - sin6.sin6_addr = ((struct ip6_hdr *) out[CLAT_POS_IPHDR].iov_base)->ip6_dst; + msg.msg_iov = out, msg.msg_iovlen = iov_len, + sin6.sin6_addr = ((struct ip6_hdr *)out[CLAT_POS_IPHDR].iov_base)->ip6_dst; sendmsg(fd, &msg, 0); } @@ -506,14 +502,14 @@ void translate_packet(int fd, int to_ipv6, const uint8_t *packet, size_t packets // iovec of the packets we'll send. This gets passed down to the translation functions. clat_packet out = { - { &tun_targ, 0 }, // Tunnel header. - { iphdr, 0 }, // IP header. - { fraghdr, 0 }, // Fragment header. - { transporthdr, 0 }, // Transport layer header. - { icmp_iphdr, 0 }, // ICMP error inner IP header. - { icmp_fraghdr, 0 }, // ICMP error fragmentation header. - { icmp_transporthdr, 0 }, // ICMP error transport layer header. - { NULL, 0 }, // Payload. No buffer, it's a pointer to the original payload. + { &tun_targ, 0 }, // Tunnel header. + { iphdr, 0 }, // IP header. + { fraghdr, 0 }, // Fragment header. + { transporthdr, 0 }, // Transport layer header. + { icmp_iphdr, 0 }, // ICMP error inner IP header. + { icmp_fraghdr, 0 }, // ICMP error fragmentation header. + { icmp_transporthdr, 0 }, // ICMP error transport layer header. + { NULL, 0 }, // Payload. No buffer, it's a pointer to the original payload. }; if (to_ipv6) { diff --git a/translate.h b/translate.h index aa8b736..692affc 100644 --- a/translate.h +++ b/translate.h @@ -18,19 +18,19 @@ #ifndef __TRANSLATE_H__ #define __TRANSLATE_H__ +#include <linux/icmp.h> +#include <linux/if_tun.h> +#include <netinet/icmp6.h> #include <netinet/in.h> #include <netinet/ip.h> +#include <netinet/ip6.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 <linux/if_tun.h> +#include <netinet/udp.h> #include "clatd.h" -#define MAX_TCP_HDR (15 * 4) // Data offset field is 4 bits and counts in 32-bit words. +#define MAX_TCP_HDR (15 * 4) // Data offset field is 4 bits and counts in 32-bit words. // Calculates the checksum over all the packet components starting from pos. uint16_t packet_checksum(uint32_t checksum, clat_packet packet, clat_packet_index pos); @@ -75,16 +75,15 @@ int icmp6_to_icmp(clat_packet out, clat_packet_index pos, const struct icmp6_hdr int generic_packet(clat_packet out, clat_packet_index pos, const uint8_t *payload, size_t len); // Translate TCP and UDP packets. -int tcp_packet(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp, - uint32_t old_sum, uint32_t new_sum, size_t len); -int udp_packet(clat_packet out, clat_packet_index pos, const struct udphdr *udp, - uint32_t old_sum, uint32_t new_sum, size_t len); +int tcp_packet(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp, uint32_t old_sum, + uint32_t new_sum, size_t len); +int udp_packet(clat_packet out, clat_packet_index pos, const struct udphdr *udp, uint32_t old_sum, + uint32_t new_sum, size_t len); int tcp_translate(clat_packet out, clat_packet_index pos, const struct tcphdr *tcp, - size_t header_size, uint32_t old_sum, uint32_t new_sum, - const uint8_t *payload, size_t payload_size); + size_t header_size, uint32_t old_sum, uint32_t new_sum, const uint8_t *payload, + size_t payload_size); int udp_translate(clat_packet out, clat_packet_index pos, const struct udphdr *udp, - uint32_t old_sum, uint32_t new_sum, - const uint8_t *payload, size_t payload_size); + uint32_t old_sum, uint32_t new_sum, const uint8_t *payload, size_t payload_size); #endif /* __TRANSLATE_H__ */ @@ -15,14 +15,14 @@ * * tun.c - tun device functions */ -#include <fcntl.h> -#include <string.h> -#include <unistd.h> #include <arpa/inet.h> +#include <fcntl.h> #include <linux/if.h> #include <linux/if_tun.h> +#include <string.h> #include <sys/ioctl.h> #include <sys/uio.h> +#include <unistd.h> #include "clatd.h" @@ -33,7 +33,7 @@ int tun_open() { int fd; fd = open("/dev/tun", O_RDWR); - if(fd < 0) { + if (fd < 0) { fd = open("/dev/net/tun", O_RDWR); } @@ -51,12 +51,12 @@ int tun_alloc(char *dev, int fd) { memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TUN; - if( *dev ) { + if (*dev) { strncpy(ifr.ifr_name, dev, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = '\0'; + ifr.ifr_name[IFNAMSIZ - 1] = '\0'; } - if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){ + if ((err = ioctl(fd, TUNSETIFF, (void *)&ifr)) < 0) { close(fd); return err; } @@ -84,6 +84,4 @@ int set_nonblocking(int fd) { * iov_len - the number of entries in the clat_packet * returns: number of bytes read on success, -1 on failure */ -int send_tun(int fd, clat_packet out, int iov_len) { - return writev(fd, out, iov_len); -} +int send_tun(int fd, clat_packet out, int iov_len) { return writev(fd, out, iov_len); } |