This commit is contained in:
Eliezer Croitoru 2026-09-09 16:58:08 +03:00
parent 2fe99008cb
commit ae5e8975c3
3 changed files with 23 additions and 9 deletions

Binary file not shown.

Binary file not shown.

View File

@ -233,6 +233,7 @@ type Tracer struct {
// lifecycle
stopCh chan struct{}
started time.Time
debug bool
}
func NewTracer(
@ -244,6 +245,7 @@ func NewTracer(
maxRounds int,
maxDur time.Duration,
noDNS bool,
debug bool,
) (*Tracer, error) {
ips, err := net.LookupHost(target)
if err != nil {
@ -287,6 +289,7 @@ func NewTracer(
maxActive: maxHops,
stopCh: make(chan struct{}),
started: time.Now(),
debug: debug,
}, nil
}
@ -523,8 +526,9 @@ func (t *Tracer) receiveLoop() {
continue
}
}
fmt.Fprintf(os.Stderr, "[debug] icmp recv %d bytes from %s\n", n, peer)
if t.debug {
fmt.Fprintf(os.Stderr, "[debug] icmp recv %d bytes from %s\n", n, peer)
}
from := peerString(peer)
now := time.Now()
@ -553,7 +557,7 @@ func (t *Tracer) receiveLoop() {
continue
}
if t.proto == "udp" {
dstPort, ok := extractOriginalUDPPort(te.Data)
dstPort, ok := t.extractOriginalUDPPort(te.Data)
if !ok {
continue
}
@ -580,7 +584,7 @@ func (t *Tracer) receiveLoop() {
continue
}
if t.proto == "udp" {
dstPort, ok := extractOriginalUDPPort(du.Data)
dstPort, ok := t.extractOriginalUDPPort(du.Data)
if !ok {
continue
}
@ -626,22 +630,30 @@ func extractOriginalICMP(data []byte) (seq, id int, ok bool) {
// extractOriginalUDPPort reads the original UDP destination port from the
// embedded original IP+UDP header in a Time Exceeded or Dest Unreachable reply.
func extractOriginalUDPPort(data []byte) (dstPort int, ok bool) {
func (t *Tracer) extractOriginalUDPPort(data []byte) (dstPort int, ok bool) {
if len(data) < 28 {
fmt.Fprintf(os.Stderr, "[debug] extractUDP: too short (%d bytes)\n", len(data))
if t.debug {
fmt.Fprintf(os.Stderr, "[debug] extractUDP: too short (%d bytes)\n", len(data))
}
return 0, false
}
ihl := int(data[0]&0x0f) * 4
if ihl < 20 || len(data) < ihl+8 {
fmt.Fprintf(os.Stderr, "[debug] extractUDP: bad IHL (%d)\n", ihl)
if t.debug {
fmt.Fprintf(os.Stderr, "[debug] extractUDP: bad IHL (%d)\n", ihl)
}
return 0, false
}
if data[9] != 17 {
fmt.Fprintf(os.Stderr, "[debug] extractUDP: proto=%d (not UDP)\n", data[9])
if t.debug {
fmt.Fprintf(os.Stderr, "[debug] extractUDP: proto=%d (not UDP)\n", data[9])
}
return 0, false
}
dstPort = int(binary.BigEndian.Uint16(data[ihl+2 : ihl+4]))
fmt.Fprintf(os.Stderr, "[debug] extractUDP: dstPort=%d\n", dstPort)
if t.debug {
fmt.Fprintf(os.Stderr, "[debug] extractUDP: dstPort=%d\n", dstPort)
}
return dstPort, true
}
@ -921,6 +933,7 @@ func main() {
noDNS := flag.Bool("n", false, "disable reverse DNS (show numeric IPs only)")
count := flag.Int("count", 0, "stop after N complete probe rounds (0 = run forever)")
dur := flag.Duration("duration", 0, "stop after this duration, e.g. 30s, 5m (0 = run forever)")
debug := flag.Bool("debug", false, "enable debug output")
flag.Usage = func() {
fmt.Fprintf(os.Stderr, `Usage: livetrace [options] <target>
@ -968,6 +981,7 @@ if p == "winapi" && runtime.GOOS != "windows" {
*count,
*dur,
*noDNS,
*debug,
)
if err != nil {
fmt.Fprintln(os.Stderr, "Error:", err)