Home | History | Annotate | Download | only in android-clat
      1 /*
      2  * Copyright 2012 Daniel Drown
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  * http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  *
     16  * clatd.c - tun interface setup and main event loop
     17  */
     18 #include <poll.h>
     19 #include <signal.h>
     20 #include <time.h>
     21 #include <stdio.h>
     22 #include <sys/types.h>
     23 #include <sys/ioctl.h>
     24 #include <sys/prctl.h>
     25 #include <sys/stat.h>
     26 #include <string.h>
     27 #include <errno.h>
     28 #include <stdlib.h>
     29 #include <unistd.h>
     30 #include <arpa/inet.h>
     31 #include <fcntl.h>
     32 
     33 #include <sys/capability.h>
     34 #include <sys/uio.h>
     35 #include <linux/filter.h>
     36 #include <linux/if.h>
     37 #include <linux/if_tun.h>
     38 #include <linux/if_ether.h>
     39 #include <linux/if_packet.h>
     40 #include <net/if.h>
     41 
     42 #include <private/android_filesystem_config.h>
     43 
     44 #include "translate.h"
     45 #include "clatd.h"
     46 #include "config.h"
     47 #include "logging.h"
     48 #include "resolv_netid.h"
     49 #include "setif.h"
     50 #include "mtu.h"
     51 #include "getaddr.h"
     52 #include "dump.h"
     53 
     54 #define DEVICENAME4 "clat4"
     55 
     56 /* 40 bytes IPv6 header - 20 bytes IPv4 header + 8 bytes fragment header */
     57 #define MTU_DELTA 28
     58 
     59 volatile sig_atomic_t running = 1;
     60 
     61 /* function: stop_loop
     62  * signal handler: stop the event loop
     63  */
     64 void stop_loop() {
     65   running = 0;
     66 }
     67 
     68 /* function: tun_open
     69  * tries to open the tunnel device
     70  */
     71 int tun_open() {
     72   int fd;
     73 
     74   fd = open("/dev/tun", O_RDWR);
     75   if(fd < 0) {
     76     fd = open("/dev/net/tun", O_RDWR);
     77   }
     78 
     79   return fd;
     80 }
     81 
     82 /* function: tun_alloc
     83  * creates a tun interface and names it
     84  * dev - the name for the new tun device
     85  */
     86 int tun_alloc(char *dev, int fd) {
     87   struct ifreq ifr;
     88   int err;
     89 
     90   memset(&ifr, 0, sizeof(ifr));
     91 
     92   ifr.ifr_flags = IFF_TUN;
     93   if( *dev ) {
     94     strncpy(ifr.ifr_name, dev, IFNAMSIZ);
     95     ifr.ifr_name[IFNAMSIZ-1] = '\0';
     96   }
     97 
     98   if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
     99     close(fd);
    100     return err;
    101   }
    102   strcpy(dev, ifr.ifr_name);
    103   return 0;
    104 }
    105 
    106 /* function: configure_packet_socket
    107  * Binds the packet socket and attaches the receive filter to it.
    108  * sock - the socket to configure
    109  */
    110 int configure_packet_socket(int sock) {
    111   struct sockaddr_ll sll = {
    112     .sll_family   = AF_PACKET,
    113     .sll_protocol = htons(ETH_P_IPV6),
    114     .sll_ifindex  = if_nametoindex((char *) &Global_Clatd_Config.default_pdp_interface),
    115     .sll_pkttype  = PACKET_OTHERHOST,  // The 464xlat IPv6 address is not assigned to the kernel.
    116   };
    117   if (bind(sock, (struct sockaddr *) &sll, sizeof(sll))) {
    118     logmsg(ANDROID_LOG_FATAL, "binding packet socket: %s", strerror(errno));
    119     return 0;
    120   }
    121 
    122   uint32_t *ipv6 = Global_Clatd_Config.ipv6_local_subnet.s6_addr32;
    123   struct sock_filter filter_code[] = {
    124     // Load the first four bytes of the IPv6 destination address (starts 24 bytes in).
    125     // Compare it against the first four bytes of our IPv6 address, in host byte order (BPF loads
    126     // are always in host byte order). If it matches, continue with next instruction (JMP 0). If it
    127     // doesn't match, jump ahead to statement that returns 0 (ignore packet). Repeat for the other
    128     // three words of the IPv6 address, and if they all match, return PACKETLEN (accept packet).
    129     BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  24),
    130     BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[0]), 0, 7),
    131     BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  28),
    132     BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[1]), 0, 5),
    133     BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  32),
    134     BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[2]), 0, 3),
    135     BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  36),
    136     BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[3]), 0, 1),
    137     BPF_STMT(BPF_RET | BPF_K,              PACKETLEN),
    138     BPF_STMT(BPF_RET | BPF_K, 0)
    139   };
    140   struct sock_fprog filter = {
    141     sizeof(filter_code) / sizeof(filter_code[0]),
    142     filter_code
    143   };
    144 
    145   if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter))) {
    146     logmsg(ANDROID_LOG_FATAL, "attach packet filter failed: %s", strerror(errno));
    147     return 0;
    148   }
    149 
    150   return 1;
    151 }
    152 
    153 /* function: interface_poll
    154  * polls the uplink network interface for address changes
    155  * tunnel - tun device data
    156  */
    157 void interface_poll(const struct tun_data *tunnel) {
    158   union anyip *interface_ip;
    159 
    160   interface_ip = getinterface_ip(Global_Clatd_Config.default_pdp_interface, AF_INET6);
    161   if(!interface_ip) {
    162     logmsg(ANDROID_LOG_WARN,"unable to find an ipv6 ip on interface %s",
    163            Global_Clatd_Config.default_pdp_interface);
    164     return;
    165   }
    166 
    167   config_generate_local_ipv6_subnet(&interface_ip->ip6);
    168 
    169   if(!IN6_ARE_ADDR_EQUAL(&interface_ip->ip6, &Global_Clatd_Config.ipv6_local_subnet)) {
    170     char from_addr[INET6_ADDRSTRLEN], to_addr[INET6_ADDRSTRLEN];
    171     inet_ntop(AF_INET6, &Global_Clatd_Config.ipv6_local_subnet, from_addr, sizeof(from_addr));
    172     inet_ntop(AF_INET6, &interface_ip->ip6, to_addr, sizeof(to_addr));
    173     logmsg(ANDROID_LOG_WARN, "clat subnet changed from %s to %s", from_addr, to_addr);
    174 
    175     // Start translating packets to the new prefix.
    176     memcpy(&Global_Clatd_Config.ipv6_local_subnet, &interface_ip->ip6, sizeof(struct in6_addr));
    177 
    178     // Update our packet socket filter to reflect the new 464xlat IP address.
    179     if (!configure_packet_socket(tunnel->read_fd6)) {
    180         // Things aren't going to work. Bail out and hope we have better luck next time.
    181         // We don't log an error here because configure_packet_socket has already done so.
    182         exit(1);
    183     }
    184   }
    185 
    186   free(interface_ip);
    187 }
    188 
    189 /* function: configure_tun_ip
    190  * configures the ipv4 and ipv6 addresses on the tunnel interface
    191  * tunnel - tun device data
    192  */
    193 void configure_tun_ip(const struct tun_data *tunnel) {
    194   int status;
    195 
    196   // Configure the interface before bringing it up. As soon as we bring the interface up, the
    197   // framework will be notified and will assume the interface's configuration has been finalized.
    198   status = add_address(tunnel->device4, AF_INET, &Global_Clatd_Config.ipv4_local_subnet,
    199       32, &Global_Clatd_Config.ipv4_local_subnet);
    200   if(status < 0) {
    201     logmsg(ANDROID_LOG_FATAL,"configure_tun_ip/if_address(4) failed: %s",strerror(-status));
    202     exit(1);
    203   }
    204 
    205   if((status = if_up(tunnel->device4, Global_Clatd_Config.ipv4mtu)) < 0) {
    206     logmsg(ANDROID_LOG_FATAL,"configure_tun_ip/if_up(4) failed: %s",strerror(-status));
    207     exit(1);
    208   }
    209 }
    210 
    211 /* function: drop_root
    212  * drops root privs but keeps the needed capability
    213  */
    214 void drop_root() {
    215   gid_t groups[] = { AID_INET, AID_VPN };
    216   if(setgroups(sizeof(groups)/sizeof(groups[0]), groups) < 0) {
    217     logmsg(ANDROID_LOG_FATAL,"drop_root/setgroups failed: %s",strerror(errno));
    218     exit(1);
    219   }
    220 
    221   prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
    222 
    223   if(setgid(AID_CLAT) < 0) {
    224     logmsg(ANDROID_LOG_FATAL,"drop_root/setgid failed: %s",strerror(errno));
    225     exit(1);
    226   }
    227   if(setuid(AID_CLAT) < 0) {
    228     logmsg(ANDROID_LOG_FATAL,"drop_root/setuid failed: %s",strerror(errno));
    229     exit(1);
    230   }
    231 
    232   struct __user_cap_header_struct header;
    233   struct __user_cap_data_struct cap;
    234   memset(&header, 0, sizeof(header));
    235   memset(&cap, 0, sizeof(cap));
    236 
    237   header.version = _LINUX_CAPABILITY_VERSION;
    238   header.pid = 0; // 0 = change myself
    239   cap.effective = cap.permitted = (1 << CAP_NET_ADMIN);
    240 
    241   if(capset(&header, &cap) < 0) {
    242     logmsg(ANDROID_LOG_FATAL,"drop_root/capset failed: %s",strerror(errno));
    243     exit(1);
    244   }
    245 }
    246 
    247 /* function: open_sockets
    248  * opens a packet socket to receive IPv6 packets and a raw socket to send them
    249  * tunnel - tun device data
    250  * mark - the socket mark to use for the sending raw socket
    251  */
    252 void open_sockets(struct tun_data *tunnel, uint32_t mark) {
    253   int rawsock = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW);
    254   if (rawsock < 0) {
    255     logmsg(ANDROID_LOG_FATAL, "raw socket failed: %s", strerror(errno));
    256     exit(1);
    257   }
    258 
    259   int off = 0;
    260   if (setsockopt(rawsock, SOL_IPV6, IPV6_CHECKSUM, &off, sizeof(off)) < 0) {
    261     logmsg(ANDROID_LOG_WARN, "could not disable checksum on raw socket: %s", strerror(errno));
    262   }
    263   if (mark != MARK_UNSET && setsockopt(rawsock, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
    264     logmsg(ANDROID_LOG_ERROR, "could not set mark on raw socket: %s", strerror(errno));
    265   }
    266 
    267   tunnel->write_fd6 = rawsock;
    268 
    269   int packetsock = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6));
    270   if (packetsock < 0) {
    271     logmsg(ANDROID_LOG_FATAL, "packet socket failed: %s", strerror(errno));
    272     exit(1);
    273   }
    274 
    275   tunnel->read_fd6 = packetsock;
    276 }
    277 
    278 /* function: configure_interface
    279  * reads the configuration and applies it to the interface
    280  * uplink_interface - network interface to use to reach the ipv6 internet
    281  * plat_prefix      - PLAT prefix to use
    282  * tunnel           - tun device data
    283  * net_id           - NetID to use, NETID_UNSET indicates use of default network
    284  */
    285 void configure_interface(const char *uplink_interface, const char *plat_prefix, struct tun_data *tunnel, unsigned net_id) {
    286   int error;
    287 
    288   if(!read_config("/system/etc/clatd.conf", uplink_interface, plat_prefix, net_id)) {
    289     logmsg(ANDROID_LOG_FATAL,"read_config failed");
    290     exit(1);
    291   }
    292 
    293   if(Global_Clatd_Config.mtu > MAXMTU) {
    294     logmsg(ANDROID_LOG_WARN,"Max MTU is %d, requested %d", MAXMTU, Global_Clatd_Config.mtu);
    295     Global_Clatd_Config.mtu = MAXMTU;
    296   }
    297   if(Global_Clatd_Config.mtu <= 0) {
    298     Global_Clatd_Config.mtu = getifmtu(Global_Clatd_Config.default_pdp_interface);
    299     logmsg(ANDROID_LOG_WARN,"ifmtu=%d",Global_Clatd_Config.mtu);
    300   }
    301   if(Global_Clatd_Config.mtu < 1280) {
    302     logmsg(ANDROID_LOG_WARN,"mtu too small = %d", Global_Clatd_Config.mtu);
    303     Global_Clatd_Config.mtu = 1280;
    304   }
    305 
    306   if(Global_Clatd_Config.ipv4mtu <= 0 ||
    307      Global_Clatd_Config.ipv4mtu > Global_Clatd_Config.mtu - MTU_DELTA) {
    308     Global_Clatd_Config.ipv4mtu = Global_Clatd_Config.mtu - MTU_DELTA;
    309     logmsg(ANDROID_LOG_WARN,"ipv4mtu now set to = %d",Global_Clatd_Config.ipv4mtu);
    310   }
    311 
    312   error = tun_alloc(tunnel->device4, tunnel->fd4);
    313   if(error < 0) {
    314     logmsg(ANDROID_LOG_FATAL,"tun_alloc/4 failed: %s",strerror(errno));
    315     exit(1);
    316   }
    317 
    318   configure_tun_ip(tunnel);
    319 }
    320 
    321 /* function: read_packet
    322  * reads a packet from the tunnel fd and passes it down the stack
    323  * active_fd - tun file descriptor marked ready for reading
    324  * tunnel    - tun device data
    325  */
    326 void read_packet(int active_fd, const struct tun_data *tunnel) {
    327   ssize_t readlen;
    328   uint8_t buf[PACKETLEN], *packet;
    329   int fd;
    330 
    331   readlen = read(active_fd, buf, PACKETLEN);
    332 
    333   if(readlen < 0) {
    334     logmsg(ANDROID_LOG_WARN,"read_packet/read error: %s", strerror(errno));
    335     return;
    336   } else if(readlen == 0) {
    337     logmsg(ANDROID_LOG_WARN,"read_packet/tun interface removed");
    338     running = 0;
    339     return;
    340   }
    341 
    342   if (active_fd == tunnel->fd4) {
    343     ssize_t header_size = sizeof(struct tun_pi);
    344 
    345     if (readlen < header_size) {
    346       logmsg(ANDROID_LOG_WARN,"read_packet/short read: got %ld bytes", readlen);
    347       return;
    348     }
    349 
    350     struct tun_pi *tun_header = (struct tun_pi *) buf;
    351     uint16_t proto = ntohs(tun_header->proto);
    352     if (proto != ETH_P_IP) {
    353       logmsg(ANDROID_LOG_WARN, "%s: unknown packet type = 0x%x", __func__, proto);
    354       return;
    355     }
    356 
    357     if(tun_header->flags != 0) {
    358       logmsg(ANDROID_LOG_WARN, "%s: unexpected flags = %d", __func__, tun_header->flags);
    359     }
    360 
    361     fd = tunnel->write_fd6;
    362     packet = buf + header_size;
    363     readlen -= header_size;
    364   } else {
    365     fd = tunnel->fd4;
    366     packet = buf;
    367   }
    368 
    369   translate_packet(fd, (fd == tunnel->write_fd6), packet, readlen);
    370 }
    371 
    372 /* function: event_loop
    373  * reads packets from the tun network interface and passes them down the stack
    374  * tunnel - tun device data
    375  */
    376 void event_loop(const struct tun_data *tunnel) {
    377   time_t last_interface_poll;
    378   struct pollfd wait_fd[] = {
    379     { tunnel->read_fd6, POLLIN, 0 },
    380     { tunnel->fd4, POLLIN, 0 },
    381   };
    382 
    383   // start the poll timer
    384   last_interface_poll = time(NULL);
    385 
    386   while(running) {
    387     if(poll(wait_fd, 2, NO_TRAFFIC_INTERFACE_POLL_FREQUENCY*1000) == -1) {
    388       if(errno != EINTR) {
    389         logmsg(ANDROID_LOG_WARN,"event_loop/poll returned an error: %s",strerror(errno));
    390       }
    391     } else {
    392       size_t i;
    393       for(i = 0; i < ARRAY_SIZE(wait_fd); i++) {
    394         // Call read_packet if the socket has data to be read, but also if an
    395         // error is waiting. If we don't call read() after getting POLLERR, a
    396         // subsequent poll() will return immediately with POLLERR again,
    397         // causing this code to spin in a loop. Calling read() will clear the
    398         // socket error flag instead.
    399         if(wait_fd[i].revents != 0) {
    400           read_packet(wait_fd[i].fd,tunnel);
    401         }
    402       }
    403     }
    404 
    405     time_t now = time(NULL);
    406     if(last_interface_poll < (now - INTERFACE_POLL_FREQUENCY)) {
    407       interface_poll(tunnel);
    408       last_interface_poll = now;
    409     }
    410   }
    411 }
    412 
    413 /* function: print_help
    414  * in case the user is running this on the command line
    415  */
    416 void print_help() {
    417   printf("android-clat arguments:\n");
    418   printf("-i [uplink interface]\n");
    419   printf("-p [plat prefix]\n");
    420   printf("-n [NetId]\n");
    421   printf("-m [socket mark]\n");
    422 }
    423 
    424 /* function: parse_unsigned
    425  * parses a string as a decimal/hex/octal unsigned integer
    426  * str - the string to parse
    427  * out - the unsigned integer to write to, gets clobbered on failure
    428  */
    429 int parse_unsigned(const char *str, unsigned *out) {
    430     char *end_ptr;
    431     *out = strtoul(str, &end_ptr, 0);
    432     return *str && !*end_ptr;
    433 }
    434 
    435 /* function: main
    436  * allocate and setup the tun device, then run the event loop
    437  */
    438 int main(int argc, char **argv) {
    439   struct tun_data tunnel;
    440   int opt;
    441   char *uplink_interface = NULL, *plat_prefix = NULL, *net_id_str = NULL, *mark_str = NULL;
    442   unsigned net_id = NETID_UNSET;
    443   uint32_t mark = MARK_UNSET;
    444 
    445   strcpy(tunnel.device4, DEVICENAME4);
    446 
    447   while((opt = getopt(argc, argv, "i:p:n:m:h")) != -1) {
    448     switch(opt) {
    449       case 'i':
    450         uplink_interface = optarg;
    451         break;
    452       case 'p':
    453         plat_prefix = optarg;
    454         break;
    455       case 'n':
    456         net_id_str = optarg;
    457         break;
    458       case 'm':
    459         mark_str = optarg;
    460         break;
    461       case 'h':
    462         print_help();
    463         exit(0);
    464       default:
    465         logmsg(ANDROID_LOG_FATAL, "Unknown option -%c. Exiting.", (char) optopt);
    466         exit(1);
    467     }
    468   }
    469 
    470   if(uplink_interface == NULL) {
    471     logmsg(ANDROID_LOG_FATAL, "clatd called without an interface");
    472     exit(1);
    473   }
    474 
    475   if (net_id_str != NULL && !parse_unsigned(net_id_str, &net_id)) {
    476     logmsg(ANDROID_LOG_FATAL, "invalid NetID %s", net_id_str);
    477     exit(1);
    478   }
    479 
    480   if (mark_str != NULL && !parse_unsigned(mark_str, &mark)) {
    481     logmsg(ANDROID_LOG_FATAL, "invalid mark %s", mark_str);
    482     exit(1);
    483   }
    484 
    485   logmsg(ANDROID_LOG_INFO, "Starting clat version %s on %s netid=%s mark=%s",
    486          CLATD_VERSION, uplink_interface,
    487          net_id_str ? net_id_str : "(none)",
    488          mark_str ? mark_str : "(none)");
    489 
    490   // open our raw sockets before dropping privs
    491   open_sockets(&tunnel, mark);
    492 
    493   // run under a regular user
    494   drop_root();
    495 
    496   // we can create tun devices as non-root because we're in the VPN group.
    497   tunnel.fd4 = tun_open();
    498   if(tunnel.fd4 < 0) {
    499     logmsg(ANDROID_LOG_FATAL, "tun_open4 failed: %s", strerror(errno));
    500     exit(1);
    501   }
    502 
    503   // When run from netd, the environment variable ANDROID_DNS_MODE is set to
    504   // "local", but that only works for the netd process itself.
    505   unsetenv("ANDROID_DNS_MODE");
    506 
    507   configure_interface(uplink_interface, plat_prefix, &tunnel, net_id);
    508 
    509   if (!configure_packet_socket(tunnel.read_fd6)) {
    510     // We've already logged an error.
    511     exit(1);
    512   }
    513 
    514   // Loop until someone sends us a signal or brings down the tun interface.
    515   if(signal(SIGTERM, stop_loop) == SIG_ERR) {
    516     logmsg(ANDROID_LOG_FATAL, "sigterm handler failed: %s", strerror(errno));
    517     exit(1);
    518   }
    519   event_loop(&tunnel);
    520 
    521   logmsg(ANDROID_LOG_INFO,"Shutting down clat on %s", uplink_interface);
    522 
    523   return 0;
    524 }
    525