forked from x-way/iptables-tracer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parse.go
87 lines (79 loc) · 3.12 KB
/
parse.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package main
import (
"fmt"
"log"
"regexp"
"strconv"
)
func extendIptablesPolicy(lines []string, traceID int, traceFilter string, fwMark int, packetLimit int, traceRules bool, nflogGroup int) ([]string, map[int]iptablesRule, int) {
var newIptablesConfig []string
maxLength := 0
ruleMap := make(map[int]iptablesRule)
chainMap := make(map[string][]string)
chainRe := regexp.MustCompile(`^:(\S+)`)
tableRe := regexp.MustCompile(`^\*(\S+)`)
ruleRe := regexp.MustCompile(`^-[AI]\s+(\S+)\s+(.*)$`)
commitRe := regexp.MustCompile(`^COMMIT`)
markFilter := ""
if fwMark != 0 {
markFilter = fmt.Sprintf("-m mark --mark 0x%x/0x%x", fwMark, fwMark)
}
table := ""
ruleIndex := 0
for _, line := range lines {
if res := chainRe.FindStringSubmatch(line); res != nil {
if table == "" {
log.Fatal("Error: found chain definition before initial table definition")
}
chainMap[table] = append(chainMap[table], res[1])
if len(res[1]) > maxLength {
maxLength = len(res[1])
}
}
if res := commitRe.FindStringSubmatch(line); res != nil {
// we are at the end of a table, add aritificial rules for all chains in this table
for _, chain := range chainMap[table] {
ruleMap[ruleIndex] = iptablesRule{Table: table, Chain: chain, ChainEntry: true}
traceRule := fmt.Sprintf("-I %s %s %s -j NFLOG --nflog-prefix \"iptr:%d:%d\" --nflog-group %d", chain, traceFilter, markFilter, traceID, ruleIndex, nflogGroup)
ruleIndex++
newIptablesConfig = append(newIptablesConfig, traceRule)
if table == "raw" && chain == "PREROUTING" && packetLimit != 0 {
newIptablesConfig = append(newIptablesConfig, fmt.Sprintf("-I %s %s -m comment --comment \"iptr:%d:limit\" -m limit --limit %d/minute --limit-burst 1 -j MARK --set-xmark 0x%x/0x%x", chain, traceFilter, traceID, packetLimit, fwMark, fwMark))
}
}
}
if res := tableRe.FindStringSubmatch(line); res != nil {
table = res[1]
}
if res := ruleRe.FindStringSubmatch(line); res != nil && traceRules {
if table == "" {
log.Fatal("Error: found rule definition before initial table definition")
}
ruleMap[ruleIndex] = iptablesRule{Table: table, Chain: res[1], Rule: res[2]}
traceRule := fmt.Sprintf("-A %s %s %s -j NFLOG --nflog-prefix \"iptr:%d:%d\" --nflog-group %d", res[1], traceFilter, markFilter, traceID, ruleIndex, nflogGroup)
ruleIndex++
newIptablesConfig = append(newIptablesConfig, traceRule)
}
newIptablesConfig = append(newIptablesConfig, line)
}
return newIptablesConfig, ruleMap, maxLength
}
func clearIptablesPolicy(policy []string, cleanupID int) []string {
var newIptablesConfig []string
iptrRe := regexp.MustCompile(`\s+--nflog-prefix\s+"iptr:(\d+):\d+"`)
limitRe := regexp.MustCompile(`\s+--comment\s+"iptr:(\d+):limit"`)
for _, line := range policy {
if res := iptrRe.FindStringSubmatch(line); res != nil {
if id, _ := strconv.Atoi(res[1]); id == cleanupID || cleanupID == 0 {
continue
}
}
if res := limitRe.FindStringSubmatch(line); res != nil {
if id, _ := strconv.Atoi(res[1]); id == cleanupID || cleanupID == 0 {
continue
}
}
newIptablesConfig = append(newIptablesConfig, line)
}
return newIptablesConfig
}