Skip to content

Commit 6fffe31

Browse files
author
zhshch2002
committedMay 15, 2022
refactor: udp trace
1 parent 6792baf commit 6fffe31

18 files changed

+721
-696
lines changed
 

‎go.mod

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@ require (
1010
require (
1111
github.com/mattn/go-colorable v0.1.9 // indirect
1212
github.com/mattn/go-isatty v0.0.14 // indirect
13+
github.com/panjf2000/ants/v2 v2.5.0 // indirect
14+
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 // indirect
1315
)
1416

1517
require (
16-
github.com/davecgh/go-spew v1.1.0 // indirect
18+
github.com/davecgh/go-spew v1.1.1 // indirect
1719
github.com/fatih/color v1.13.0
1820
github.com/pmezard/go-difflib v1.0.0 // indirect
1921
github.com/rodaine/table v1.0.1
@@ -22,5 +24,5 @@ require (
2224
github.com/tidwall/match v1.1.1 // indirect
2325
github.com/tidwall/pretty v1.2.0 // indirect
2426
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
25-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
27+
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
2628
)

‎go.sum

+6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
22
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
34
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
45
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
56
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
@@ -11,6 +12,8 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9
1112
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
1213
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
1314
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
15+
github.com/panjf2000/ants/v2 v2.5.0 h1:1rWGWSnxCsQBga+nQbA4/iY6VMeNoOIAM0ZWh9u3q2Q=
16+
github.com/panjf2000/ants/v2 v2.5.0/go.mod h1:cU93usDlihJZ5CfRGNDYsiBYvoilLvBF5Qp/BT2GNRE=
1417
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1518
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1619
github.com/rodaine/table v1.0.1 h1:U/VwCnUxlVYxw8+NJiLIuCxA/xa6jL38MY3FYysVWWQ=
@@ -34,6 +37,8 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
3437
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
3538
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
3639
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
40+
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
41+
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
3742
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
3843
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
3944
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -48,3 +53,4 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+
4853
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
4954
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
5055
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
56+
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

‎ipgeo/ipgeo.go

+13
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,16 @@ type IPGeoData struct {
1111
}
1212

1313
type Source = func(ip string) (*IPGeoData, error)
14+
15+
func GetSource(s string) Source {
16+
switch s {
17+
case "LeoMoeAPI":
18+
return LeoIP
19+
case "IP.SB":
20+
return IPSB
21+
case "IPInsight":
22+
return IPInSight
23+
default:
24+
return nil
25+
}
26+
}

‎main.go

+47-57
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ package main
33
import (
44
"flag"
55
"fmt"
6+
"github.com/xgadget-lab/nexttrace/ipgeo"
7+
"github.com/xgadget-lab/nexttrace/printer"
8+
"github.com/xgadget-lab/nexttrace/trace"
9+
"github.com/xgadget-lab/nexttrace/util"
10+
"log"
611
"os"
712
"time"
8-
9-
"github.com/xgadget-lab/nexttrace/methods"
10-
"github.com/xgadget-lab/nexttrace/methods/tcp"
11-
"github.com/xgadget-lab/nexttrace/methods/udp"
12-
"github.com/xgadget-lab/nexttrace/util"
13-
"github.com/xgadget-lab/nexttrace/util/printer"
1413
)
1514

1615
var tcpSYNFlag = flag.Bool("T", false, "Use TCP SYN for tracerouting (default port is 80 in TCP, 53 in UDP)")
@@ -22,67 +21,58 @@ var dataOrigin = flag.String("d", "LeoMoeAPI", "Choose IP Geograph Data Provider
2221
var displayMode = flag.String("displayMode", "table", "Choose The Display Mode [table, classic]")
2322
var rdnsenable = flag.Bool("rdns", false, "Set whether rDNS will be display")
2423

24+
func flagApply() string {
25+
flag.Parse()
26+
ipArg := flag.Args()
27+
if flag.NArg() != 1 {
28+
fmt.Println("Args Error\nUsage : ./nexttrace [-T] [-rdns] [-displayMode <displayMode>] [-d <dataOrigin> ] [ -m <hops> ] [ -p <port> ] [ -q <probes> ] [ -r <parallelrequests> ] <hostname>")
29+
os.Exit(2)
30+
}
31+
return ipArg[0]
32+
}
33+
2534
func main() {
26-
printer.PrintCopyRight()
35+
if os.Getuid() != 0 {
36+
log.Fatalln("Traceroute requires root/sudo privileges.")
37+
}
38+
2739
domain := flagApply()
2840
ip := util.DomainLookUp(domain)
2941
printer.PrintTraceRouteNav(ip, domain, *dataOrigin)
3042

43+
var m trace.Method = ""
3144
if *tcpSYNFlag {
32-
tcpTraceroute := tcp.New(ip, methods.TracerouteConfig{
33-
MaxHops: uint16(*maxHops),
34-
NumMeasurements: uint16(*numMeasurements),
35-
ParallelRequests: uint16(*parallelRequests),
36-
Port: *port,
37-
Timeout: time.Second / 2,
38-
})
39-
res, err := tcpTraceroute.Start()
45+
m = trace.TCPTrace
46+
} else {
47+
m = trace.UDPTrace
48+
}
4049

41-
if err != nil {
42-
fmt.Println("请赋予 sudo (root) 权限运行本程序")
43-
} else {
44-
util.Printer(&util.PrinterConfig{
45-
IP: ip,
46-
DisplayMode: *displayMode,
47-
DataOrigin: *dataOrigin,
48-
Rdnsenable: *rdnsenable,
49-
Results: *res,
50-
})
51-
}
50+
if !*tcpSYNFlag && *port == 80 {
51+
*port = 53
52+
}
5253

53-
} else {
54-
if *port == 80 {
55-
*port = 53
56-
}
57-
udpTraceroute := udp.New(ip, true, methods.TracerouteConfig{
58-
MaxHops: uint16(*maxHops),
59-
NumMeasurements: uint16(*numMeasurements),
60-
ParallelRequests: uint16(*parallelRequests),
61-
Port: *port,
62-
Timeout: 2 * time.Second,
63-
})
64-
res, err := udpTraceroute.Start()
54+
var conf = trace.Config{
55+
DestIP: ip,
56+
DestPort: *port,
57+
MaxHops: *maxHops,
58+
NumMeasurements: *numMeasurements,
59+
ParallelRequests: *parallelRequests,
60+
RDns: *rdnsenable,
61+
IPGeoSource: ipgeo.GetSource(*dataOrigin),
62+
Timeout: 2 * time.Second,
6563

66-
if err != nil {
67-
fmt.Println("请赋予 sudo (root) 权限运行本程序")
68-
} else {
69-
util.Printer(&util.PrinterConfig{
70-
IP: ip,
71-
DisplayMode: *displayMode,
72-
DataOrigin: *dataOrigin,
73-
Rdnsenable: *rdnsenable,
74-
Results: *res,
75-
})
76-
}
64+
//Quic: false,
7765
}
78-
}
7966

80-
func flagApply() string {
81-
flag.Parse()
82-
ipArg := flag.Args()
83-
if flag.NArg() != 1 {
84-
fmt.Println("Args Error\nUsage : ./nexttrace [-T] [-rdns] [-displayMode <displayMode>] [-d <dataOrigin> ] [ -m <hops> ] [ -p <port> ] [ -q <probes> ] [ -r <parallelrequests> ] <hostname>")
85-
os.Exit(2)
67+
res, err := trace.Traceroute(m, conf)
68+
69+
if err != nil {
70+
log.Fatalln(err)
71+
}
72+
73+
if *displayMode == "table" {
74+
printer.TracerouteTablePrinter(res)
75+
} else {
76+
printer.TraceroutePrinter(res)
8677
}
87-
return ipArg[0]
8878
}

‎methods/methods.go

-33
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package methods
22

33
import (
4-
"encoding/binary"
5-
"errors"
64
"net"
75
"time"
86
)
@@ -24,37 +22,6 @@ type TracerouteConfig struct {
2422
Timeout time.Duration
2523
}
2624

27-
func GetIPHeaderLength(data []byte) (int, error) {
28-
if len(data) < 1 {
29-
return 0, errors.New("received invalid IP header")
30-
}
31-
return int((data[0] & 0x0F) * 4), nil
32-
}
33-
34-
func GetICMPResponsePayload(data []byte) ([]byte, error) {
35-
length, err := GetIPHeaderLength(data)
36-
if err != nil {
37-
return nil, err
38-
}
39-
40-
if len(data) < length {
41-
return nil, errors.New("length of packet too short")
42-
}
43-
44-
return data[length:], nil
45-
}
46-
47-
func GetUDPSrcPort(data []byte) uint16 {
48-
srcPortBytes := data[:2]
49-
srcPort := binary.BigEndian.Uint16(srcPortBytes)
50-
return srcPort
51-
}
52-
53-
func GetTCPSeq(data []byte) uint32 {
54-
seqBytes := data[4:8]
55-
return binary.BigEndian.Uint32(seqBytes)
56-
}
57-
5825
func ReduceFinalResult(preliminary map[uint16][]TracerouteHop, maxHops uint16, destIP net.IP) map[uint16][]TracerouteHop {
5926
// reduce the results to remove all hops after the first encounter to final destination
6027
finalResults := map[uint16][]TracerouteHop{}

‎methods/tcp/tcp.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,11 @@ func (tr *Traceroute) addToResult(ttl uint16, hop methods.TracerouteHop) {
133133
}
134134

135135
func (tr *Traceroute) handleICMPMessage(msg listener_channel.ReceivedMessage, data []byte) {
136-
header, err := methods.GetICMPResponsePayload(data)
136+
header, err := util.GetICMPResponsePayload(data)
137137
if err != nil {
138138
return
139139
}
140-
sequenceNumber := methods.GetTCPSeq(header)
140+
sequenceNumber := util.GetTCPSeq(header)
141141
val, ok := tr.results.inflightRequests.LoadAndDelete(sequenceNumber)
142142
if !ok {
143143
return

0 commit comments

Comments
 (0)
Please sign in to comment.