parent
f45a5665cf
commit
98bc2c21ba
5 changed files with 168 additions and 34 deletions
@ -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