Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Send raw IP packet with tun device

I'm trying to programmatically construct and send IP packet through TUN device.

I've setup the TUN device and proper routes:

# ip tuntap add mode tun tun0
# ip link set tun0 up
# ip addr add 10.0.0.2/24 dev tun0

which results in:

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use 
Iface
0.0.0.0         192.168.0.1     0.0.0.0         UG    600    0        0 wlp3s0
10.0.0.0        0.0.0.0         255.255.255.0   U     0      0        0 tun0
192.168.0.0     0.0.0.0         255.255.255.0   U     600    0        0 wlp3s0

$ ifconfig tun0
tun0: flags=4241<UP,POINTOPOINT,NOARP,MULTICAST>  mtu 1500
    inet 10.0.0.2  netmask 255.255.255.0  destination 10.0.0.2
    inet6 fe80::f834:5267:3a1:5d1d  prefixlen 64  scopeid 0x20<link>
    unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)

IP forwarding is ON: # echo 1 > /proc/sys/net/ipv4/ip_forward

I've setup NAT for tun0 packets:

# iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o wlp3s0 -j MASQUERADE
# iptables -t nat -L -v
Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target     prot opt in     out     source               destination                   
0     0 MASQUERADE  all  --  any    wlp3s0  10.0.0.0/24          anywhere

Then I have python script to produce ICMP packets:

import os
from fcntl import ioctl
import struct
import time
import random

# pip install pypacker==4.0
from pypacker.layer3.ip import IP
from pypacker.layer3.icmp import ICMP

TUNSETIFF = 0x400454ca
IFF_TUN   = 0x0001
IFF_NO_PI = 0x1000

ftun = os.open("/dev/net/tun", os.O_RDWR)
ioctl(ftun, TUNSETIFF, struct.pack("16sH", b"tun0", IFF_TUN | IFF_NO_PI))

req_nr = 1
req_id = random.randint(1, 65000)
while True:
    icmp_req = IP(src_s="10.0.0.2", dst_s="8.8.8.8", p=1) +\
        ICMP(type=8) +\
        ICMP.Echo(id=req_id, seq=req_nr, body_bytes=b"povilas-test")
    os.write(ftun, icmp_req.bin())
    time.sleep(1)
    req_nr += 1

I can see packets originating from tun0 interface:

# tshark -i tun0
1 0.000000000     10.0.0.2 → 8.8.8.8      ICMP 48 Echo (ping) request  id=0xb673, seq=1/256, ttl=64
2 1.001695939     10.0.0.2 → 8.8.8.8      ICMP 48 Echo (ping) request  id=0xb673, seq=2/512, ttl=64
3 2.003375319     10.0.0.2 → 8.8.8.8      ICMP 48 Echo (ping) request  id=0xb673, seq=3/768, ttl=6

But wlp3s0 interface is silent, thus it seems that packets don't get NAT'ed and routed to wlp3s0 interface, which is my WLAN card.

Any ideas what I am missing?

like image 475
PovilasB Avatar asked Oct 20 '25 06:10

PovilasB


1 Answers

I'm running Debian 9. And turns out that packet forwarding was disabled - default policy for FORWARD chain is DROP:

# iptables -L -v
Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

So I changed the policy:

# iptables -P FORWARD ACCEPT
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Also, I had to change the IP packet source address to something other than 10.0.0.2 which is the preferred source address for tun0 interface:

$ ip route
10.0.0.0/24 dev tun0 proto kernel scope link src 10.0.0.2

So I changed the packet source address to 10.0.0.4:

icmp_req = IP(src_s="10.0.0.4", dst_s="8.8.8.8", p=1) +\
    ICMP(type=8) +\
    ICMP.Echo(id=req_id, seq=req_nr, body_bytes=b"povilas-test")

Then kernel started forwarding packets coming from tun0 interface to the gateway interface:

# tshark -i wlp3s0

5 0.008428567 192.168.0.103 → 8.8.8.8      ICMP 62 Echo (ping) request  id=0xb5c7, seq=9/2304, ttl=63
6 0.041114028      8.8.8.8 → 192.168.0.103 ICMP 62 Echo (ping) reply    id=0xb5c7, seq=9/2304, ttl=48 (request in 5)

Also ping responses were sent back to tun0:

# tshark -i tun0

1 0.000000000     10.0.0.4 → 8.8.8.8      ICMP 48 Echo (ping) request  id=0xb5c7, seq=113/28928, ttl=64
2 0.035470191      8.8.8.8 → 10.0.0.4     ICMP 48 Echo (ping) reply    id=0xb5c7, seq=113/28928, ttl=47 (request in 1)
like image 193
PovilasB Avatar answered Oct 21 '25 19:10

PovilasB