120 lines
2.7 KiB
Go
120 lines
2.7 KiB
Go
package owrt
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// UCIFirewall is the description of the OpenWRT Firewall rules (all types)
|
|
type UCIFirewall struct {
|
|
UCI *UCI
|
|
Rules map[int]*UCIFirewallRule
|
|
Redirects map[int]*UCIFirewallRedirect
|
|
Customs map[int]*UCIFirewallCustomRule
|
|
}
|
|
|
|
// NewUCIFirewall builds a new UCIFirewall instance
|
|
func NewUCIFirewall(uci *UCI) *UCIFirewall {
|
|
return &UCIFirewall{
|
|
UCI: uci,
|
|
Rules: map[int]*UCIFirewallRule{},
|
|
Redirects: map[int]*UCIFirewallRedirect{},
|
|
Customs: map[int]*UCIFirewallCustomRule{},
|
|
}
|
|
}
|
|
|
|
// loadRules loads existing firewall rules
|
|
func (f *UCIFirewall) loadRules() error {
|
|
var rules = map[int]*UCIFirewallRule{}
|
|
var lines []string
|
|
|
|
matches := map[string]*regexp.Regexp{
|
|
"Name": regexp.MustCompile(`@rule\[[0-9]*\].name=`),
|
|
"Src": regexp.MustCompile(`@rule\[[0-9]*\].src=`),
|
|
"Target": regexp.MustCompile(`@rule\[[0-9]*\].target=`),
|
|
"Proto": regexp.MustCompile(`@rule\[[0-9]*\].porto=`),
|
|
"DestPort": regexp.MustCompile(`@rule\[[0-9]*\].dest_port=`),
|
|
}
|
|
|
|
if f.UCI == nil {
|
|
return fmt.Errorf("No UCI Client present ... this could not append")
|
|
}
|
|
|
|
firewallRes := f.UCI.uciRun("uci", "show", "firewall")
|
|
if firewallRes.ReturnCode == 0 {
|
|
lines = grep(firewallRes.Stdout, "firewall.@rule")
|
|
// lines = strings.Split(firewallRes.Stdout, "\n")
|
|
} else {
|
|
return fmt.Errorf("%d - %s %s %s",
|
|
firewallRes.ReturnCode,
|
|
firewallRes.Command,
|
|
firewallRes.Stdout,
|
|
firewallRes.Stdout)
|
|
}
|
|
|
|
for _, li := range lines {
|
|
var idx int
|
|
var sIdx string
|
|
|
|
if li != "" {
|
|
sIdx = strings.Split(li, "[")[1]
|
|
sIdx = strings.Split(sIdx, "]")[0]
|
|
|
|
if s, err := strconv.ParseInt(sIdx, 10, 32); err == nil {
|
|
idx = int(s)
|
|
}
|
|
}
|
|
|
|
if _, exists := rules[idx]; !exists {
|
|
rules[idx] = NewUCIFirewallRule(f.UCI)
|
|
rules[idx].Index = idx
|
|
}
|
|
|
|
for key, expr := range matches {
|
|
if expr.MatchString(li) {
|
|
value := strings.Split(li, "=")[1]
|
|
value = strings.Trim(value, "'")
|
|
if key == "Name" {
|
|
fmt.Printf("Setting Name %s for rule #%d\n", value, idx)
|
|
rules[idx].Name = value
|
|
}
|
|
if key == "Src" {
|
|
rules[idx].Src = value
|
|
}
|
|
if key == "Proto" {
|
|
rules[idx].Proto = value
|
|
}
|
|
if key == "DestPort" {
|
|
rules[idx].DestPort = value
|
|
}
|
|
if key == "Target" {
|
|
rules[idx].Target = value
|
|
}
|
|
}
|
|
}
|
|
}
|
|
f.Rules = rules
|
|
return nil
|
|
}
|
|
|
|
func (f *UCIFirewall) loadRedirects() error {
|
|
return nil
|
|
}
|
|
|
|
func (f *UCIFirewall) loadCustoms() error {
|
|
return nil
|
|
}
|
|
|
|
// Load run uci show firewall and creates an nice UCIFirewall Object
|
|
func (f *UCIFirewall) Load() error {
|
|
if r := f.loadRules(); r != nil {
|
|
return r
|
|
}
|
|
if r := f.loadRedirects(); r != nil {
|
|
return r
|
|
}
|
|
return f.loadCustoms()
|
|
}
|