-
-
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?