Skip to content

Commit

Permalink
pcapinput: split to multiple .go files
Browse files Browse the repository at this point in the history
  • Loading branch information
yoursunny committed Oct 31, 2023
1 parent 078c1d2 commit d4c3fae
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 224 deletions.
10 changes: 5 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ go 1.21

require (
github.com/google/gopacket v1.1.19
github.com/klauspost/compress v1.16.7
github.com/klauspost/compress v1.17.2
github.com/urfave/cli/v2 v2.25.7
github.com/usnistgov/ndn-dpdk v0.0.0-20230816175739-b1080e8c296b
github.com/usnistgov/ndn-dpdk v0.0.0-20231012213844-da654608dfe8
github.com/zyedidia/generic v1.2.1
go4.org/netipx v0.0.0-20230824141953-6213f710f925
)
Expand All @@ -15,7 +15,7 @@ require (
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb // indirect
golang.org/x/net v0.12.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/sys v0.13.0 // indirect
)
20 changes: 10 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
Expand All @@ -18,8 +18,8 @@ github.com/tul/emission v0.0.0-20180606124623-7d2aae804ca2 h1:iPOayn1rRdG1AB2T/W
github.com/tul/emission v0.0.0-20180606124623-7d2aae804ca2/go.mod h1:ANCVehq/ebSfxkRMtL7xwd64CRO6GXnf42j06yeC1JA=
github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
github.com/usnistgov/ndn-dpdk v0.0.0-20230816175739-b1080e8c296b h1:Veg94qxmsWDbzigkXj922o9UGqQut9HGkjCSb3pFQjI=
github.com/usnistgov/ndn-dpdk v0.0.0-20230816175739-b1080e8c296b/go.mod h1:ZOLNXJ9UcqKxlGJv+jbgRC+5LjD8OgzBL09vT0xl0Qw=
github.com/usnistgov/ndn-dpdk v0.0.0-20231012213844-da654608dfe8 h1:3NVtfRdAOUsWgxxRY5Q3MSeCzjmIoXNRZs0wBzaXyAI=
github.com/usnistgov/ndn-dpdk v0.0.0-20231012213844-da654608dfe8/go.mod h1:INUM3+d5d3gLSaXSENzH5Kmu03ROmyKGbCBPlFo6JCM=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
github.com/zyedidia/generic v1.2.1 h1:Zv5KS/N2m0XZZiuLS82qheRG4X1o5gsWreGb0hR7XDc=
Expand All @@ -28,19 +28,19 @@ go4.org/netipx v0.0.0-20230824141953-6213f710f925 h1:eeQDDVKFkx0g4Hyy8pHgmZaK0Eq
go4.org/netipx v0.0.0-20230824141953-6213f710f925/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb h1:mIKbk8weKhSeLH2GmUTrvx8CjkyJmnU1wFmg59CUjFA=
golang.org/x/exp v0.0.0-20230811145659-89c5cff77bcb/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
Expand Down
90 changes: 90 additions & 0 deletions pcapinput/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package pcapinput

import (
"compress/gzip"
"errors"
"io"
"net"
"os"
"path/filepath"

"github.com/google/gopacket"
"github.com/google/gopacket/pcapgo"
"github.com/klauspost/compress/zstd"
"github.com/usnistgov/ndn-dpdk/core/macaddr"
)

type fileHandle struct {
local net.HardwareAddr
file *os.File
decompress io.ReadCloser
reader *pcapgo.Reader
ngr *pcapgo.NgReader
}

func (hdl *fileHandle) open(filename string) (e error) {
if hdl.file, e = os.Open(filename); e != nil {
return e
}
pcapStream := io.Reader(hdl.file)

ext := filepath.Ext(filename)
switch ext {
case ".gz":
if hdl.decompress, e = gzip.NewReader(hdl.file); e != nil {
return e
}
pcapStream = hdl.decompress
case ".zst":
if pcapStream, e = zstd.NewReader(hdl.file); e != nil {
return e
}
hdl.decompress = io.NopCloser(pcapStream)
}

if hdl.decompress != nil {
filename = filename[:len(filename)-len(ext)]
ext = filepath.Ext(filename)
}

switch ext {
case ".pcap":
hdl.reader, e = pcapgo.NewReader(pcapStream)
case ".pcapng":
hdl.ngr, e = pcapgo.NewNgReader(pcapStream, pcapgo.NgReaderOptions{SkipUnknownVersion: true})
default:
return errors.New("unknown file extension")
}
return e
}

func (hdl *fileHandle) Name() string {
if hdl.ngr != nil {
if intf, e := hdl.ngr.Interface(0); e == nil {
return intf.Name
}
}
return hdl.file.Name()
}

func (hdl *fileHandle) IsLocal(mac net.HardwareAddr) bool {
return macaddr.Equal(hdl.local, mac)
}

func (hdl *fileHandle) ZeroCopyReadPacketData() (wire []byte, ci gopacket.CaptureInfo, e error) {
if hdl.reader != nil {
return hdl.reader.ZeroCopyReadPacketData()
}
return hdl.ngr.ZeroCopyReadPacketData()
}

func (hdl *fileHandle) Close() error {
errs := []error{}
if hdl.decompress != nil {
errs = append(errs, hdl.decompress.Close())
}
if hdl.file != nil {
errs = append(errs, hdl.file.Close())
}
return errors.Join(errs...)
}
49 changes: 49 additions & 0 deletions pcapinput/handle.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Package pcapinput opens GoPacket input handle.
package pcapinput

import (
"errors"
"io"
"net"

"github.com/google/gopacket"
"github.com/usnistgov/ndn-dpdk/core/macaddr"
)

// Handle represents a pcap input handle.
type Handle interface {
gopacket.ZeroCopyPacketDataSource
io.Closer
Name() string
IsLocal(mac net.HardwareAddr) bool
}

// Open creates a pcap input handle.
//
// ifname: network interface name.
// filename: input filename.
// local: local MAC address.
func Open(ifname, filename, local string) (handle Handle, e error) {
if (ifname == "") == (filename == "") {
return nil, errors.New("exactly one of ifname and filename+local should be specified")
}

if ifname != "" {
hdl := &netifHandle{ifname: ifname}
if e = hdl.open(); e != nil {
return nil, e
}
return hdl, nil
}

localMAC, e := net.ParseMAC(local)
if e != nil || !macaddr.IsUnicast(localMAC) {
return nil, errors.New("invalid local MAC address")
}
hdl := &fileHandle{local: localMAC}
if e = hdl.open(filename); e != nil {
hdl.Close()
return nil, e
}
return hdl, nil
}
89 changes: 89 additions & 0 deletions pcapinput/netif.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package pcapinput

import (
"errors"
"io"
"net"
"sync"
"sync/atomic"
"time"

"github.com/google/gopacket"
"github.com/google/gopacket/afpacket"
"github.com/usnistgov/ndn-dpdk/core/macaddr"
"github.com/zyedidia/generic/mapset"
)

type netifHandle struct {
ifname string
locals mapset.Set[[6]byte]
tp *afpacket.TPacket
mu sync.RWMutex
closing atomic.Bool
}

func (hdl *netifHandle) open() (e error) {
hdl.locals = mapset.New[[6]byte]()

opts := []any{afpacket.OptPollTimeout(time.Second)}
if hdl.ifname == "*" {
netifs, e := net.Interfaces()
if e != nil {
return e
}
for _, netif := range netifs {
if macaddr.IsUnicast(netif.HardwareAddr) {
hdl.locals.Put([6]byte(netif.HardwareAddr))
}
}
} else {
netif, e := net.InterfaceByName(hdl.ifname)
if e != nil {
return e
}
hdl.locals.Put([6]byte(netif.HardwareAddr))
opts = append(opts, afpacket.OptInterface(netif.Name))
}

hdl.tp, e = afpacket.NewTPacket(opts...)
return e
}

func (hdl *netifHandle) Name() string {
return hdl.ifname
}

func (hdl *netifHandle) IsLocal(mac net.HardwareAddr) bool {
return hdl.locals.Has([6]byte(mac))
}

func (hdl *netifHandle) ZeroCopyReadPacketData() (wire []byte, ci gopacket.CaptureInfo, e error) {
hdl.mu.RLock()
defer hdl.mu.RUnlock()

if hdl.closing.Load() {
return nil, gopacket.CaptureInfo{}, io.EOF
}

RETRY:
wire, ci, e = hdl.tp.ZeroCopyReadPacketData()
if e != nil && errors.Is(e, afpacket.ErrTimeout) {
if hdl.closing.Load() {
e = io.EOF
} else {
goto RETRY
}
}

return
}

func (hdl *netifHandle) Close() error {
if wasClosed := hdl.closing.Swap(true); wasClosed {
return nil
}
hdl.mu.Lock()
defer hdl.mu.Unlock()
hdl.tp.Close()
return nil
}
Loading

0 comments on commit d4c3fae

Please sign in to comment.