From b733ef2d8242b00d52c8fcaacfef7ec5c50a2b60 Mon Sep 17 00:00:00 2001 From: tsosunchia <59512455+tsosunchia@users.noreply.github.com> Date: Fri, 6 Oct 2023 06:02:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=AF=B9=E5=A4=9AMPLS?= =?UTF-8?q?=E6=83=85=E6=99=AF=E7=9A=84=E6=94=AF=E6=8C=81=EF=BC=8C=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E9=80=9A=E8=BF=87ENV=E6=88=96=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E7=A6=81=E7=94=A8MPLS=E5=8A=9F=E8=83=BD=20=20=E8=A6=81?= =?UTF-8?q?=E6=8F=90=E4=BA=A4=E7=9A=84=E5=8F=98=E6=9B=B4=EF=BC=9A=20=09?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20=20=20cmd/cmd.go=20=09?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20=20=20printer/basic.go=20?= =?UTF-8?q?=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20=20=20printer/printer.go?= =?UTF-8?q?=20=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20=20=20printer/realtim?= =?UTF-8?q?e=5Fprinter.go=20=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20=20=20t?= =?UTF-8?q?race/icmp=5Fipv4.go=20=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20?= =?UTF-8?q?=20=20trace/icmp=5Fipv6.go=20=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20?= =?UTF-8?q?=20=20=20=20trace/trace.go=20=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20?= =?UTF-8?q?=20=20=20=20util/util.go?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/cmd.go | 5 ++ printer/basic.go | 3 - printer/printer.go | 5 +- printer/realtime_printer.go | 5 ++ trace/icmp_ipv4.go | 44 ++------------- trace/icmp_ipv6.go | 3 +- trace/trace.go | 110 +++++++++++++++++++++++++++++++++++- util/util.go | 1 + 8 files changed, 128 insertions(+), 48 deletions(-) diff --git a/cmd/cmd.go b/cmd/cmd.go index 2dfeed0..97f4a93 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -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 { diff --git a/printer/basic.go b/printer/basic.go index 79377e1..686743a 100644 --- a/printer/basic.go +++ b/printer/basic.go @@ -109,7 +109,4 @@ func applyLangSetting(h *trace.Hop) { } } - if len(h.MPLS) > 1 { - h.Hostname += " [MPLS: " + h.MPLS + "]" - } } diff --git a/printer/printer.go b/printer/printer.go index 49d19f3..7ddfa89 100644 --- a/printer/printer.go +++ b/printer/printer.go @@ -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: diff --git a/printer/realtime_printer.go b/printer/realtime_printer.go index ccc659f..f7bf110 100644 --- a/printer/realtime_printer.go +++ b/printer/realtime_printer.go @@ -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 } diff --git a/trace/icmp_ipv4.go b/trace/icmp_ipv4.go index 7f6cc6e..96c68b6 100644 --- a/trace/icmp_ipv4.go +++ b/trace/icmp_ipv4.go @@ -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, }, } diff --git a/trace/icmp_ipv6.go b/trace/icmp_ipv6.go index b545d31..82cac1e 100644 --- a/trace/icmp_ipv6.go +++ b/trace/icmp_ipv6.go @@ -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, }, } diff --git a/trace/trace.go b/trace/trace.go index f52ad7a..8288987 100644 --- a/trace/trace.go +++ b/trace/trace.go @@ -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 +} diff --git a/util/util.go b/util/util.go index 31bbe7e..35e0908 100644 --- a/util/util.go +++ b/util/util.go @@ -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) { // 如果在缓存中找到,直接返回