|
@@ -41,6 +41,7 @@ var (
|
|
natsQueue = flag.String("nats-queue", "requests", "The NATS queue name")
|
|
natsQueue = flag.String("nats-queue", "requests", "The NATS queue name")
|
|
natsCA = flag.String("nats-ca", "", "CA chain for NATS TLS")
|
|
natsCA = flag.String("nats-ca", "", "CA chain for NATS TLS")
|
|
reconnectToNatsAfter = flag.Duration("reconnect-to-nats-after", 0, "reconnect to nats after this long periodically")
|
|
reconnectToNatsAfter = flag.Duration("reconnect-to-nats-after", 0, "reconnect to nats after this long periodically")
|
|
|
|
+ resetLiveCapAfter = flag.Duration("rest-live-cap-after", 0, "reset the live capture setup after this amount of time")
|
|
sleepFor = flag.Duration("sleep", 0, "Sleep this long between sending data (only when replaying a file)")
|
|
sleepFor = flag.Duration("sleep", 0, "Sleep this long between sending data (only when replaying a file)")
|
|
requestsFile = flag.String("requests", "", "CSV file containing requests (IP and URL)")
|
|
requestsFile = flag.String("requests", "", "CSV file containing requests (IP and URL)")
|
|
protocol = flag.String("protocol", "http", "which protocol to parse: http or ajp13")
|
|
protocol = flag.String("protocol", "http", "which protocol to parse: http or ajp13")
|
|
@@ -103,6 +104,7 @@ type Config struct {
|
|
AccessWatchKey string
|
|
AccessWatchKey string
|
|
RPCAddress string
|
|
RPCAddress string
|
|
ReconnectToNatsAfter duration
|
|
ReconnectToNatsAfter duration
|
|
|
|
+ ResetLiveCaptureAfter duration
|
|
}
|
|
}
|
|
|
|
|
|
type duration struct {
|
|
type duration struct {
|
|
@@ -138,6 +140,7 @@ func (c Config) print() {
|
|
fmt.Printf("AccessWatchKey: %s\n", c.AccessWatchKey)
|
|
fmt.Printf("AccessWatchKey: %s\n", c.AccessWatchKey)
|
|
fmt.Printf("UseXForwardedAsSource: %t\n", c.UseXForwardedAsSource)
|
|
fmt.Printf("UseXForwardedAsSource: %t\n", c.UseXForwardedAsSource)
|
|
fmt.Printf("Protocol: %s\n", c.Protocol)
|
|
fmt.Printf("Protocol: %s\n", c.Protocol)
|
|
|
|
+ fmt.Printf("Reset Live Cap After: %s\n", c.ResetLiveCaptureAfter.String())
|
|
fmt.Printf("RPCAddress: %s\n", c.RPCAddress)
|
|
fmt.Printf("RPCAddress: %s\n", c.RPCAddress)
|
|
fmt.Printf("Quiet: %t\n", c.Quiet)
|
|
fmt.Printf("Quiet: %t\n", c.Quiet)
|
|
fmt.Printf("Trace: %t\n", c.Trace)
|
|
fmt.Printf("Trace: %t\n", c.Trace)
|
|
@@ -277,27 +280,108 @@ func connectToNATS() error {
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+type liveCap struct {
|
|
|
|
+ filter string
|
|
|
|
+ device string
|
|
|
|
+ promisc bool
|
|
|
|
+ snapshotLen int
|
|
|
|
+ handle *pcap.Handle
|
|
|
|
+ packetChan chan gopacket.Packet
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func newLiveCap(device string, filter string, snapshotLen int, promisc bool) (*liveCap, error) {
|
|
|
|
+ lc := liveCap{
|
|
|
|
+ filter: filter,
|
|
|
|
+ device: device,
|
|
|
|
+ promisc: promisc,
|
|
|
|
+ snapshotLen: snapshotLen,
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ err := lc.Setup()
|
|
|
|
+ if err != nil {
|
|
|
|
+ return nil, err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return &lc, nil
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (lc *liveCap) Setup() error {
|
|
|
|
+ if lc.packetChan != nil {
|
|
|
|
+ close(lc.packetChan)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if lc.handle != nil {
|
|
|
|
+ lc.handle.Close()
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // PCAP setup
|
|
|
|
+ //
|
|
|
|
+ handle, err := pcap.OpenLive(config.Interface, int32(config.SnapshotLen), config.Promiscuous, timeout)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+ // defer handle.Close()
|
|
|
|
+ lc.handle = handle
|
|
|
|
+
|
|
|
|
+ err = lc.handle.SetBPFFilter(config.Filter)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return err
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
|
|
|
|
+ lc.packetChan = packetSource.Packets()
|
|
|
|
+
|
|
|
|
+ return nil
|
|
|
|
+}
|
|
|
|
+
|
|
func liveCapture() {
|
|
func liveCapture() {
|
|
ipPriv = ip.NewIP()
|
|
ipPriv = ip.NewIP()
|
|
|
|
|
|
|
|
+ livecap, err := newLiveCap(config.Interface, config.Filter, config.SnapshotLen, config.Promiscuous)
|
|
|
|
+ if err != nil {
|
|
|
|
+ log.Fatal(err)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ closeChan := make(chan bool, 1)
|
|
|
|
+ go func(cc chan bool) {
|
|
|
|
+ for range time.Tick(1 * time.Minute) {
|
|
|
|
+ cc <- true
|
|
|
|
+ }
|
|
|
|
+ }(closeChan)
|
|
|
|
+
|
|
|
|
+ for {
|
|
|
|
+ if !config.Quiet {
|
|
|
|
+ log.Printf("reading incoming HTTP requests on %s %s\n", config.Interface, config.Filter)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ select {
|
|
|
|
+ case <-closeChan:
|
|
|
|
+ livecap.Setup()
|
|
|
|
+ case packet := <-livecap.packetChan:
|
|
|
|
+ go processPacket(packet)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func setupLiveCapture() (chan gopacket.Packet, error) {
|
|
// PCAP setup
|
|
// PCAP setup
|
|
//
|
|
//
|
|
handle, err := pcap.OpenLive(config.Interface, int32(config.SnapshotLen), config.Promiscuous, timeout)
|
|
handle, err := pcap.OpenLive(config.Interface, int32(config.SnapshotLen), config.Promiscuous, timeout)
|
|
if err != nil {
|
|
if err != nil {
|
|
- log.Fatal(err)
|
|
|
|
|
|
+ return nil, err
|
|
|
|
+ // log.Fatal(err)
|
|
}
|
|
}
|
|
defer handle.Close()
|
|
defer handle.Close()
|
|
|
|
|
|
err = handle.SetBPFFilter(config.Filter)
|
|
err = handle.SetBPFFilter(config.Filter)
|
|
if err != nil {
|
|
if err != nil {
|
|
- log.Fatal(err)
|
|
|
|
|
|
+ return nil, err
|
|
|
|
+ // log.Fatal(err)
|
|
}
|
|
}
|
|
|
|
|
|
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
|
|
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
|
|
|
|
|
|
- for packet := range packetSource.Packets() {
|
|
|
|
- go processPacket(packet)
|
|
|
|
- }
|
|
|
|
|
|
+ return packetSource.Packets(), nil
|
|
}
|
|
}
|
|
|
|
|
|
func writeLogToWatch(r *data.Request) {
|
|
func writeLogToWatch(r *data.Request) {
|
|
@@ -724,6 +808,7 @@ func loadConfig() {
|
|
config.AccessWatchKey = *accessWatchKey
|
|
config.AccessWatchKey = *accessWatchKey
|
|
config.RPCAddress = *rpcAddr
|
|
config.RPCAddress = *rpcAddr
|
|
config.ReconnectToNatsAfter.Duration = *reconnectToNatsAfter
|
|
config.ReconnectToNatsAfter.Duration = *reconnectToNatsAfter
|
|
|
|
+ config.ResetLiveCaptureAfter.Duration = *resetLiveCapAfter
|
|
|
|
|
|
if *configFile == "" {
|
|
if *configFile == "" {
|
|
return
|
|
return
|