I am trying to parse a ICMP packet starting with the IP header.
func main() {
fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_ICMP)
if err != nil {
fmt.Println(err)
return
}
for {
buf := make([]byte, 1024)
numRead, err := syscall.Read(fd, buf)
if err != nil {
fmt.Println(err)
}
fmt.Println(hex.EncodeToString(buf[:numRead]))
}
}
This is my starting Go code.
I was expecting to reply packets from the Wireshark and my application to be the same but results are like this:
Note: Bytes is starting from IP Header I did not give the Link Layer bytes.
Go: 45004000000000003801c12cd8ef2678c0a8016d00007e72324f0000668e33570008ca4d08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
Wireshark: 45000054000000003801c12cd8ef2678c0a8016d00007e72324f0000668e33570008ca4d08090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f3031323334353637
If we look at the first 20 bytes of the IP Header the only difference is the datagram length. Starting from the 3. byte to the 4. byte.
Go: 4000
Wireshark: 0054
I could not find that why they are different since I am listenning on the same datagram with the same sequence number. Thanks for your time.
It turns out macOS is changing the raw socket header when it arrives. Wireshark can show the true result since it was working on a kernel level. When I run a fedora docker container and run the script it gives the same result as in the Wireshark.