Skip to content

Instantly share code, notes, and snippets.

@grahamking
Last active August 29, 2015 14:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save grahamking/999f07b4659545a197d7 to your computer and use it in GitHub Desktop.
Save grahamking/999f07b4659545a197d7 to your computer and use it in GitHub Desktop.
ICMP raw send
package main
import (
"log"
"net"
"syscall"
)
func main() {
var err error
fd, _ := syscall.Socket(syscall.AF_INET, syscall.SOCK_RAW, syscall.IPPROTO_RAW)
addr := syscall.SockaddrInet4{
Port: 0,
Addr: [4]byte{127, 0, 0, 1},
}
p := pkt()
err = syscall.Sendto(fd, p, 0, &addr)
if err != nil {
log.Fatal("Sendto:", err)
}
}
func pkt() []byte {
h := Header{
Version: 4,
Len: 20,
TotalLen: 20 + 10, // 20 bytes for IP, 10 for ICMP
TTL: 64,
Protocol: 1, // ICMP
Dst: net.IPv4(127, 0, 0, 1),
// ID, Src and Checksum will be set for us by the kernel
}
icmp := []byte{
8, // type: echo request
0, // code: not used by echo request
0, // checksum (16 bit), we fill in below
0,
0, // identifier (16 bit). zero allowed.
0,
0, // sequence number (16 bit). zero allowed.
0,
0xC0, // Optional data. ping puts time packet sent here
0xDE,
}
cs := csum(icmp)
icmp[2] = byte(cs)
icmp[3] = byte(cs >> 8)
out, err := h.Marshal()
if err != nil {
log.Fatal(err)
}
return append(out, icmp...)
}
func csum(b []byte) uint16 {
var s uint32
for i := 0; i < len(b); i += 2 {
s += uint32(b[i+1])<<8 | uint32(b[i])
}
// add back the carry
s = s>>16 + s&0xffff
s = s + s>>16
return uint16(^s)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment