增加对多MPLS情景的支持,支持通过ENV或参数禁用MPLS功能

要提交的变更:
	修改:     cmd/cmd.go
	修改:     printer/basic.go
	修改:     printer/printer.go
	修改:     printer/realtime_printer.go
	修改:     trace/icmp_ipv4.go
	修改:     trace/icmp_ipv6.go
	修改:     trace/trace.go
	修改:     util/util.go
This commit is contained in:
tsosunchia
2023-10-06 06:02:09 +08:00
parent 2113264336
commit b733ef2d82
8 changed files with 128 additions and 48 deletions

View File

@@ -55,6 +55,7 @@ func Excute() {
classicPrint := parser.Flag("c", "classic", &argparse.Options{Help: "Classic Output trace results like BestTrace"})
beginHop := parser.Int("f", "first", &argparse.Options{Default: 1, Help: "Start from the first_ttl hop (instead from 1)"})
disableMaptrace := parser.Flag("M", "map", &argparse.Options{Help: "Disable Print Trace Map"})
disableMPLS := parser.Flag("e", "disable-mpls", &argparse.Options{Help: "Disable MPLS"})
ver := parser.Flag("v", "version", &argparse.Options{Help: "Print version info and exit"})
srcAddr := parser.String("s", "source", &argparse.Options{Help: "Use source src_addr for outgoing packets"})
srcDev := parser.String("D", "dev", &argparse.Options{Help: "Use the following Network Devices as the source address in outgoing packets"})
@@ -286,6 +287,10 @@ func Excute() {
}
}
if *disableMPLS {
util.DisableMPLS = "1"
}
res, err := trace.Traceroute(m, conf)
if err != nil {

View File

@@ -109,7 +109,4 @@ func applyLangSetting(h *trace.Hop) {
}
}
if len(h.MPLS) > 1 {
h.Hostname += " [MPLS: " + h.MPLS + "]"
}
}

View File

@@ -47,9 +47,8 @@ func HopPrinter(h trace.Hop, info HopInfo) {
if h.Geo != nil {
txt += " " + formatIpGeoData(h.Address.String(), h.Geo)
}
if len(h.MPLS) > 1 {
txt += " [MPLS: " + h.MPLS + "]"
for _, v := range h.MPLS {
txt += " " + v
}
switch info {
case IXP:

View File

@@ -166,6 +166,11 @@ func RealtimePrinter(res *trace.Result, ttl int) {
)
}
}
for _, v := range res.Hops[ttl][i].MPLS {
fmt.Fprintf(color.Output, "%s",
color.New(color.FgHiBlack, color.Bold).Sprintf("\n %s", v),
)
}
fmt.Println()
blockDisplay = true
}

View File

@@ -30,6 +30,8 @@ type ICMPTracer struct {
fetchLock sync.Mutex
}
var psize = 52
func (t *ICMPTracer) PrintFunc() {
defer t.wg.Done()
var ttl = t.Config.BeginHop - 1
@@ -118,6 +120,7 @@ func (t *ICMPTracer) Execute() (*Result, error) {
func (t *ICMPTracer) listenICMP() {
lc := NewPacketListener(t.icmpListen, t.ctx)
psize = t.Config.PktSize
go lc.Start()
for {
select {
@@ -186,45 +189,6 @@ func (t *ICMPTracer) handleICMPMessage(msg ReceivedMessage, icmpType int8, data
}
}
func extractMPLS(msg ReceivedMessage, data []byte) string {
extensionOffset := 20 + 8 + 52
if len(data) <= extensionOffset {
return ""
}
extensionBody := data[extensionOffset:]
if len(extensionBody) < 8 || len(extensionBody)%8 != 0 {
return ""
}
tmp := fmt.Sprintf("%x", msg.Msg[:*msg.N])
if len(tmp) < 8 {
return ""
}
label, err := strconv.ParseInt(tmp[len(tmp)-8:len(tmp)-3], 16, 32)
if err != nil {
return ""
}
strSlice := []byte(tmp[len(tmp)-3 : len(tmp)-2])
charValue := int(strSlice[0] - '0')
binaryStr := fmt.Sprintf("%04b", charValue)
tc, err := strconv.ParseInt(binaryStr[:3], 2, 32)
if err != nil {
return ""
}
s := binaryStr[3:]
ttlMpls, err := strconv.ParseInt(tmp[len(tmp)-2:], 16, 32)
if err != nil {
return ""
}
return fmt.Sprintf("Lbl %d, TC %d, S %s, TTL %d", label, tc, s, ttlMpls)
}
func gernerateID(ttl_int int) int {
const ID_FIXED_HEADER = "10"
var processID = fmt.Sprintf("%07b", os.Getpid()&0x7f) //取进程ID的前7位
@@ -298,7 +262,7 @@ func (t *ICMPTracer) send(ttl int) error {
Body: &icmp.Echo{
ID: id,
//Data: []byte("HELLO-R-U-THERE"),
Data: bytes.Repeat([]byte{1}, t.Config.PktSize),
Data: append(bytes.Repeat([]byte{1}, t.Config.PktSize-4), 0x00, 0x00, 0x4f, 0xff),
Seq: ttl,
},
}

View File

@@ -137,6 +137,7 @@ func (t *ICMPTracerv6) Execute() (*Result, error) {
func (t *ICMPTracerv6) listenICMP() {
lc := NewPacketListener(t.icmpListen, t.ctx)
psize = t.Config.PktSize
go lc.Start()
for {
select {
@@ -256,7 +257,7 @@ func (t *ICMPTracerv6) send(ttl int) error {
Body: &icmp.Echo{
ID: id,
//Data: []byte("HELLO-R-U-THERE"),
Data: bytes.Repeat([]byte{1}, t.Config.PktSize),
Data: append(bytes.Repeat([]byte{1}, t.Config.PktSize-4), 0x00, 0x00, 0x4f, 0xff),
Seq: ttl,
},
}

View File

@@ -2,7 +2,10 @@ package trace
import (
"errors"
"fmt"
"net"
"strconv"
"strings"
"sync"
"time"
@@ -124,7 +127,7 @@ type Hop struct {
Error error
Geo *ipgeo.IPGeoData
Lang string
MPLS string
MPLS []string
}
func (h *Hop) fetchIPData(c Config) (err error) {
@@ -226,3 +229,108 @@ func (h *Hop) fetchIPData(c Config) (err error) {
return
}
func extractMPLS(msg ReceivedMessage, data []byte) []string {
if util.DisableMPLS != "" {
return nil
}
if psize != 52 {
return nil
}
extensionOffset := 20 + 8 + psize
if len(data) <= extensionOffset {
return nil
}
extensionBody := data[extensionOffset:]
if len(extensionBody) < 8 || len(extensionBody)%8 != 0 {
return nil
}
tmp := fmt.Sprintf("%x", msg.Msg[:*msg.N])
index := strings.Index(tmp, strings.Repeat("01", psize-4)+"00004fff")
if index == -1 {
return nil
}
tmp = tmp[index+psize*2:]
//由于限制长度了
index1 := strings.Index(tmp, "00002000")
l := len(tmp[index1+4:])/8 - 2
//fmt.Printf("l:%d\n", l)
if l < 1 {
return nil
}
//去掉扩展头和MPLS头
tmp = tmp[index1+4+8*2:]
//fmt.Print(tmp)
var retStrList []string
for i := 0; i < l; i++ {
label, err := strconv.ParseInt(tmp[i*8+0:i*8+5], 16, 32)
if err != nil {
return nil
}
strSlice := fmt.Sprintf("%s", []byte(tmp[i*8+5:i*8+6]))
//fmt.Printf("\nstrSlice: %s\n", strSlice)
num, err := strconv.ParseUint(strSlice, 16, 64)
if err != nil {
return nil
}
binaryStr := fmt.Sprintf("%04s", strconv.FormatUint(num, 2))
//fmt.Printf("\nbinaryStr: %s\n", binaryStr)
tc, err := strconv.ParseInt(binaryStr[:3], 2, 32)
if err != nil {
return nil
}
s := binaryStr[3:]
ttlMpls, err := strconv.ParseInt(tmp[i*8+6:i*8+8], 16, 32)
if err != nil {
return nil
}
//if i > 0 {
// retStr += "\n "
//}
retStrList = append(retStrList, fmt.Sprintf("[MPLS: Lbl %d, TC %d, S %s, TTL %d]", label, tc, s, ttlMpls))
}
//label, err := strconv.ParseInt(tmp[len(tmp)-8:len(tmp)-3], 16, 32)
//if err != nil {
// return ""
//}
//
//strSlice := fmt.Sprintf("%s", []byte(tmp[len(tmp)-3:len(tmp)-2]))
////fmt.Printf("\nstrSlice: %s\n", strSlice)
//
//num, err := strconv.ParseUint(strSlice, 16, 64)
//if err != nil {
// return ""
//}
//binaryStr := fmt.Sprintf("%04s", strconv.FormatUint(num, 2))
//
////fmt.Printf("\nbinaryStr: %s\n", binaryStr)
//tc, err := strconv.ParseInt(binaryStr[:3], 2, 32)
//if err != nil {
// return ""
//}
//s := binaryStr[3:]
//
//ttlMpls, err := strconv.ParseInt(tmp[len(tmp)-2:], 16, 32)
//if err != nil {
// return ""
//}
//
//retStr := fmt.Sprintf("Lbl %d, TC %d, S %s, TTL %d", label, tc, s, ttlMpls)
return retStrList
}

View File

@@ -20,6 +20,7 @@ var EnvToken = GetenvDefault("NEXTTRACE_TOKEN", "")
var UserAgent = fmt.Sprintf("NextTrace %s/%s/%s", config.Version, runtime.GOOS, runtime.GOARCH)
var RdnsCache sync.Map
var PowProviderParam = ""
var DisableMPLS = GetenvDefault("NEXTTRACE_DISABLEMPLS", "")
func LookupAddr(addr string) ([]string, error) {
// 如果在缓存中找到,直接返回