Skip to content

Commit

Permalink
Merge pull request #17 from MEschenbacher/icmp-type
Browse files Browse the repository at this point in the history
Add match extension for icmp and icmp6
  • Loading branch information
leonnicolas authored Mar 31, 2024
2 parents fd02469 + 4bd1313 commit 7eaddee
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 0 deletions.
106 changes: 106 additions & 0 deletions match_modules.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ func (p *Parser) parseMatch(ms *[]Match) (state, error) {
s, err = p.parseStatistic(&m.Flags)
case "multiport":
s, err = p.parseMultiport(&m.Flags)
case "icmp":
s, err = p.parseIcmp(&m.Flags)
case "icmp6":
s, err = p.parseIcmp6(&m.Flags)
default:
if _, ok := matchModules[lit]; ok {
return sError, fmt.Errorf("match modules %q is not implemented", lit)
Expand Down Expand Up @@ -529,3 +533,105 @@ func (p *Parser) parseComment(f *map[string]Flag) (state, error) {
}
return sStart, nil
}

func (p *Parser) parseIcmp(f *map[string]Flag) (state, error) {
s := sStart
for tok, lit := p.scanIgnoreWhitespace(); tok != EOF; tok, lit = p.scanIgnoreWhitespace() {
for nextValue := false; !nextValue; {
nextValue = true
switch s {
case sStart:
switch tok {
case NOT:
s = sINotF
case FLAG:
s = sIF
nextValue = false
default:
return sError, fmt.Errorf("unexpected token %q, expected flag, or \"!\"", lit)
}
case sINotF:
switch {
case lit == "--icmp-type":
_, lit := p.scanIgnoreWhitespace()
(*f)["icmp-type"] = Flag{
Not: true,
Values: []string{lit},
}
s = sStart
default:
p.unscan(1)
return sNot, nil
}
case sIF:
switch {
case lit == "--icmp-type":
_, lit := p.scanIgnoreWhitespace()
(*f)["icmp-type"] = Flag{
Values: []string{lit},
}
s = sStart
default:
// The end of the match statement is reached.
p.unscan(1)
return sStart, nil
}

default:
return sStart, errors.New("unexpected error parsing match extension")
}
}
}
return sStart, nil
}

func (p *Parser) parseIcmp6(f *map[string]Flag) (state, error) {
s := sStart
for tok, lit := p.scanIgnoreWhitespace(); tok != EOF; tok, lit = p.scanIgnoreWhitespace() {
for nextValue := false; !nextValue; {
nextValue = true
switch s {
case sStart:
switch tok {
case NOT:
s = sINotF
case FLAG:
s = sIF
nextValue = false
default:
return sError, fmt.Errorf("unexpected token %q, expected flag, or \"!\"", lit)
}
case sINotF:
switch {
case lit == "--icmpv6-type":
_, lit := p.scanIgnoreWhitespace()
(*f)["icmpv6-type"] = Flag{
Not: true,
Values: []string{lit},
}
s = sStart
default:
p.unscan(1)
return sNot, nil
}
case sIF:
switch {
case lit == "--icmpv6-type":
_, lit := p.scanIgnoreWhitespace()
(*f)["icmpv6-type"] = Flag{
Values: []string{lit},
}
s = sStart
default:
// The end of the match statement is reached.
p.unscan(1)
return sStart, nil
}

default:
return sStart, errors.New("unexpected error parsing match extension")
}
}
}
return sStart, nil
}
40 changes: 40 additions & 0 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,46 @@ func TestParser_Parse(t *testing.T) {
},
err: nil,
},
{
name: "parse rule with icmp type",
s: "-A foo -p icmp -m icmp --icmp-type 11",
r: Rule{
Chain: "foo",
Protocol: &StringPair{
Not: false,
Value: "icmp",
},
Matches: []Match{
{
Type: "icmp",
Flags: map[string]Flag{
"icmp-type": {Values: []string{"11"}},
},
},
},
},
err: nil,
},
{
name: "parse rule with icmp type",
s: "-A foo -p ipv6-icmp -m icmp6 --icmpv6-type 11",
r: Rule{
Chain: "foo",
Protocol: &StringPair{
Not: false,
Value: "ipv6-icmp",
},
Matches: []Match{
{
Type: "icmp6",
Flags: map[string]Flag{
"icmpv6-type": {Values: []string{"11"}},
},
},
},
},
err: nil,
},
{
name: "parse rule with match expression tcp and a lot of flags and overwriting",
s: "-A foo -m tcp --tcp-flags SYN,FIN ACK --sport 1010 ! --dport=1000:1010 --syn! --syn ! --tcp-option 1 ! -f ",
Expand Down

0 comments on commit 7eaddee

Please sign in to comment.