diff --git a/capture/capture.go b/capture/capture.go index 3cc48103c..7e94ab2e4 100644 --- a/capture/capture.go +++ b/capture/capture.go @@ -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) @@ -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 @@ -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)) @@ -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)) @@ -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 { diff --git a/input_raw.go b/input_raw.go index 7d73affee..aa6c7c3c1 100644 --- a/input_raw.go +++ b/input_raw.go @@ -6,6 +6,7 @@ import ( "log" "net" "strconv" + "strings" "sync" "time" @@ -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 @@ -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) @@ -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) } @@ -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