mirror of
https://github.com/oneclickvirt/backtrace.git
synced 2025-04-22 04:02:07 +08:00
fix: 添加ipv6的hop日志记录
This commit is contained in:
parent
466c8dbe5d
commit
fcc0403612
@ -13,6 +13,7 @@ import (
|
|||||||
"golang.org/x/net/icmp"
|
"golang.org/x/net/icmp"
|
||||||
"golang.org/x/net/ipv4"
|
"golang.org/x/net/ipv4"
|
||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
|
. "github.com/oneclickvirt/defaultset"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultConfig is the default configuration for Tracer.
|
// DefaultConfig is the default configuration for Tracer.
|
||||||
@ -132,6 +133,16 @@ func (t *Tracer) init() {
|
|||||||
conn, err := net.ListenIP(network, t.Addr)
|
conn, err := net.ListenIP(network, t.Addr)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.ipv6conn = ipv6.NewPacketConn(conn)
|
t.ipv6conn = ipv6.NewPacketConn(conn)
|
||||||
|
err = t.ipv6conn.SetControlMessage(ipv6.FlagHopLimit|ipv6.FlagSrc|ipv6.FlagDst|ipv6.FlagInterface, true)
|
||||||
|
if err != nil {
|
||||||
|
if EnableLoger {
|
||||||
|
InitLogger()
|
||||||
|
defer Logger.Sync()
|
||||||
|
Logger.Info("设置IPv6控制消息失败: " + err.Error())
|
||||||
|
}
|
||||||
|
t.ipv6conn.Close()
|
||||||
|
continue
|
||||||
|
}
|
||||||
go t.serveIPv6(t.ipv6conn)
|
go t.serveIPv6(t.ipv6conn)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -224,18 +235,23 @@ func (t *Tracer) sendRequest(dst net.IP, ttl int) (*packet, error) {
|
|||||||
req := &packet{dst, id, ttl, time.Now()}
|
req := &packet{dst, id, ttl, time.Now()}
|
||||||
if dst.To4() == nil {
|
if dst.To4() == nil {
|
||||||
// IPv6
|
// IPv6
|
||||||
b = newPacketV6(id, dst, ttl)
|
b := newPacketV6(id, dst, ttl)
|
||||||
if t.ipv6conn != nil {
|
if t.ipv6conn != nil {
|
||||||
cm := &ipv6.ControlMessage{
|
cm := &ipv6.ControlMessage{
|
||||||
HopLimit: ttl,
|
HopLimit: ttl,
|
||||||
}
|
}
|
||||||
_, err := t.ipv6conn.WriteTo(b, cm, &net.IPAddr{IP: dst})
|
_, err := t.ipv6conn.WriteTo(b, cm, &net.IPAddr{IP: dst})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if EnableLoger {
|
||||||
|
InitLogger()
|
||||||
|
defer Logger.Sync()
|
||||||
|
Logger.Info("发送IPv6请求失败: " + err.Error())
|
||||||
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("IPv6 connection not available")
|
return nil, errors.New("IPv6连接不可用")
|
||||||
} else {
|
} else {
|
||||||
// IPv4
|
// IPv4
|
||||||
b = newPacketV4(id, dst, ttl)
|
b = newPacketV4(id, dst, ttl)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package backtrace
|
package backtrace
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
@ -11,45 +10,71 @@ import (
|
|||||||
"golang.org/x/net/ipv6"
|
"golang.org/x/net/ipv6"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// func newPacketV6(id uint16, dst net.IP, ttl int) []byte {
|
||||||
|
// // 创建ICMP消息(回显请求)
|
||||||
|
// msg := icmp.Message{
|
||||||
|
// Type: ipv6.ICMPTypeEchoRequest,
|
||||||
|
// Body: &icmp.Echo{
|
||||||
|
// ID: int(id),
|
||||||
|
// Seq: int(id),
|
||||||
|
// },
|
||||||
|
// }
|
||||||
|
// // 序列化ICMP消息
|
||||||
|
// icmpData, _ := msg.Marshal(nil)
|
||||||
|
// // 手动创建原始IPv6数据包头部
|
||||||
|
// ipHeaderBytes := make([]byte, ipv6.HeaderLen)
|
||||||
|
// // 设置版本和流量类别(第一个字节)
|
||||||
|
// ipHeaderBytes[0] = (ipv6.Version << 4)
|
||||||
|
// // 设置下一个头部(协议)
|
||||||
|
// ipHeaderBytes[6] = ProtocolIPv6ICMP
|
||||||
|
// // 设置跳数限制
|
||||||
|
// ipHeaderBytes[7] = byte(ttl)
|
||||||
|
// // 设置有效载荷长度(2字节字段)
|
||||||
|
// binary.BigEndian.PutUint16(ipHeaderBytes[4:6], uint16(len(icmpData)))
|
||||||
|
// // 设置目标地址(最后16个字节)
|
||||||
|
// copy(ipHeaderBytes[24:40], dst.To16())
|
||||||
|
// // 合并头部和ICMP数据
|
||||||
|
// return append(ipHeaderBytes, icmpData...)
|
||||||
|
// }
|
||||||
|
|
||||||
func newPacketV6(id uint16, dst net.IP, ttl int) []byte {
|
func newPacketV6(id uint16, dst net.IP, ttl int) []byte {
|
||||||
// 创建ICMP消息(回显请求)
|
// 使用ipv6包的Echo请求
|
||||||
msg := icmp.Message{
|
msg := icmp.Message{
|
||||||
Type: ipv6.ICMPTypeEchoRequest,
|
Type: ipv6.ICMPTypeEchoRequest,
|
||||||
|
Code: 0,
|
||||||
Body: &icmp.Echo{
|
Body: &icmp.Echo{
|
||||||
ID: int(id),
|
ID: int(id),
|
||||||
Seq: int(id),
|
Seq: int(id),
|
||||||
|
Data: []byte("HELLO-R-U-THERE"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
// 序列化ICMP消息
|
// 序列化ICMP消息
|
||||||
icmpData, _ := msg.Marshal(nil)
|
icmpBytes, _ := msg.Marshal(nil)
|
||||||
// 手动创建原始IPv6数据包头部
|
return icmpBytes
|
||||||
ipHeaderBytes := make([]byte, ipv6.HeaderLen)
|
|
||||||
// 设置版本和流量类别(第一个字节)
|
|
||||||
ipHeaderBytes[0] = (ipv6.Version << 4)
|
|
||||||
// 设置下一个头部(协议)
|
|
||||||
ipHeaderBytes[6] = ProtocolIPv6ICMP
|
|
||||||
// 设置跳数限制
|
|
||||||
ipHeaderBytes[7] = byte(ttl)
|
|
||||||
// 设置有效载荷长度(2字节字段)
|
|
||||||
binary.BigEndian.PutUint16(ipHeaderBytes[4:6], uint16(len(icmpData)))
|
|
||||||
// 设置目标地址(最后16个字节)
|
|
||||||
copy(ipHeaderBytes[24:40], dst.To16())
|
|
||||||
// 合并头部和ICMP数据
|
|
||||||
return append(ipHeaderBytes, icmpData...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Tracer) serveIPv6(conn *ipv6.PacketConn) error {
|
func (t *Tracer) serveIPv6(conn *ipv6.PacketConn) error {
|
||||||
|
if EnableLoger {
|
||||||
|
InitLogger()
|
||||||
|
defer Logger.Sync()
|
||||||
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
buf := make([]byte, 1500)
|
buf := make([]byte, 1500)
|
||||||
for {
|
for {
|
||||||
n, _, from, err := conn.ReadFrom(buf)
|
n, cm, src, err := conn.ReadFrom(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if EnableLoger {
|
||||||
|
Logger.Error("读取IPv6响应失败: " + err.Error())
|
||||||
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
fromIP := from.(*net.IPAddr).IP
|
if EnableLoger {
|
||||||
|
Logger.Info(fmt.Sprintf("收到IPv6响应: 来源=%v, 跳数=%d", src, cm.HopLimit))
|
||||||
|
}
|
||||||
|
fromIP := src.(*net.IPAddr).IP
|
||||||
err = t.serveData(fromIP, buf[:n])
|
err = t.serveData(fromIP, buf[:n])
|
||||||
if err != nil {
|
if err != nil && EnableLoger {
|
||||||
continue
|
Logger.Warn("处理IPv6数据失败: " + err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user