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() }