-
-
Save glacjay/585620 to your computer and use it in GitHub Desktop.
package main | |
import ( | |
"exec" | |
"log" | |
"os" | |
"syscall" | |
"unsafe" | |
) | |
func main() { | |
file, err := os.Open("/dev/net/tun", os.O_RDWR, 0) | |
if err != nil { | |
log.Exitf("error os.Open(): %v\n", err) | |
} | |
ifr := make([]byte, 18) | |
copy(ifr, []byte("tun0")) | |
ifr[16] = 0x01 | |
ifr[17] = 0x10 | |
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(file.Fd()), | |
uintptr(0x400454ca), uintptr(unsafe.Pointer(&ifr[0]))) | |
if errno != 0 { | |
log.Exitf("error syscall.Ioctl(): %v\n", os.Errno(errno)) | |
} | |
cmd, err := exec.Run("/sbin/ifconfig", | |
[]string{"ifconfig", "tun0", "192.168.7.1", | |
"pointopoint", "192.168.7.2", "up"}, | |
nil, ".", 0, 1, 2) | |
if err != nil { | |
log.Exitf("error exec.Run(): %v\n", err) | |
} | |
cmd.Wait(0) | |
for { | |
buf := make([]byte, 2048) | |
read, err := file.Read(buf) | |
if err != nil { | |
log.Exitf("error os.Read(): %v\n", err) | |
} | |
for i := 0; i < 4; i++ { | |
buf[i+12], buf[i+16] = buf[i+16], buf[i+12] | |
} | |
buf[20] = 0 | |
buf[22] = 0 | |
buf[23] = 0 | |
var checksum uint16 | |
for i := 20; i < read; i += 2 { | |
checksum += uint16(buf[i])<<8 + uint16(buf[i+1]) | |
} | |
checksum = ^(checksum + 4) | |
buf[22] = byte(checksum >> 8) | |
buf[23] = byte(checksum & ((1 << 8) - 1)) | |
_, err = file.Write(buf) | |
if err != nil { | |
log.Exitf("error os.Write(): %v\n", err) | |
} | |
} | |
} |
are there any way to pass the request to TCPIP stack?
not sure what you mean
Normally TCPIP stack are handled by OS kernel. But you get layer 2 packet directly. If you want to handle this like generate HTTP request, you have to use userspace implemented tcp/ip stack such as gvisor/vpp etc or construct your own tcp/ip stack and handle it yourself.
Here is an example: https://github.com/WireGuard/wireguard-go/blob/master/tun/netstack/examples/http_server.go , it serves a http server under wireguard which is a layer3 VPN. In this case it handle layer3 packet directly to serve a http server.
In your case you get layer2 packet but convert it to layer3 is pretty easy, you need to fill/remove the layer2 header such as source MAC address and Destination MAC address so that you can convert a layer2 packet to layer3 packet.
Layer 3 to layer 4 you have to construct tcp/ip stack or use gvisor.
are there any way to pass the request to TCPIP stack?