how can I send the read packet from tun to the server? I checked the packets by Wireshark and all of them was DNS request and changed the default gateway of my system to the IP of my VM and all packets goes there. the tun works good and I can print everything about packets but the problem is I don't know how to forward them to the destination server. (i know socket programming)
the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <netdb.h>
#include <fcntl.h>
#include <signal.h>
#include <linux/if.h>
#include <linux/if_tun.h>
#include <linux/ip.h>
#include <arpa/inet.h>
#include <netinet/in.h>
struct sockaddr_in Packet, dest;
#define Tun_Device "tun0"
static int max(int a, int b){
return a > b ? a : b;
}
int read_tun(char *name, int type){
struct ifreq ifr;
int tun_fd;
tun_fd = open("/dev/net/tun", O_RDWR)
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_flags = type;
strncpy(ifr.ifr_name, name, IFNAMSIZ);
ioctl(tun_fd, TUNSETIFF, (void *)&ifr);
return tun_fd;
}
int main(){
int tun_fd, packet_length, tcpfd;
struct sockaddr_in cliaddr, servaddr;
char buffer[2048];
char destination[16];
int i = 0;
struct iphdr *iph = (struct iphdr*) buffer;
tun_fd = read_tun(Tun_Device, IFF_TUN | IFF_NO_PI);
while (1) {
fd_set readset;
FD_ZERO(&readset);
FD_SET(tun_fd, &readset);
FD_SET( , &readset);
int max_fd = max(tun_fd, udp_fd) + 1;
select(max_fd, &readset, NULL, NULL, NULL)
if (FD_ISSET( , &readset)) {
}
if (FD_ISSET( , &readset)) {
}
}
}
Your default gateway must activate IP forwarding and you need to set corresponding iptables rules.
# Turn on IPv4 forward
sudo sysctl net.ipv4.ip_forward=1
# Add MASQUERADE rule
iptables -t nat -I POSTROUTING -s x.x.x.x/y ! -o tun0 -j MASQUERADE
# Allow forwarding
iptables -t filter -I FORWARD -d x.x.x.x/y -j ACCEPT
iptables -t filter -I FORWARD -s x.x.x.x/y -j ACCEPT
iptables -t filter -I FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
x.x.x.x/y
with your TUN/TAP network subnet.tun0
with virtual network interface name you use.You still need to communicate with your internet router when you override any traffic to virtual network interface, because you need to send encapsulated packet to VPN server.
In order to do that, you should not delete your default route that is going via your physical router.
The rule is simple:
VPN_IFACE=tun0
VPN_PRIVATE_IP=10.8.8.2
VPN_GATEWAY_IP=10.8.8.1
VPN_BROADCAST_IP=10.8.8.25
VPN_PUBLIC_IP=123.123.123.123
REAL_DEFAULT_IP=192.168.1.1
# Raise up virtual network interface
sudo ip link set dev $VPN_IFACE up mtu 1480
sudo ip addr add dev $VPN_IFACE $VPN_PRIVATE_IP/24 broadcast $VPN_BROADCAST_IP
# Encapsulated packet must be routed via your real router.
sudo ip route add $VPN_PUBLIC_IP/32 via $REAL_DEFAULT_IP
# Override any traffic, except for encapsulated packet
# Make them routed via virtual network interface gateway
sudo ip route add 0.0.0.0/1 dev $VPN_IFACE via $VPN_GATEWAY_IP
sudo ip route add 128.0.0.0/1 dev $VPN_IFACE via $VPN_GATEWAY_IP
# Don't delete default route to your real physical router!