Skip to content

Instantly share code, notes, and snippets.

@buger
Last active September 27, 2017 08:36
Show Gist options
  • Save buger/95cbbca9decabd7e0d610102796b7e07 to your computer and use it in GitHub Desktop.
Save buger/95cbbca9decabd7e0d610102796b7e07 to your computer and use it in GitHub Desktop.
Rcapd go lang implementation

Record to file:

rcapd --input-raw "<interface>" --input-raw-engine "pcap" --input-raw-bpf "tcp" --output-file network.pcap

Forward traffic from 1 machine to another:

rcapd --input-raw "<interface>" --input-raw-engine "pcap" --input-raw-bpf "tcp" --output-tcp <ip>:<port>
rcapd --input-tcp <ip>:<port> --output-file network.pcap

PFRING

On linux it is possible to use --input-raw-engine pfring

package main
import (
"flag"
"log"
"net"
"os"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
"github.com/google/gopacket/pcapgo"
)
var pcapHandlers = make(map[string]func(string, string) gopacket.PacketDataSource)
var outputTCP = flag.String("output-tcp", "", "Set to forward pcap data to another host")
var outputFile = flag.String("output-file", "", "Set to write pcap data to file")
var inputTCP = flag.String("input-tcp", "", "Set to receive pcap data from another host")
var inputRAW = flag.String("input-raw", "", "Set interface to read package from")
var inputRAWBpf = flag.String("input-raw-bpf", "", "Apply additional bpf filter")
var inputRAWEngine = flag.String("input-raw-engine", "pcap", "Possible values `pcap` or `pfring`")
func init() {
pcapHandlers["pcap"] = func(in, bpf string) gopacket.PacketDataSource {
handle, err := pcap.OpenLive(in, 65536, true, -1)
if err != nil {
log.Fatal(err)
}
handle.SetBPFFilter(bpf)
return handle
}
}
func main() {
flag.Parse()
if *inputTCP != "" {
listener, lerr := net.Listen("tcp", *inputTCP)
if lerr != nil {
log.Fatal(lerr)
}
var output *pcapgo.Writer
if *outputFile != "" {
f, err := os.OpenFile(*outputFile, os.O_CREATE|os.O_RDWR, 0666)
if err != nil {
log.Fatal(err)
}
output = pcapgo.NewWriter(f)
output.WriteFileHeader(65536, layers.LinkTypeEthernet)
}
for {
conn, cerr := listener.Accept()
if cerr != nil {
log.Fatal(cerr)
}
r, _ := pcapgo.NewReader(conn)
for {
data, ci, err := r.ReadPacketData()
if err != nil {
break
}
if output != nil {
output.WritePacket(ci, data)
} else {
log.Println(ci)
}
}
conn.Close()
}
}
if *inputRAW != "" {
var handle gopacket.PacketDataSource
if fn, ok := pcapHandlers[*inputRAWEngine]; ok {
handle = fn(*inputRAW, *inputRAWBpf)
} else {
log.Fatal("Unknown or unsupported engine", *inputRAWEngine)
}
var output *pcapgo.Writer
if *outputFile != "" {
f, err := os.OpenFile(*outputFile, os.O_CREATE|os.O_RDWR, 0666)
if err != nil {
log.Fatal(err)
}
log.Println("File writer")
output = pcapgo.NewWriter(f)
} else if *outputTCP != "" {
conn, err := net.Dial("tcp", *outputTCP)
if err != nil {
log.Fatal(err)
}
output = pcapgo.NewWriter(conn)
}
if output != nil {
output.WriteFileHeader(65536, layers.LinkTypeEthernet)
}
for {
data, ci, err := handle.ReadPacketData()
if err != nil {
log.Fatal(err)
}
if output != nil {
output.WritePacket(ci, data)
} else {
log.Println(ci)
}
}
}
}
// +build linux
package main
import (
"log"
"github.com/google/gopacket"
"github.com/google/gopacket/pfring"
)
func init() {
pcapHandlers["pfring"] = func(in string, bpf string) gopacket.PacketDataSource {
if ring, err := pfring.NewRing(in, 65536, pfring.FlagPromisc); err != nil {
log.Fatal(err)
} else if err := ring.SetBPFFilter(bpf); err != nil { // optional
log.Fatal(err)
} else if err := ring.Enable(); err != nil { // Must do this!, or you get no packets!
log.Fatal(err)
return ring
}
return nil
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment