Files
kubeshark/tap/source/handle_pcap.go
M. Mert Yıldıran e52ba1f05d Add AF_PACKET support (#1052)
* Add `AF_PACKET` support

* Update `.gitignore`

* Support both `libpcap` and `AF_PACKET` at the same time

* Fix linter errors

* Fix a bug that introduced while fixing a linter error

* Revert the changes related to `MaxBufferedPages` prefixed consts

* #run_acceptance_tests

* #run_acceptance_tests

* Revert channel buffer size #run_acceptance_tests

* Revert "Revert channel buffer size #run_acceptance_tests"

This reverts commit e62c3844cd.

* Increase `cy.wait` from `500` to `1000` #run_acceptance_tests

* Fix the `pcapHandle` handle

* Revert "Increase `cy.wait` from `500` to `1000` #run_acceptance_tests"

This reverts commit 938c550e72.

* #run_acceptance_tests

* Handle the merge conflicts

* Add `AF_XDP` support

* Implement `Close()` of `AF_XDP` and fix linter errors

* Fix `NewIPProtoProgram` function and internet protocol number

* Pipe the packet stream from every network interface using `*pcapgo.NgReader` and `*pcapgo.NgWriter`

Implement `SetDecoder` and `SetBPF` methods.

* Fix `NewNgReader` call

* Implement `Stats` method

* Rebroadcast to the XDP socket

* Add `-packet-capture` flag and make `AF_PACKET`, `AF_XDP` optional

* #run_acceptance_tests

* Fix `newAfXdpHandle` method

* #run_acceptance_tests

* Update tap/xdp/ipproto.c

Co-authored-by: Nimrod Gilboa Markevich <59927337+nimrod-up9@users.noreply.github.com>

* Update tap/xdp/ipproto.c

Co-authored-by: Nimrod Gilboa Markevich <59927337+nimrod-up9@users.noreply.github.com>

* Update tap/xdp/ipproto.c

Co-authored-by: Nimrod Gilboa Markevich <59927337+nimrod-up9@users.noreply.github.com>

* Fix several issues

* Update tap/xdp/ipproto.c

Co-authored-by: Nimrod Gilboa Markevich <59927337+nimrod-up9@users.noreply.github.com>

* Fix `ipproto.c`

* Remove `AF_XDP`

* Comment on frameSize

Co-authored-by: Nimrod Gilboa Markevich <59927337+nimrod-up9@users.noreply.github.com>
2022-08-08 13:48:19 +03:00

98 lines
2.6 KiB
Go

package source
import (
"fmt"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
type pcapHandle struct {
source *gopacket.PacketSource
capture *pcap.Handle
}
func (h *pcapHandle) NextPacket() (packet gopacket.Packet, err error) {
return h.source.NextPacket()
}
func (h *pcapHandle) SetDecoder(decoder gopacket.Decoder, lazy bool, noCopy bool) {
h.source = gopacket.NewPacketSource(h.capture, decoder)
h.source.Lazy = lazy
h.source.NoCopy = noCopy
}
func (h *pcapHandle) SetBPF(expr string) (err error) {
return h.capture.SetBPFFilter(expr)
}
func (h *pcapHandle) LinkType() layers.LinkType {
return h.capture.LinkType()
}
func (h *pcapHandle) Stats() (packetsReceived uint, packetsDropped uint, err error) {
var stats *pcap.Stats
stats, err = h.capture.Stats()
packetsReceived = uint(stats.PacketsReceived)
packetsDropped = uint(stats.PacketsDropped)
return
}
func (h *pcapHandle) Close() (err error) {
h.capture.Close()
return
}
func newPcapHandle(filename string, device string, snaplen int, promisc bool, tstype string) (handle Handle, err error) {
var capture *pcap.Handle
if filename != "" {
if capture, err = pcap.OpenOffline(filename); err != nil {
err = fmt.Errorf("PCAP OpenOffline error: %v", err)
return
}
} else {
// This is a little complicated because we want to allow all possible options
// for creating the packet capture handle... instead of all this you can
// just call pcap.OpenLive if you want a simple handle.
var inactive *pcap.InactiveHandle
inactive, err = pcap.NewInactiveHandle(device)
if err != nil {
err = fmt.Errorf("could not create: %v", err)
return
}
defer inactive.CleanUp()
if err = inactive.SetSnapLen(snaplen); err != nil {
err = fmt.Errorf("could not set snap length: %v", err)
return
} else if err = inactive.SetPromisc(promisc); err != nil {
err = fmt.Errorf("could not set promisc mode: %v", err)
return
} else if err = inactive.SetTimeout(time.Second); err != nil {
err = fmt.Errorf("could not set timeout: %v", err)
return
}
if tstype != "" {
var t pcap.TimestampSource
if t, err = pcap.TimestampSourceFromString(tstype); err != nil {
err = fmt.Errorf("supported timestamp types: %v", inactive.SupportedTimestamps())
return
} else if err = inactive.SetTimestampSource(t); err != nil {
err = fmt.Errorf("supported timestamp types: %v", inactive.SupportedTimestamps())
return
}
}
if capture, err = inactive.Activate(); err != nil {
err = fmt.Errorf("PCAP Activate error: %v", err)
return
}
}
handle = &pcapHandle{
capture: capture,
}
return
}