Search code examples
socketsgonetworkingraw-sockets

Read from a raw socket connected to a network interface using golang


I'm trying to read the link-layer packets received by my wifi-card using golang. The program I wrote compiles successfully and runs without any errors, but it seems to be stuck trying to read from the socket (syscall.Recvfrom(fd, data, 0 - At this point to be precise). What am i doing wrong?

PS: wlx34e894f77905 is the name of my wifi device.

My function which tries to read the packets:

func readFromSocket() {
    fd, error := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, syscall.ETH_P_ALL)
    if error != nil {
        syscall.Close(fd)
        panic(error)
    }
    err := syscall.BindToDevice(fd, "wlx34e894f77905")
    if err != nil {
        syscall.Close(fd)
        panic(err)
    }
    data := make([]byte, 1024)
    for {
        syscall.Recvfrom(fd, data, 0)
        fmt.Println(data)
    }
}

netstat -r output:

default         _gateway        0.0.0.0         UG        0 0          0 wlx34e894f77905
link-local      0.0.0.0         255.255.0.0     U         0 0          0 wlx34e894f77905
172.17.0.0      0.0.0.0         255.255.0.0     U         0 0          0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U         0 0          0 br-3d5c8c113e89
192.168.0.0     0.0.0.0         255.255.255.0   U         0 0          0 wlx34e894f77905

Solution

  • like c/c++ code:

    sock_raw=socket(AF_PACKET,SOCK_RAW,htons(ETH_P_ALL));
    

    so, golang is:

    syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, htons(syscall.ETH_P_ALL))
    

    htons(syscall.ETH_P_ALL) => 0x0300 (little endian)