Files
sing-box-extended-mirror/cmd/sing-box/cmd_rule_set_match.go
T

106 lines
2.6 KiB
Go
Raw Normal View History

2024-03-24 19:23:11 +08:00
package main
import (
"bytes"
2024-11-10 12:11:21 +08:00
"context"
2024-03-24 19:23:11 +08:00
"io"
"os"
2025-05-01 11:00:01 +08:00
"path/filepath"
2024-03-24 19:23:11 +08:00
"github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/srs"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
2024-10-21 23:38:34 +08:00
"github.com/sagernet/sing-box/route/rule"
2024-03-24 19:23:11 +08:00
E "github.com/sagernet/sing/common/exceptions"
2024-06-26 11:19:27 +08:00
F "github.com/sagernet/sing/common/format"
2024-03-24 19:23:11 +08:00
"github.com/sagernet/sing/common/json"
M "github.com/sagernet/sing/common/metadata"
2024-03-24 19:23:11 +08:00
"github.com/spf13/cobra"
)
var flagRuleSetMatchFormat string
var commandRuleSetMatch = &cobra.Command{
Use: "match <rule-set path> <IP address/domain>",
2024-06-26 00:45:10 +08:00
Short: "Check if an IP address or a domain matches the rule-set",
2024-03-24 19:23:11 +08:00
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
err := ruleSetMatch(args[0], args[1])
if err != nil {
log.Fatal(err)
}
},
}
func init() {
commandRuleSetMatch.Flags().StringVarP(&flagRuleSetMatchFormat, "format", "f", "source", "rule-set format")
commandRuleSet.AddCommand(commandRuleSetMatch)
}
func ruleSetMatch(sourcePath string, domain string) error {
var (
reader io.Reader
err error
)
if sourcePath == "stdin" {
reader = os.Stdin
} else {
reader, err = os.Open(sourcePath)
if err != nil {
return E.Cause(err, "read rule-set")
}
}
content, err := io.ReadAll(reader)
if err != nil {
return E.Cause(err, "read rule-set")
}
2025-05-01 11:00:01 +08:00
if flagRuleSetMatchFormat == "" {
switch filepath.Ext(sourcePath) {
case ".json":
flagRuleSetMatchFormat = C.RuleSetFormatSource
case ".srs":
flagRuleSetMatchFormat = C.RuleSetFormatBinary
}
}
2024-11-11 16:27:28 +08:00
var ruleSet option.PlainRuleSetCompat
2024-03-24 19:23:11 +08:00
switch flagRuleSetMatchFormat {
case C.RuleSetFormatSource:
2024-11-11 16:27:28 +08:00
ruleSet, err = json.UnmarshalExtended[option.PlainRuleSetCompat](content)
if err != nil {
return err
}
2024-03-24 19:23:11 +08:00
case C.RuleSetFormatBinary:
2024-11-11 16:27:28 +08:00
ruleSet, err = srs.Read(bytes.NewReader(content), false)
2024-03-24 19:23:11 +08:00
if err != nil {
return err
}
default:
2024-06-26 00:45:10 +08:00
return E.New("unknown rule-set format: ", flagRuleSetMatchFormat)
2024-03-24 19:23:11 +08:00
}
2024-11-11 16:27:28 +08:00
plainRuleSet, err := ruleSet.Upgrade()
if err != nil {
return err
}
ipAddress := M.ParseAddr(domain)
var metadata adapter.InboundContext
if ipAddress.IsValid() {
metadata.Destination = M.SocksaddrFrom(ipAddress, 0)
} else {
metadata.Domain = domain
}
2024-03-24 19:23:11 +08:00
for i, ruleOptions := range plainRuleSet.Rules {
var currentRule adapter.HeadlessRule
2024-11-10 12:11:21 +08:00
currentRule, err = rule.NewHeadlessRule(context.Background(), ruleOptions)
2024-03-24 19:23:11 +08:00
if err != nil {
return E.Cause(err, "parse rule_set.rules.[", i, "]")
}
if currentRule.Match(&metadata) {
2024-06-26 11:19:27 +08:00
println(F.ToString("match rules.[", i, "]: ", currentRule))
2024-03-24 19:23:11 +08:00
}
}
return nil
}