parent
f45a5665cf
commit
98bc2c21ba
@ -0,0 +1,90 @@
|
||||
package capture
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.freifunk-franken.de/jkimmel/abbel/packet"
|
||||
"github.com/google/gopacket"
|
||||
"github.com/google/gopacket/afpacket"
|
||||
"github.com/google/gopacket/layers"
|
||||
"golang.org/x/net/bpf"
|
||||
"inet.af/netaddr"
|
||||
)
|
||||
|
||||
var (
|
||||
// tcpdump -y RAW -dd ip6 and udp dst port 6696
|
||||
babelBPFRAW = []bpf.RawInstruction{
|
||||
{0x30, 0, 0, 0x00000000},
|
||||
{0x54, 0, 0, 0x000000f0},
|
||||
{0x15, 0, 5, 0x00000060},
|
||||
{0x30, 0, 0, 0x00000006},
|
||||
{0x15, 0, 3, 0x00000011},
|
||||
{0x28, 0, 0, 0x0000002a},
|
||||
{0x15, 0, 1, 0x00001a28},
|
||||
{0x6, 0, 0, 0x00040000},
|
||||
{0x6, 0, 0, 0x00000000},
|
||||
}
|
||||
)
|
||||
|
||||
type Handle struct {
|
||||
tp *afpacket.TPacket
|
||||
}
|
||||
|
||||
func FromInterface(iface string) (Handle, error) {
|
||||
var h Handle
|
||||
var err error
|
||||
|
||||
if iface != "any" {
|
||||
h.tp, err = afpacket.NewTPacket(
|
||||
afpacket.SocketDgram,
|
||||
afpacket.OptInterface(iface),
|
||||
)
|
||||
} else {
|
||||
h.tp, err = afpacket.NewTPacket(
|
||||
afpacket.SocketDgram,
|
||||
)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
fmt.Println("here")
|
||||
return Handle{}, err
|
||||
}
|
||||
|
||||
err = h.tp.SetBPF(babelBPFRAW)
|
||||
if err != nil {
|
||||
return Handle{}, err
|
||||
}
|
||||
|
||||
return h, nil
|
||||
}
|
||||
|
||||
func (h Handle) Close() error {
|
||||
h.tp.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h Handle) ReadFrom(b []byte) (body []byte, src netaddr.IP, ifindex int, err error) {
|
||||
data, ci, err := h.tp.ZeroCopyReadPacketData()
|
||||
if err != nil {
|
||||
return nil, netaddr.IP{}, 0, err
|
||||
}
|
||||
pckt := gopacket.NewPacket(data, layers.LayerTypeIPv6, gopacket.NoCopy)
|
||||
ip6, ok := pckt.NetworkLayer().(*layers.IPv6)
|
||||
if !ok {
|
||||
return nil, netaddr.IP{}, 0, fmt.Errorf("Expected IPv6 layer, got %v", pckt.NetworkLayer())
|
||||
}
|
||||
|
||||
src, ok = netaddr.FromStdIP(ip6.SrcIP)
|
||||
if !ok {
|
||||
return nil, netaddr.IP{}, 0, fmt.Errorf("Error parsing packet src address %q", ip6.SrcIP)
|
||||
}
|
||||
|
||||
payload := pckt.ApplicationLayer().Payload()
|
||||
copy(b, payload)
|
||||
b, err = packet.Validate(b[:len(payload)])
|
||||
if err != nil {
|
||||
return nil, netaddr.IP{}, 0, err
|
||||
}
|
||||
|
||||
return b, src, ci.InterfaceIndex, nil
|
||||
}
|
Loading…
Reference in new issue