1ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti/*
2ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * Copyright 2014 The Android Open Source Project
3ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti *
4ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * Licensed under the Apache License, Version 2.0 (the "License");
5ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * you may not use this file except in compliance with the License.
6ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * You may obtain a copy of the License at
7ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti *
8ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * http://www.apache.org/licenses/LICENSE-2.0
9ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti *
10ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * Unless required by applicable law or agreed to in writing, software
11ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * distributed under the License is distributed on an "AS IS" BASIS,
12ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * See the License for the specific language governing permissions and
14ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * limitations under the License.
15ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti *
16ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * tun.c - tun device functions
17ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti */
18ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti#include <fcntl.h>
19ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti#include <string.h>
20ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti#include <unistd.h>
21ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti#include <arpa/inet.h>
22ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti#include <linux/if.h>
23ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti#include <linux/if_tun.h>
24ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti#include <sys/ioctl.h>
256b2007aacd13344c9bc73d5d858bd903b432c228Lorenzo Colitti#include <sys/uio.h>
266b2007aacd13344c9bc73d5d858bd903b432c228Lorenzo Colitti
276b2007aacd13344c9bc73d5d858bd903b432c228Lorenzo Colitti#include "clatd.h"
28ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti
29ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti/* function: tun_open
30ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * tries to open the tunnel device
31ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti */
32ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colittiint tun_open() {
33ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  int fd;
34ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti
35ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  fd = open("/dev/tun", O_RDWR);
36ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  if(fd < 0) {
37ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti    fd = open("/dev/net/tun", O_RDWR);
38ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  }
39ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti
40ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  return fd;
41ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti}
42ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti
43ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti/* function: tun_alloc
44ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * creates a tun interface and names it
45ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti * dev - the name for the new tun device
46ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti */
47ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colittiint tun_alloc(char *dev, int fd) {
48ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  struct ifreq ifr;
49ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  int err;
50ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti
51ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  memset(&ifr, 0, sizeof(ifr));
52ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti
53ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  ifr.ifr_flags = IFF_TUN;
54ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  if( *dev ) {
55ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti    strncpy(ifr.ifr_name, dev, IFNAMSIZ);
56ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti    ifr.ifr_name[IFNAMSIZ-1] = '\0';
57ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  }
58ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti
59ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
60ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti    close(fd);
61ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti    return err;
62ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  }
63ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  strcpy(dev, ifr.ifr_name);
64ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti  return 0;
65ff6f7fe4bd983c623d490100fa17cdb4936b95a2Lorenzo Colitti}
666b2007aacd13344c9bc73d5d858bd903b432c228Lorenzo Colitti
67b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti/* function: set_nonblocking
68b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti * sets a filedescriptor to non-blocking mode
69b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti * fd - the filedescriptor
70b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti * returns: 0 on success, -1 on failure
71b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti */
72b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colittiint set_nonblocking(int fd) {
73b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti  int flags = fcntl(fd, F_GETFL);
74b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti  if (flags == -1) {
75b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti    return flags;
76b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti  }
77b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti  return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
78b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti}
79b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti
80b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti/* function: send_tun
81b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti * sends a clat_packet to a tun interface
82b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti * fd      - the tun filedescriptor
83b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti * out     - the packet to send
84b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti * iov_len - the number of entries in the clat_packet
85b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti * returns: number of bytes read on success, -1 on failure
86b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti */
87b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colittiint send_tun(int fd, clat_packet out, int iov_len) {
88b20719ebf403b16d36a231aeef96607f8c7aa252Lorenzo Colitti  return writev(fd, out, iov_len);
896b2007aacd13344c9bc73d5d858bd903b432c228Lorenzo Colitti}
90