diff --git a/build_static.sh b/build_static.sh index 8f24c24..7e8220a 100644 --- a/build_static.sh +++ b/build_static.sh @@ -1,5 +1,8 @@ #!/bin/sh +# Thanks for the idea to use musl! +# https://www.moiji-mobile.com/2017/10/15/static-binaries-for-go-with-docker/ + set -ex apk update diff --git a/config/config.go b/config/config.go index 4eff8f3..6db0869 100644 --- a/config/config.go +++ b/config/config.go @@ -21,6 +21,7 @@ type InterfacesConfig struct { Type string `config:"type"` ReadFile string `config:"read_file"` WriteFile string `config:"write_file"` + PortRange string `config:"port_range"` Snaplen int `config:"snaplen"` BufferSizeMb int `config:"buffer_size_mb"` ReadSpeed bool `config:"top_speed"` diff --git a/example/rtp_rtcp_sip.pcap b/example/rtp_rtcp_sip.pcap new file mode 100644 index 0000000..59dd1a2 Binary files /dev/null and b/example/rtp_rtcp_sip.pcap differ diff --git a/main.go b/main.go index e64f3bb..0d7585b 100644 --- a/main.go +++ b/main.go @@ -25,12 +25,13 @@ func parseFlags() { var keepLogFiles int flag.StringVar(&ifaceConfig.Device, "i", "", "Listen on interface") - flag.StringVar(&ifaceConfig.Type, "t", "pcap", "Capture types are [af_packet, pcap, file]") - flag.StringVar(&ifaceConfig.ReadFile, "rf", "", "Read packets from file. Please use -t file") - flag.StringVar(&ifaceConfig.WriteFile, "wf", "", "Write packets to file") - flag.IntVar(&ifaceConfig.Loop, "lp", 1, "Loop count over ReadFile") - flag.BoolVar(&ifaceConfig.ReadSpeed, "rs", false, "Maximum read speed. Doesn't use packet timestamps") - flag.IntVar(&ifaceConfig.Snaplen, "s", 32768, "Snap length") + flag.StringVar(&ifaceConfig.Type, "t", "pcap", "Capture types are [pcap, af_packet]") + flag.StringVar(&ifaceConfig.ReadFile, "rf", "", "Read packets from pcap file") + flag.StringVar(&ifaceConfig.WriteFile, "wf", "", "Write packets to pcap file") + flag.IntVar(&ifaceConfig.Loop, "lp", 1, "Loop count over ReadFile. Use 0 to loop forever") + flag.BoolVar(&ifaceConfig.ReadSpeed, "rs", false, "Maximum pcap read speed. Doesn't use packet timestamps") + flag.IntVar(&ifaceConfig.Snaplen, "s", 32768, "Snaplength") + flag.StringVar(&ifaceConfig.PortRange, "pr", "5060-5090", "Portrange to capture SIP") flag.IntVar(&ifaceConfig.BufferSizeMb, "b", 64, "Interface buffersize (MB)") flag.IntVar(&keepLogFiles, "kl", 4, "Rotate the number of log files") flag.StringVar(&logging.Level, "l", "info", "Log level [debug, info, warning, error]") @@ -38,10 +39,10 @@ func parseFlags() { flag.StringVar(&fileRotator.Path, "p", "./", "Log filepath") flag.StringVar(&fileRotator.Name, "n", "heplify.log", "Log filename") flag.Uint64Var(&rotateEveryKB, "r", 16384, "Log filesize (KB)") - flag.StringVar(&config.Cfg.Mode, "m", "SIP", "Capture modes [DNS, LOG, SIP, RTCP, TLS]") + flag.StringVar(&config.Cfg.Mode, "m", "SIP", "Capture modes [DNS, LOG, SIP, SIPRTCP, TLS]") flag.BoolVar(&config.Cfg.Dedup, "dd", true, "Deduplicate packets") - flag.StringVar(&config.Cfg.Filter, "fi", "", "Filter out interesting packets like SIP INVITES, Handshakes ...") - flag.StringVar(&config.Cfg.Discard, "di", "", "Discard uninteresting packets like SIP OPTIONS, HTTP Requests ...") + flag.StringVar(&config.Cfg.Filter, "fi", "", "Filter interesting packets") + flag.StringVar(&config.Cfg.Discard, "di", "", "Discard uninteresting packets") flag.StringVar(&config.Cfg.HepServer, "hs", "127.0.0.1:9060", "HEP Server address") flag.Parse() diff --git a/protos/rtcp.go b/protos/rtcp.go index 38880c4..30cdf28 100644 --- a/protos/rtcp.go +++ b/protos/rtcp.go @@ -183,7 +183,7 @@ func ParseRTCP(data []byte) ([]byte, error) { offset := 0 for dataLen > 0 { - if dataLen%4 != 0 || dataLen < 4 { + if dataLen < 4 || dataLen > 576 { return nil, fmt.Errorf("Fishy RTCP packet=%v length=%d", data, dataLen) } diff --git a/sniffer/sniffer.go b/sniffer/sniffer.go index 781d88e..501d064 100644 --- a/sniffer/sniffer.go +++ b/sniffer/sniffer.go @@ -95,11 +95,11 @@ func (sniffer *SnifferSetup) setFromConfig(cfg *config.InterfacesConfig) error { switch sniffer.mode { case "SIP": - sniffer.filter = "(greater 256 and portrange 5060-5090 or ip[6:2] & 0x1fff != 0) or (vlan and (greater 256 and portrange 5060-5090 or ip[6:2] & 0x1fff != 0))" + sniffer.filter = "(greater 256 and portrange " + sniffer.config.PortRange + " or ip[6:2] & 0x1fff != 0) or (vlan and (greater 256 and portrange " + sniffer.config.PortRange + " or ip[6:2] & 0x1fff != 0))" case "RTCP": sniffer.filter = "(ip and ip[6] & 0x2 = 0 and ip[6:2] & 0x1fff = 0 and udp and udp[8] & 0xc0 = 0x80 and udp[9] >= 0xc8 && udp[9] <= 0xcc)" case "SIPRTCP": - sniffer.filter = "(greater 256 and portrange 5060-5090 or ip[6:2] & 0x1fff != 0) or (ip and ip[6] & 0x2 = 0 and ip[6:2] & 0x1fff = 0 and udp and udp[8] & 0xc0 = 0x80 and udp[9] >= 0xc8 && udp[9] <= 0xcc)" + sniffer.filter = "(greater 256 and portrange " + sniffer.config.PortRange + " or ip[6:2] & 0x1fff != 0) or (ip and ip[6] & 0x2 = 0 and ip[6:2] & 0x1fff = 0 and udp and udp[8] & 0xc0 = 0x80 and udp[9] >= 0xc8 && udp[9] <= 0xcc)" case "LOG": sniffer.filter = "greater 128 and port 514" case "DNS": @@ -108,7 +108,7 @@ func (sniffer *SnifferSetup) setFromConfig(cfg *config.InterfacesConfig) error { sniffer.filter = "tcp and port 443 and tcp[(((tcp[12:1] & 0xf0) >> 2)):1] = 0x16 and ((tcp[(((tcp[12:1] & 0xf0) >> 2)+5):1] = 0x01) or (tcp[(((tcp[12:1] & 0xf0) >> 2)+5):1] = 0x02))" default: sniffer.mode = "SIP" - sniffer.filter = "(greater 256 and portrange 5060-5090 or ip[6:2] & 0x1fff != 0) or (vlan and (greater 256 and portrange 5060-5090 or ip[6:2] & 0x1fff != 0))" + sniffer.filter = "(greater 256 and portrange " + sniffer.config.PortRange + " or ip[6:2] & 0x1fff != 0) or (vlan and (greater 256 and portrange " + sniffer.config.PortRange + " or ip[6:2] & 0x1fff != 0))" } logp.Info("Sniffer type: [%s] device: [%s] mode: [%s]", sniffer.config.Type, sniffer.config.Device, sniffer.mode) @@ -167,13 +167,17 @@ func (sniffer *SnifferSetup) Init(testMode bool, mode string, factory WorkerFact sniffer.mode = mode if interfaces.Device == "" && interfaces.ReadFile == "" { - fmt.Printf("\nPlease use one of the following devices:\n\n") + fmt.Printf("Please use one of the following devices:\n\n") _, err := ListDeviceNames(false, false) if err != nil { return fmt.Errorf("getting devices list: %v", err) } fmt.Println("") os.Exit(1) + } else if interfaces.Device == "any" && interfaces.Type == "pcap" { + fmt.Println("Interface 'any' and capture type 'pcap' will break VLAN capture!") + fmt.Println("To listen on interface 'any' please use 'af_packet' capture type!") + os.Exit(1) } if !testMode {