mirror of
https://github.com/nxtrace/NTrace-core.git
synced 2025-08-12 06:26:39 +00:00
增加对多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:
@@ -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 {
|
||||
|
||||
@@ -109,7 +109,4 @@ func applyLangSetting(h *trace.Hop) {
|
||||
}
|
||||
}
|
||||
|
||||
if len(h.MPLS) > 1 {
|
||||
h.Hostname += " [MPLS: " + h.MPLS + "]"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
110
trace/trace.go
110
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
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
// 如果在缓存中找到,直接返回
|
||||
|
||||
Reference in New Issue
Block a user