Skip to content

Instantly share code, notes, and snippets.

@niedbalski
Last active December 8, 2021 13:16
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save niedbalski/08edc6a2d3c8a3197c99 to your computer and use it in GitHub Desktop.
Save niedbalski/08edc6a2d3c8a3197c99 to your computer and use it in GitHub Desktop.
A small traceroute written in go
package main
import (
//"bufio"
"fmt"
"golang.org/x/net/icmp"
"golang.org/x/net/internal/iana"
"golang.org/x/net/ipv4"
"log"
"net"
"os"
"time"
)
const (
DEFAULT_TTL = 32
DEFAULT_TIMEOUT = 3 * time.Second
)
func ParseReplies(routers chan string) {
c, err := icmp.ListenPacket("ip4:icmp", "0.0.0.0")
if err != nil {
panic(err)
}
for {
c.SetReadDeadline(time.Now().Add(DEFAULT_TIMEOUT))
rb := make([]byte, 1500)
readed, peer, _ := c.ReadFrom(rb)
if readed <= 0 {
routers <- "*"
continue
}
message, err := icmp.ParseMessage(iana.ProtocolICMP, rb[:readed])
if err != nil {
routers <- "*"
continue
}
switch message.Type {
case ipv4.ICMPTypeTimeExceeded:
routers <- peer.String()
default:
continue
}
}
}
func main() {
var router string
routers := make(chan string)
addr, err := net.ResolveUDPAddr("udp4", fmt.Sprintf("%s:%d", os.Args[1], 33434))
if err != nil {
log.Fatal(err)
}
go ParseReplies(routers)
for i := 1; i <= DEFAULT_TTL; i++ {
conn, err := net.DialUDP("udp4", nil, addr)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
start := time.Now()
pkt := ipv4.NewPacketConn(conn)
defer pkt.Close()
pkt.SetTTL(i)
buffer := make([]byte, 1024)
_, err = pkt.Write(buffer) // write bytes through connected socket
if err != nil {
continue
}
router = <-routers
fmt.Printf("TTL: %d - Router: %s - Roundtrip: %f\n", i, router, time.Since(start).Seconds())
}
}
@smallnest
Copy link

_, err = pkt.Write(buffer)
Here pkt has no Write method?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment