Skip to content

Commit

Permalink
支持DST-MAC
Browse files Browse the repository at this point in the history
  • Loading branch information
mlkt committed Aug 7, 2024
1 parent fa91973 commit bca5c31
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 63 deletions.
9 changes: 6 additions & 3 deletions constant/rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ const (
GEOSITE
GEOIP
SrcGEOIP
IPASN
SrcMAC
DstMAC
IPASN
SrcIPASN
IPCIDR
SrcIPCIDR
Expand Down Expand Up @@ -55,10 +56,12 @@ func (rt RuleType) String() string {
return "GeoIP"
case SrcGEOIP:
return "SrcGeoIP"
case IPASN:
return "IPASN"
case SrcMAC:
return "SrcMAC"
case DstMAC:
return "DstMAC"
case IPASN:
return "IPASN"
case SrcIPASN:
return "SrcIPASN"
case IPCIDR:
Expand Down
46 changes: 29 additions & 17 deletions rules/common/mac.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,21 +19,27 @@ var arpTable = make(map[string]string)
const reloadInterval = 5 * time.Minute

var startOnce sync.Once

func init() {
}

type SrcMAC struct {
type MacAddr struct {
*Base
mac string
adapter string
mac string
adapter string
isSourceIP bool
}

func (d *SrcMAC) RuleType() C.RuleType {
return C.SrcMAC
func (d *MacAddr) RuleType() C.RuleType {
if d.isSourceIP {
return C.SrcMAC
} else {
return C.DstMAC
}
}

func getLoadArpTableFunc() func() (string, error) {
const ipv6Error = "can't load ipv6 arp table, SRC-MAC rule can't match src ipv6 address"
const ipv6Error = "can't load ipv6 arp table, SRC-MAC/DST-MAC rule can't match src ipv6 address"

getIpv4Only := func() (string, error) {
return cmd.ExecCmd("arp -a")
Expand Down Expand Up @@ -95,39 +101,45 @@ func getLoadArpTableFunc() func() (string, error) {
}
}

func (d *SrcMAC) Match(metadata *C.Metadata) (bool, string) {
func (d *MacAddr) Match(metadata *C.Metadata) (bool, string) {
table := getArpTable()
srcIP := metadata.SrcIP.String()
mac, exists := table[srcIP]
var ip string
if d.isSourceIP {
ip = metadata.SrcIP.String()
} else {
ip = metadata.DstIP.String()
}
mac, exists := table[ip]
if exists {
if mac == d.mac {
return true, d.adapter
}
} else {
log.Warnln("can't find the IP address in arp table: %s", srcIP)
log.Infoln("can't find the IP address in arp table: %s", ip)
}
return false, d.adapter
}

func (d *SrcMAC) Adapter() string {
func (d *MacAddr) Adapter() string {
return d.adapter
}

func (d *SrcMAC) Payload() string {
func (d *MacAddr) Payload() string {
return d.mac
}

var macRegex = regexp.MustCompile(`^([0-9a-f]{2}:){5}[0-9a-f]{2}$`)

func NewMAC(mac string, adapter string) (*SrcMAC, error) {
func NewMAC(mac string, adapter string, isSrc bool) (*MacAddr, error) {
macAddr := strings.ReplaceAll(strings.ToLower(mac), "-", ":")
if !macRegex.MatchString(macAddr) {
return nil, errors.New("mac address format error: " + mac)
}
return &SrcMAC{
Base: &Base{},
mac: macAddr,
adapter: adapter,
return &MacAddr{
Base: &Base{},
mac: macAddr,
adapter: adapter,
isSourceIP: isSrc,
}, nil
}

Expand Down
6 changes: 4 additions & 2 deletions rules/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ func ParseRule(tp, payload, target string, params []string, subRules map[string]
parsed, parseErr = RC.NewGEOIP(payload, target, false, noResolve)
case "SRC-GEOIP":
parsed, parseErr = RC.NewGEOIP(payload, target, true, true)
case "SRC-MAC":
parsed, parseErr = RC.NewMAC(payload, target, true)
case "DST-MAC":
parsed, parseErr = RC.NewMAC(payload, target, false)
case "IP-ASN":
noResolve := RC.HasNoResolve(params)
parsed, parseErr = RC.NewIPASN(payload, target, false, noResolve)
case "SRC-MAC":
parsed, parseErr = RC.NewMAC(payload, target)
case "SRC-IP-ASN":
parsed, parseErr = RC.NewIPASN(payload, target, true, true)
case "IP-CIDR", "IP-CIDR6":
Expand Down
82 changes: 41 additions & 41 deletions test/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,27 @@ require (
github.com/docker/docker v20.10.21+incompatible
github.com/docker/go-connections v0.4.0
github.com/metacubex/mihomo v0.0.0
github.com/miekg/dns v1.1.57
github.com/stretchr/testify v1.8.4
golang.org/x/net v0.18.0
github.com/miekg/dns v1.1.61
github.com/stretchr/testify v1.9.0
golang.org/x/net v0.26.0
)

replace github.com/metacubex/mihomo => ../

require (
github.com/3andne/restls-client-go v0.1.6 // indirect
github.com/Microsoft/go-winio v0.6.0 // indirect
github.com/RyuaNerin/go-krypto v1.0.2 // indirect
github.com/RyuaNerin/go-krypto v1.2.4 // indirect
github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 // indirect
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
github.com/andybalholm/brotli v1.0.5 // indirect
github.com/andybalholm/brotli v1.0.6 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/cilium/ebpf v0.12.3 // indirect
github.com/coreos/go-iptables v0.7.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/dlclark/regexp2 v1.10.0 // indirect
github.com/dlclark/regexp2 v1.11.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/ericlagergren/aegis v0.0.0-20230312195928-b4ce538b56f9 // indirect
Expand All @@ -39,32 +39,32 @@ require (
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/gobwas/httphead v0.1.0 // indirect
github.com/gobwas/pool v0.2.1 // indirect
github.com/gobwas/ws v1.3.1 // indirect
github.com/gofrs/uuid/v5 v5.0.0 // indirect
github.com/gobwas/ws v1.4.0 // indirect
github.com/gofrs/uuid/v5 v5.2.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 // indirect
github.com/hashicorp/yamux v0.1.1 // indirect
github.com/insomniacslk/dhcp v0.0.0-20231016090811-6a2c8fbdcc1c // indirect
github.com/insomniacslk/dhcp v0.0.0-20240529192340-51bc6136a0a6 // indirect
github.com/josharian/native v1.1.0 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/klauspost/compress v1.16.7 // indirect
github.com/klauspost/cpuid/v2 v2.2.6 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mdlayher/netlink v1.7.2 // indirect
github.com/mdlayher/socket v0.4.1 // indirect
github.com/metacubex/gopacket v1.1.20-0.20230608035415-7e2f98a3e759 // indirect
github.com/metacubex/gvisor v0.0.0-20231001104248-0f672c3fb8d8 // indirect
github.com/metacubex/quic-go v0.40.1-0.20231130135418-0c1b47cf9394 // indirect
github.com/metacubex/sing-quic v0.0.0-20231130141855-0022295e524b // indirect
github.com/metacubex/sing-shadowsocks v0.2.5 // indirect
github.com/metacubex/sing-shadowsocks2 v0.1.4 // indirect
github.com/metacubex/sing-tun v0.1.15-0.20231103033938-170591e8d5bd // indirect
github.com/metacubex/sing-vmess v0.1.9-0.20230921005247-a0488d7dac74 // indirect
github.com/metacubex/sing-wireguard v0.0.0-20231001110902-321836559170 // indirect
github.com/metacubex/gvisor v0.0.0-20240320004321-933faba989ec // indirect
github.com/metacubex/quic-go v0.45.1-0.20240610004319-163fee60637e // indirect
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 // indirect
github.com/metacubex/sing-shadowsocks v0.2.7 // indirect
github.com/metacubex/sing-shadowsocks2 v0.2.1 // indirect
github.com/metacubex/sing-tun v0.2.7-0.20240719141246-19c49ac9589d // indirect
github.com/metacubex/sing-vmess v0.1.9-0.20240719134745-1df6fb20bbf9 // indirect
github.com/metacubex/sing-wireguard v0.0.0-20240618022557-a6efaa37127a // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/mroth/weightedrand/v2 v2.1.0 // indirect
Expand All @@ -78,22 +78,22 @@ require (
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/puzpuzpuz/xsync/v3 v3.0.2 // indirect
github.com/puzpuzpuz/xsync/v3 v3.2.0 // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a // indirect
github.com/sagernet/go-tun2socks v1.16.12-0.20220818015926-16cb67876a61 // indirect
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 // indirect
github.com/sagernet/sing v0.2.18-0.20231108041402-4fbbd193203c // indirect
github.com/sagernet/sing-mux v0.1.5-0.20231109075101-6b086ed6bb07 // indirect
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect
github.com/sagernet/sing v0.5.0-alpha.13 // indirect
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6 // indirect
github.com/sagernet/sing-shadowtls v0.1.4 // indirect
github.com/sagernet/smux v0.0.0-20230312102458-337ec2a5af37 // indirect
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect
github.com/sagernet/tfo-go v0.0.0-20230816093905-5a5c285d44a6 // indirect
github.com/sagernet/utls v0.0.0-20230309024959-6732c2ab36f2 // indirect
github.com/sagernet/wireguard-go v0.0.0-20230807125731-5d4a7ef2dc5f // indirect
github.com/samber/lo v1.38.1 // indirect
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e // indirect
github.com/samber/lo v1.39.0 // indirect
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 // indirect
github.com/shirou/gopsutil/v3 v3.23.10 // indirect
github.com/shirou/gopsutil/v3 v3.24.5 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b // indirect
github.com/sina-ghaderi/rabaead v0.0.0-20220730151906-ab6e06b96e8c // indirect
Expand All @@ -102,22 +102,22 @@ require (
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zhangyunhao116/fastrand v0.3.0 // indirect
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect
go.uber.org/mock v0.3.0 // indirect
go4.org/netipx v0.0.0-20230824141953-6213f710f925 // indirect
golang.org/x/crypto v0.16.0 // indirect
golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect
golang.org/x/tools v0.15.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
go.uber.org/mock v0.4.0 // indirect
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
golang.org/x/crypto v0.24.0 // indirect
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.22.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.2.1 // indirect
lukechampine.com/blake3 v1.3.0 // indirect
)
Loading

0 comments on commit bca5c31

Please sign in to comment.