update
This commit is contained in:
parent
5ece8b96bb
commit
68f1eef7a6
@ -24,6 +24,8 @@ var dns, ipinfoaddr string
|
|||||||
var timeout int
|
var timeout int
|
||||||
var maxHop int
|
var maxHop int
|
||||||
var disableIpInfo bool
|
var disableIpInfo bool
|
||||||
|
var bindAddr string
|
||||||
|
var hideIncorrect bool
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
CmdNatClient.Flags().StringVarP(&natc.ServiceTarget, "target", "t", "", "forward server target address")
|
CmdNatClient.Flags().StringVarP(&natc.ServiceTarget, "target", "t", "", "forward server target address")
|
||||||
@ -48,6 +50,8 @@ func init() {
|
|||||||
CmdNetTrace.Flags().IntVarP(&timeout, "timeout", "t", 800, "超时时间,单位毫秒")
|
CmdNetTrace.Flags().IntVarP(&timeout, "timeout", "t", 800, "超时时间,单位毫秒")
|
||||||
CmdNetTrace.Flags().IntVarP(&maxHop, "max-hop", "m", 32, "最大跳数")
|
CmdNetTrace.Flags().IntVarP(&maxHop, "max-hop", "m", 32, "最大跳数")
|
||||||
CmdNetTrace.Flags().BoolVarP(&disableIpInfo, "disable-ipinfo", "D", false, "禁用ip信息查询")
|
CmdNetTrace.Flags().BoolVarP(&disableIpInfo, "disable-ipinfo", "D", false, "禁用ip信息查询")
|
||||||
|
CmdNetTrace.Flags().StringVarP(&bindAddr, "bind", "b", "0.0.0.0", "绑定地址")
|
||||||
|
CmdNetTrace.Flags().BoolVarP(&hideIncorrect, "hide-incorrect", "H", false, "隐藏错误节点")
|
||||||
Cmd.AddCommand(CmdNetTrace)
|
Cmd.AddCommand(CmdNetTrace)
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -86,7 +90,7 @@ var CmdNetTrace = &cobra.Command{
|
|||||||
}
|
}
|
||||||
for _, target := range args {
|
for _, target := range args {
|
||||||
starlog.Infoln("Traceroute to ", target)
|
starlog.Infoln("Traceroute to ", target)
|
||||||
Traceroute(target, dns, maxHop, time.Millisecond*time.Duration(timeout), ipinfoaddr)
|
Traceroute(target, bindAddr, dns, maxHop, time.Millisecond*time.Duration(timeout), ipinfoaddr, hideIncorrect)
|
||||||
fmt.Println("-----------------------------")
|
fmt.Println("-----------------------------")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
72
net/trace.go
72
net/trace.go
@ -32,7 +32,7 @@ func useCustomeDNS(dns []string) {
|
|||||||
net.DefaultResolver = &resolver
|
net.DefaultResolver = &resolver
|
||||||
}
|
}
|
||||||
|
|
||||||
func Traceroute(address string, dns string, maxHops int, timeout time.Duration, ipinfoAddr string) {
|
func Traceroute(address string, bindaddr string, dns string, maxHops int, timeout time.Duration, ipinfoAddr string, hideIncorrect bool) {
|
||||||
ipinfo := net.ParseIP(address)
|
ipinfo := net.ParseIP(address)
|
||||||
if ipinfo == nil {
|
if ipinfo == nil {
|
||||||
{
|
{
|
||||||
@ -51,9 +51,9 @@ func Traceroute(address string, dns string, maxHops int, timeout time.Duration,
|
|||||||
address = addr.String()
|
address = addr.String()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
traceroute(address, maxHops, timeout, ipinfoAddr)
|
traceroute(address, bindaddr, maxHops, timeout, ipinfoAddr, hideIncorrect)
|
||||||
}
|
}
|
||||||
func traceroute(address string, maxHops int, timeout time.Duration, ipinfoAddr string) {
|
func traceroute(address string, bindaddr string, maxHops int, timeout time.Duration, ipinfoAddr string, hideIncorrect bool) {
|
||||||
ipinfo := net.ParseIP(address)
|
ipinfo := net.ParseIP(address)
|
||||||
if ipinfo == nil {
|
if ipinfo == nil {
|
||||||
starlog.Errorln("IP地址解析失败:", address)
|
starlog.Errorln("IP地址解析失败:", address)
|
||||||
@ -74,18 +74,16 @@ func traceroute(address string, maxHops int, timeout time.Duration, ipinfoAddr s
|
|||||||
replyType = ipv6.ICMPTypeEchoReply
|
replyType = ipv6.ICMPTypeEchoReply
|
||||||
proto = 58
|
proto = 58
|
||||||
}
|
}
|
||||||
c, err := icmp.ListenPacket(network, "0.0.0.0")
|
if bindaddr == "" {
|
||||||
|
bindaddr = "0.0.0.0"
|
||||||
|
}
|
||||||
|
c, err := icmp.ListenPacket(network, bindaddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
fmt.Println(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer c.Close()
|
defer c.Close()
|
||||||
|
|
||||||
dst, err := net.ResolveIPAddr(resolveIP, address)
|
|
||||||
if err != nil {
|
|
||||||
starlog.Errorln("IP地址解析失败:", address, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if maxHops == 0 {
|
if maxHops == 0 {
|
||||||
maxHops = 32
|
maxHops = 32
|
||||||
}
|
}
|
||||||
@ -95,6 +93,13 @@ func traceroute(address string, maxHops int, timeout time.Duration, ipinfoAddr s
|
|||||||
}
|
}
|
||||||
exitfor:
|
exitfor:
|
||||||
for i := 1; i <= maxHops; i++ {
|
for i := 1; i <= maxHops; i++ {
|
||||||
|
retry := 0
|
||||||
|
doRetry:
|
||||||
|
dst, err := net.ResolveIPAddr(resolveIP, address)
|
||||||
|
if err != nil {
|
||||||
|
starlog.Errorln("IP地址解析失败:", address, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
if atomic.LoadInt32(&firstTargetHop) <= int32(i) {
|
if atomic.LoadInt32(&firstTargetHop) <= int32(i) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -134,34 +139,73 @@ exitfor:
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
exitrecheck:
|
||||||
|
for {
|
||||||
reply := make([]byte, 1500)
|
reply := make([]byte, 1500)
|
||||||
err = c.SetReadDeadline(time.Now().Add(timeout))
|
err = c.SetReadDeadline(time.Now().Add(timeout))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%d\tSetReadDeadline error: %v\n", i, err)
|
fmt.Printf("%d\tSetReadDeadline error: %v\n", i, err)
|
||||||
continue
|
break
|
||||||
}
|
}
|
||||||
n, peer, err := c.ReadFrom(reply)
|
n, peer, err := c.ReadFrom(reply)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%d\tReadFrom error: %v\n", i, err)
|
fmt.Printf("%d\tReadFrom error: %v\n", i, err)
|
||||||
continue
|
break
|
||||||
}
|
}
|
||||||
duration := time.Since(start)
|
duration := time.Since(start)
|
||||||
|
|
||||||
rm, err := icmp.ParseMessage(proto, reply[:n])
|
rm, err := icmp.ParseMessage(proto, reply[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%d\tParseMessage error: %v\n", i, err)
|
fmt.Printf("%d\tParseMessage error: %v\n", i, err)
|
||||||
return
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
switch rm.Type {
|
switch rm.Type {
|
||||||
case exceededType:
|
case exceededType:
|
||||||
fmt.Printf("%d\thops away:\t%s\t(%s) %s\n", i, peer, duration, GetIPInfo(peer.String(), ipinfoAddr))
|
fmt.Printf("%d\thops away:\t%s\t(%s) %s\n", i, peer, duration, GetIPInfo(peer.String(), ipinfoAddr))
|
||||||
|
break exitrecheck
|
||||||
case replyType:
|
case replyType:
|
||||||
fmt.Printf("%d\thops away:\t%s\t(%s) %s\n", i, peer, duration, GetIPInfo(peer.String(), ipinfoAddr))
|
fmt.Printf("%d\thops away:\t%s\t(%s) %s\n", i, peer, duration, GetIPInfo(peer.String(), ipinfoAddr))
|
||||||
|
if peer.String() == dst.String() {
|
||||||
break exitfor
|
break exitfor
|
||||||
default:
|
|
||||||
fmt.Printf("%d\tgot %+v from %v; want echo reply;%s\n", i, rm, peer, GetIPInfo(peer.String(), ipinfoAddr))
|
|
||||||
}
|
}
|
||||||
|
case ipv4.ICMPTypeEcho, ipv6.ICMPTypeEchoRequest:
|
||||||
|
if time.Now().Sub(now).Seconds() > timeout.Seconds() {
|
||||||
|
if retry < 1 {
|
||||||
|
retry++
|
||||||
|
goto doRetry
|
||||||
|
}
|
||||||
|
if !hideIncorrect {
|
||||||
|
fmt.Printf("%d\tInvalid Echo Request:%s (%s) %s\n", i, peer, duration, GetIPInfo(peer.String(), ipinfoAddr))
|
||||||
|
}
|
||||||
|
break exitrecheck
|
||||||
|
}
|
||||||
|
case ipv4.ICMPTypeDestinationUnreachable, ipv6.ICMPTypeDestinationUnreachable:
|
||||||
|
if time.Now().Sub(now).Seconds() > timeout.Seconds() {
|
||||||
|
if retry < 1 {
|
||||||
|
retry++
|
||||||
|
goto doRetry
|
||||||
|
}
|
||||||
|
if !hideIncorrect {
|
||||||
|
fmt.Printf("%d\tInvalid DstInv Request:%s (%s) %s\n", i, peer, duration, GetIPInfo(peer.String(), ipinfoAddr))
|
||||||
|
}
|
||||||
|
break exitrecheck
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if time.Now().Sub(now).Seconds() > timeout.Seconds() {
|
||||||
|
if retry < 1 {
|
||||||
|
retry++
|
||||||
|
goto doRetry
|
||||||
|
}
|
||||||
|
if !hideIncorrect {
|
||||||
|
fmt.Printf("%d\tgot %+v from %v (%s) %s\n", i, rm.Type, peer, duration, GetIPInfo(peer.String(), ipinfoAddr))
|
||||||
|
}
|
||||||
|
break exitrecheck
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user