summaryrefslogtreecommitdiff
path: root/att script/6(v6篡改)/code/src/fakedns6/ipv6util.go
blob: 09245d344a0ecbb05461fb6260669e12aacefba7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
package main

import (
	"encoding/hex"
	"fmt"
	"net"
	"os/exec"
	"strings"
	"syscall"
	"unsafe"
)

type router struct {
	ifaces []net.Interface
	addrs  []net.IP
	v6     routeSlice
}
type routeSlice []*rtInfo

type rtInfo struct {
	// Dst              net.IPNet
	Gateway, PrefSrc net.IP
	OutputIface      uint32
	Priority         uint32
}

func getv6Gateway() (net.IP, error) {
	rtr := &router{}

	tab, err := syscall.NetlinkRIB(syscall.RTM_GETROUTE, syscall.AF_INET6)
	if err != nil {
		return nil, err
	}

	msgs, err := syscall.ParseNetlinkMessage(tab)
	if err != nil {
		return nil, err
	}

	for _, m := range msgs {
		switch m.Header.Type {
		case syscall.NLMSG_DONE:
			break
		case syscall.RTM_NEWROUTE:
			// rtmsg := (*syscall.RtMsg)(unsafe.Pointer(&m.Data[0]))
			attrs, err := syscall.ParseNetlinkRouteAttr(&m)
			if err != nil {
				return nil, err
			}
			routeInfo := rtInfo{}
			rtr.v6 = append(rtr.v6, &routeInfo)
			for _, attr := range attrs {
				switch attr.Attr.Type {
				// case syscall.RTA_DST:
				// 	routeInfo.Dst.IP = net.IP(attr.Value)
				// 	routeInfo.Dst.Mask = net.CIDRMask(int(rtmsg.Dst_len), len(attr.Value)*8)
				case syscall.RTA_GATEWAY:
					routeInfo.Gateway = net.IP(attr.Value)
				case syscall.RTA_OIF:
					routeInfo.OutputIface = *(*uint32)(unsafe.Pointer(&attr.Value[0]))
				case syscall.RTA_PRIORITY:
					routeInfo.Priority = *(*uint32)(unsafe.Pointer(&attr.Value[0]))
				case syscall.RTA_PREFSRC:
					routeInfo.PrefSrc = net.IP(attr.Value)
				}
			}
		}
	}
	ips := []net.IP{}
	for _, rt := range rtr.v6 {
		if rt.Gateway != nil {
			ips = append(ips, rt.Gateway)
		}
	}
	return ips[0], nil
}

func getGatewayV6Mac(ifacename string, gwIP net.IP) (net.HardwareAddr, error) {
	if debugOutput {
		println("邻居发现--使用网卡接口为:" + ifacename)
	}
	out, err := exec.Command("ip", "-6", "neighbor", "show", "dev", ifacename).Output()
	if err != nil {
		println(err.Error())
	} else {
		outlines := strings.Split(string(out), "/n")
		for _, line := range outlines {
			linelist := strings.Split(line, " ")
			// 与网关对应的MAC地址
			if linelist[0] == gwIP.String() {

				maclist := strings.Split(linelist[2], ":")
				var macbyte []byte
				for _, m := range maclist {
					b, _ := hex.DecodeString(m)
					macbyte = append(macbyte, b[0])
				}
				return net.HardwareAddr(macbyte), nil
			}
		}
	}
	return nil, fmt.Errorf("无法找到网关" + gwIP.String() + "对应的MAC地址")
}