Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

capture list of ports in a single listener #935

Merged
merged 2 commits into from
Jun 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions capture/capture.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ type Listener struct {
Reading chan bool // this channel is closed when the listener has started reading packets
PcapOptions
Engine EngineType
port uint16 // src or/and dst port
ports []uint16 // src or/and dst ports
trackResponse bool

host string // pcap file name or interface (name, hardware addr, index or ip address)
Expand Down Expand Up @@ -99,15 +99,15 @@ func (eng *EngineType) String() (e string) {
// NewListener creates and initialize a new Listener. if transport or/and engine are invalid/unsupported
// is "tcp" and "pcap", are assumed. l.Engine and l.Transport can help to get the values used.
// if there is an error it will be associated with getting network interfaces
func NewListener(host string, port uint16, transport string, engine EngineType, trackResponse bool) (l *Listener, err error) {
func NewListener(host string, ports []uint16, transport string, engine EngineType, trackResponse bool) (l *Listener, err error) {
l = &Listener{}

l.host = host
if l.host == "localhost" {
l.host = "127.0.0.1"
}

l.port = port

l.Transport = "tcp"
if transport != "" {
l.Transport = transport
Expand Down Expand Up @@ -181,7 +181,7 @@ func (l *Listener) Filter(ifi pcap.Interface) (filter string) {
hosts = interfaceAddresses(ifi)
}

filter = portsFilter(l.Transport, "dst", l.port)
filter = portsFilter(l.Transport, "dst", l.ports)

if len(hosts) != 0 {
filter = fmt.Sprintf("((%s) and (%s))", filter, hostsFilter("dst", hosts))
Expand All @@ -190,7 +190,7 @@ func (l *Listener) Filter(ifi pcap.Interface) (filter string) {
}

if l.trackResponse {
responseFilter := portsFilter(l.Transport, "src", l.port)
responseFilter := portsFilter(l.Transport, "src", l.ports)

if len(hosts) != 0 {
responseFilter = fmt.Sprintf("((%s) and (%s))", responseFilter, hostsFilter("src", hosts))
Expand Down Expand Up @@ -501,12 +501,16 @@ func listenAll(addr string) bool {
return false
}

func portsFilter(transport string, direction string, port uint16) string {
if port == 0 {
func portsFilter(transport string, direction string, ports []uint16) string {
if len(ports) == 0 || ports[0] == 0 {
return fmt.Sprintf("%s %s portrange 0-%d", transport, direction, 1<<16-1)
}

return fmt.Sprintf("%s %s port %d", transport, direction, port)
var filters []string
for _, port := range ports {
filters = append(filters, fmt.Sprintf("%s %s port %d", transport, direction, port))
}
return strings.Join(filters, " or ")
}

func hostsFilter(direction string, hosts []string) string {
Expand Down
33 changes: 20 additions & 13 deletions input_raw.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"log"
"net"
"strconv"
"strings"
"sync"
"time"

Expand Down Expand Up @@ -61,7 +62,7 @@ type RAWInputConfig struct {
Stats bool `json:"input-raw-stats"`
quit chan bool // Channel used only to indicate goroutine should shutdown
host string
port uint16
ports []uint16
}

// RAWInput used for intercepting traffic for given address
Expand All @@ -81,22 +82,28 @@ func NewRAWInput(address string, config RAWInputConfig) (i *RAWInput) {
i.RAWInputConfig = config
i.message = make(chan *tcp.Message, 10000)
i.quit = make(chan bool)
var host, _port string
var err error
var port int
host, _port, err = net.SplitHostPort(address)

host, _ports, err := net.SplitHostPort(address)
if err != nil {
log.Fatalf("input-raw: error while parsing address: %s", err)
}
if _port != "" {
port, err = strconv.Atoi(_port)
}

if err != nil {
log.Fatalf("parsing port error: %v", err)
var ports []uint16
if _ports != "" {
portsStr := strings.Split(_ports, ",")

for _, portStr := range portsStr {
port, err := strconv.Atoi(strings.TrimSpace(portStr))
if err != nil {
log.Fatalf("parsing port error: %v", err)
}
ports = append(ports, uint16(port))

}
}

i.host = host
i.port = uint16(port)
i.ports = ports

i.listen(address)

Expand Down Expand Up @@ -141,7 +148,7 @@ func (i *RAWInput) PluginRead() (*Message, error) {

func (i *RAWInput) listen(address string) {
var err error
i.listener, err = capture.NewListener(i.host, i.port, "", i.Engine, i.TrackResponse)
i.listener, err = capture.NewListener(i.host, i.ports, "", i.Engine, i.TrackResponse)
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -172,7 +179,7 @@ func (i *RAWInput) messageEmitter(m *tcp.Message) {
}

func (i *RAWInput) String() string {
return fmt.Sprintf("Intercepting traffic from: %s:%d", i.host, i.port)
return fmt.Sprintf("Intercepting traffic from: %s:%s", i.host, strings.Join(strings.Fields(fmt.Sprint(i.ports)), ","))
}

// GetStats returns the stats so far and reset the stats
Expand Down