n2n/android/tuntap_android.c
2018-06-12 02:59:13 +08:00

108 lines
3.4 KiB
C

/*
* (C) 2007-09 - Luca Deri <deri@ntop.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>
*/
#include "../n2n.h"
#ifdef __ANDROID_NDK__
#include <tun2tap/tun2tap.h>
/* ********************************** */
/** @brief Open and configure the TAP device for packet read/write.
*
* This routine creates the interface via the tuntap driver then uses ifconfig
* to configure address/mask and MTU.
*
* @param device - [inout] a device info holder object
* @param dev - user-defined name for the new iface,
* if NULL system will assign a name
* @param device_ip - address of iface
* @param device_mask - netmask for device_ip
* @param mtu - MTU for device_ip
*
* @return - negative value on error
* - non-negative file-descriptor on success
*/
int tuntap_open(tuntap_dev *device,
char *dev, /* user-definable interface name, eg. edge0 */
const char *address_mode, /* static or dhcp */
char *device_ip,
char *device_mask,
const char * device_mac,
int mtu) {
int i, n_matched;
unsigned int mac[6];
n_matched = sscanf(device_mac, "%x:%x:%x:%x:%x:%x", mac, mac + 1, mac + 2, mac + 3, mac + 4, mac + 5);
if (n_matched != 6) {
return -1;
}
memset(device->mac_addr, 0, sizeof(device->mac_addr));
for (i = 0; i < 6; i++)
device->mac_addr[i] = mac[i];
device->ip_addr = inet_addr(device_ip);
device->device_mask = inet_addr(device_mask);
device->mtu = mtu;
strncpy(device->dev_name, dev, MIN(IFNAMSIZ, N2N_IFNAMSIZ));
return device->fd;
}
int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len) {
int rlen = read(tuntap->fd, buf + UIP_LLH_LEN, len - UIP_LLH_LEN);
if ((rlen <= 0) || (rlen > N2N_PKT_BUF_SIZE - UIP_LLH_LEN))
{
return rlen;
}
uip_buf = buf;
uip_len = rlen;
uip_arp_out();
if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_ARP))
{
traceEvent(TRACE_DEBUG, "ARP request packets are sent instead of packets");
}
return uip_len;
}
int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len) {
uip_buf = buf;
uip_len = len;
if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_IP)) {
return write(tuntap->fd, buf + UIP_LLH_LEN, len - UIP_LLH_LEN);
} else if (IPBUF->ethhdr.type == htons(UIP_ETHTYPE_ARP)) {
uip_arp_arpin();
if (uip_len > 0) {
uip_arp_len = uip_len;
memcpy(uip_arp_buf, uip_buf, uip_arp_len);
traceEvent(TRACE_DEBUG, "ARP reply packet prepare to send");
}
return uip_len;
}
errno = EINVAL;
return -1;
}
void tuntap_close(struct tuntap_dev *tuntap) {
close(tuntap->fd);
}
void tuntap_get_address(struct tuntap_dev *tuntap) {
}
#endif /* #ifdef __ANDROID_NDK__ */