Open stealthybox opened 4 years ago
type CustomStat struct {
Packets uint64 `json:"pkts"`
Bytes uint64 `json:"bytes"`
Target string `json:"target"`
Protocol string `json:"prot"`
Opt string `json:"opt"`
Input string `json:"in"`
Output string `json:"out"`
Source string `json:"source"`
Destination string `json:"destination"`
Port string `json:"port"`
Options string `json:"options"`
}
func parseIptablesOutput(output string) ([]CustomStat, error) {
var customStats []CustomStat
scanner := bufio.NewScanner(strings.NewReader(output))
for scanner.Scan() {
line := scanner.Text()
fields := strings.Fields(line)
if len(fields) < 10 {
continue
}
packets, _ := strconv.ParseUint(fields[0], 10, 64)
bytes, _ := strconv.ParseUint(fields[1], 10, 64)
customStats = append(customStats, CustomStat{
Packets: packets,
Bytes: bytes,
Target: fields[2],
Protocol: fields[3],
Opt: fields[4],
Input: fields[5],
Output: fields[6],
Source: fields[7],
Destination: fields[8],
Options: strings.Join(fields[9:], " "),
})
}
return customStats, scanner.Err()
}
Calling
ipt.StructuredStats("nat", "POSTROUTING")
when rules have negated ranges can error:On my machine, I set up a virtual bridge for this subnet, and these iptables rules were auto-created:
ignite
uses this library call to cleanup chains, and these MASQ rules fail tonet.ParseCIDR
due to the leading exclamation mark negating the subnet: https://github.com/weaveworks/ignite/issues/393Here's a minimal reproduction:
Test Code
```go package main import ( "fmt" "github.com/coreos/go-iptables/iptables" ) // testActual is a forked version of ipt.StructuredStats() that prints debug info func testActual(ipt *iptables.IPTables) ([]iptables.Stat, error) { table := "nat" chain := "POSTROUTING" rawStats, err := ipt.Stats(table, chain) if err != nil { return nil, err } structStats := []iptables.Stat{} for _, rawStat := range rawStats { fmt.Println(rawStat[7], rawStat[8]) stat, err := ipt.ParseStat(rawStat) if err != nil { fmt.Println("rawStat: ", rawStat) fmt.Println("stat: ", stat) fmt.Println("err: ", err) return nil, err } structStats = append(structStats, stat) } return structStats, nil } func minimalReproduction(ipt *iptables.IPTables) (iptables.Stat, error) { return ipt.ParseStat( []string{ "1859", "112600", "MASQUERADE", "tcp", "--", "*", "*", "192.168.122.0/24", "!192.168.122.0/24", "masq ports: 1024-65535", }, ) } func main() { ipt, _ := iptables.NewWithProtocol(iptables.ProtocolIPv4) fmt.Println("minimalReproduction") fmt.Println(minimalReproduction(ipt)) fmt.Println() fmt.Println("testActual") fmt.Println(testActual(ipt)) } ```Test logs: