Skip to content

Commit

Permalink
Add AF_PACKET support
Browse files Browse the repository at this point in the history
NOTE "interesting" behavior accompanies using AF_PACKET support:
 - you may not be able scan properly on loopback interface.
 - you must the various types of segment offloading
  • Loading branch information
david415 committed May 29, 2015
1 parent a492772 commit 1c345f3
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 15 deletions.
2 changes: 2 additions & 0 deletions cmd/honeyBadger/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ continuing to stream connection data. If zero or less, this is infinite`)
maxPcapLogSize = flag.Int("max_pcap_log_size", 1, "maximum pcap size per rotation in megabytes")
maxNumPcapRotations = flag.Int("max_pcap_rotations", 10, "maximum number of pcap rotations per connection")
archiveDir = flag.String("archive_dir", "", "archive directory for storing attack logs and related pcap files")
useAfPacket = flag.Bool("afpacket", true, "Use AF_PACKET")
)
flag.Parse()

Expand Down Expand Up @@ -103,6 +104,7 @@ continuing to stream connection data. If zero or less, this is infinite`)
WireDuration: wireDuration,
Snaplen: int32(*snaplen),
Filter: *filter,
UseAfPacket: *useAfPacket,
}

connectionFactory := &HoneyBadger.DefaultConnFactory{}
Expand Down
47 changes: 32 additions & 15 deletions sniffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"time"

"github.com/google/gopacket"
"github.com/google/gopacket/afpacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"

Expand All @@ -41,6 +42,7 @@ type SnifferOptions struct {
Snaplen int32
Dispatcher PacketDispatcher
Supervisor types.Supervisor
UseAfPacket bool
}

// Sniffer sets up the connection pool and is an abstraction layer for dealing
Expand All @@ -50,7 +52,9 @@ type Sniffer struct {
stopCaptureChan chan bool
decodePacketChan chan TimedRawPacket
stopDecodeChan chan bool
handle *pcap.Handle
packetDataSource gopacket.PacketDataSource
pcapHandle *pcap.Handle
tpacketHandle *afpacket.TPacket
supervisor types.Supervisor
}

Expand All @@ -74,7 +78,7 @@ func (i *Sniffer) GetStartedChan() chan bool {

// Start... starts the TCP attack inquisition!
func (i *Sniffer) Start() {
if i.handle == nil {
if i.pcapHandle == nil && i.tpacketHandle == nil {
i.setupHandle()
}
go i.capturePackets()
Expand All @@ -84,23 +88,36 @@ func (i *Sniffer) Start() {
func (i *Sniffer) Stop() {
i.stopCaptureChan <- true
i.stopDecodeChan <- true
i.handle.Close()
if i.pcapHandle != nil {
i.pcapHandle.Close()
} else {
i.tpacketHandle.Close()
}
}

func (i *Sniffer) setupHandle() {
var err error
if i.options.Filename != "" {
if i.options.UseAfPacket { // sniff AF_PACKET interface
log.Printf("Starting AF_PACKET capture on interface %s", i.options.Interface)
if i.tpacketHandle, err = afpacket.NewTPacket(afpacket.OptInterface(i.options.Interface)); err != nil {
log.Fatal(err)
panic(err)
}
i.packetDataSource = i.tpacketHandle
} else if i.options.Filename != "" { // sniff pcap file
log.Printf("Reading from pcap file %q", i.options.Filename)
i.handle, err = pcap.OpenOffline(i.options.Filename)
} else {
log.Printf("Starting capture on interface %q", i.options.Interface)
i.handle, err = pcap.OpenLive(i.options.Interface, i.options.Snaplen, true, i.options.WireDuration)
}
if err != nil {
log.Fatal(err)
}
if err = i.handle.SetBPFFilter(i.options.Filter); err != nil {
log.Fatal(err)
i.pcapHandle, err = pcap.OpenOffline(i.options.Filename)
i.packetDataSource = i.pcapHandle
} else { // sniff pcap wire interface
log.Printf("Starting pcap capture on interface %q", i.options.Interface)
i.pcapHandle, err = pcap.OpenLive(i.options.Interface, i.options.Snaplen, true, i.options.WireDuration)
if err != nil {
log.Fatal(err)
}
if err = i.pcapHandle.SetBPFFilter(i.options.Filter); err != nil {
log.Fatal(err)
}
i.packetDataSource = i.pcapHandle
}
}

Expand All @@ -110,7 +127,7 @@ func (i *Sniffer) capturePackets() {
// XXX does this need a shutdown code path?
go func() {
for {
rawPacket, captureInfo, err := i.handle.ReadPacketData()
rawPacket, captureInfo, err := i.packetDataSource.ReadPacketData()
if err == io.EOF {
log.Print("ReadPacketData got EOF\n")
i.Stop()
Expand Down

0 comments on commit 1c345f3

Please sign in to comment.