|
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) |
|
} |
|
} |
|
} |
|
} |