2020-02-05 22:16:58 +00:00
|
|
|
// Copyright (c) 2020 Tailscale Inc & AUTHORS All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package filter
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
2020-02-29 03:27:17 +00:00
|
|
|
|
2020-11-10 04:12:21 +00:00
|
|
|
"inet.af/netaddr"
|
2020-02-05 22:16:58 +00:00
|
|
|
)
|
|
|
|
|
2020-11-10 04:12:21 +00:00
|
|
|
// PortRange is a range of TCP and UDP ports.
|
2020-02-05 22:16:58 +00:00
|
|
|
type PortRange struct {
|
2020-11-10 04:12:21 +00:00
|
|
|
First, Last uint16 // inclusive
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
|
2020-11-10 04:12:21 +00:00
|
|
|
// PortRangeAny represents all TCP and UDP ports.
|
2020-02-05 22:16:58 +00:00
|
|
|
var PortRangeAny = PortRange{0, 65535}
|
|
|
|
|
|
|
|
func (pr PortRange) String() string {
|
|
|
|
if pr.First == 0 && pr.Last == 65535 {
|
|
|
|
return "*"
|
|
|
|
} else if pr.First == pr.Last {
|
|
|
|
return fmt.Sprintf("%d", pr.First)
|
|
|
|
} else {
|
|
|
|
return fmt.Sprintf("%d-%d", pr.First, pr.Last)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-10 04:12:21 +00:00
|
|
|
func (pr PortRange) contains(port uint16) bool {
|
|
|
|
return port >= pr.First && port <= pr.Last
|
|
|
|
}
|
|
|
|
|
|
|
|
// NetAny matches all IP addresses.
|
|
|
|
// TODO: add ipv6.
|
|
|
|
var NetAny = []netaddr.IPPrefix{{IP: netaddr.IPv4(0, 0, 0, 0), Bits: 0}}
|
|
|
|
|
|
|
|
// NetPortRange combines an IP address prefix and PortRange.
|
2020-04-30 05:49:17 +00:00
|
|
|
type NetPortRange struct {
|
2020-11-10 04:12:21 +00:00
|
|
|
Net netaddr.IPPrefix
|
2020-02-05 22:16:58 +00:00
|
|
|
Ports PortRange
|
|
|
|
}
|
|
|
|
|
2020-11-10 04:12:21 +00:00
|
|
|
func (npr NetPortRange) String() string {
|
|
|
|
return fmt.Sprintf("%v:%v", npr.Net, npr.Ports)
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
|
2020-11-10 04:12:21 +00:00
|
|
|
var NetPortRangeAny = []NetPortRange{{Net: NetAny[0], Ports: PortRangeAny}}
|
|
|
|
|
|
|
|
// Match matches packets from any IP address in Srcs to any ip:port in
|
|
|
|
// Dsts.
|
2020-02-05 22:16:58 +00:00
|
|
|
type Match struct {
|
2020-04-30 05:49:17 +00:00
|
|
|
Dsts []NetPortRange
|
2020-11-10 04:12:21 +00:00
|
|
|
Srcs []netaddr.IPPrefix
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (m Match) String() string {
|
|
|
|
srcs := []string{}
|
2020-04-30 05:49:17 +00:00
|
|
|
for _, src := range m.Srcs {
|
|
|
|
srcs = append(srcs, src.String())
|
2020-02-05 22:16:58 +00:00
|
|
|
}
|
|
|
|
dsts := []string{}
|
2020-04-30 05:49:17 +00:00
|
|
|
for _, dst := range m.Dsts {
|
2020-02-05 22:16:58 +00:00
|
|
|
dsts = append(dsts, dst.String())
|
|
|
|
}
|
|
|
|
|
|
|
|
var ss, ds string
|
|
|
|
if len(srcs) == 1 {
|
|
|
|
ss = srcs[0]
|
|
|
|
} else {
|
|
|
|
ss = "[" + strings.Join(srcs, ",") + "]"
|
|
|
|
}
|
|
|
|
if len(dsts) == 1 {
|
|
|
|
ds = dsts[0]
|
|
|
|
} else {
|
|
|
|
ds = "[" + strings.Join(dsts, ",") + "]"
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("%v=>%v", ss, ds)
|
|
|
|
}
|
|
|
|
|
2020-11-10 04:12:21 +00:00
|
|
|
// Matches is a list of packet matchers.
|
2020-02-05 22:16:58 +00:00
|
|
|
type Matches []Match
|