IPv4 ICMP
Simple ICMP (Ping) with Golang
Tujuan: nge-ping 100 ribu IP aktif.
Get Umar Rudi’s stories in your inbox
Join Medium for free to get updates from this writer.
Strategi: respon server tidak perlu dibaca dari layer aplikasi. Cukup dari layer network. (Pakai sudo ngrep “” “icmp” di terminal lain). Supaya kode aplikasinya bisa pendek. Ketika pendek, untuk scaling ke 100k jadi mudah.
package main
import (
"fmt"
"net"
"os"
)
func main() {
destAddr, _ := net.ResolveIPAddr("ip", os.Args[1])
conn, _ := net.DialIP("ip4:icmp", nil, destAddr)
defer conn.Close()
message := "Hello"
data := []byte(message)
icmpPacket := make([]byte, 8+len(data)) // icmpPacket langsung diisi nol (byte) semua sepanjang 8
icmpPacket[0] = byte(8)
copy(icmpPacket[8:], data)
// checksum := calculateChecksum(icmpPacket)
icmpPacket[2] = 212 // byte(checksum >> 8)
icmpPacket[3] = 45 // byte(checksum & 0xff)
conn.Write(icmpPacket)
}Angka 212 dan 45 didapat dari fungsi calculateChecksum. Sesuai panjang message.
Impelementasi fungsi calculateChecksum
func calculateChecksum(data []byte) uint16 {
sum := 0
for i := 0; i < len(data)-1; i += 2 {
sum += int(data[i])<<8 | int(data[i+1])
}
if len(data)%2 != 0 {
sum += int(data[len(data)-1]) << 8
}
sum = (sum >> 16) + (sum & 0xffff)
sum += sum >> 16
return uint16(^sum)
}Output:
➜ dev sudo ngrep "" "icmp"
interface: wlp3s0 (192.168.177.0/255.255.255.0)
filter: ( icmp ) and ((ip || ip6) || (vlan && (ip || ip6)))
#
I 192.168.177.38 -> 142.251.12.102 8:0 #37
....Hello
#
I 142.251.12.102 -> 192.168.177.38 0:0 #38
....Hello







