owrt/uci_firewall.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()
}