Add udp process detection with ebpf
This commit is contained in:
@@ -20,7 +20,8 @@ type bpfEvent struct {
|
|||||||
Dport uint16
|
Dport uint16
|
||||||
Pid uint32
|
Pid uint32
|
||||||
IpVersion uint8
|
IpVersion uint8
|
||||||
_ [3]byte
|
Protocol uint8
|
||||||
|
_ [2]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadBpf returns the embedded CollectionSpec for bpf.
|
// loadBpf returns the embedded CollectionSpec for bpf.
|
||||||
@@ -66,6 +67,8 @@ type bpfSpecs struct {
|
|||||||
type bpfProgramSpecs struct {
|
type bpfProgramSpecs struct {
|
||||||
TcpV4Connect *ebpf.ProgramSpec `ebpf:"tcp_v4_connect"`
|
TcpV4Connect *ebpf.ProgramSpec `ebpf:"tcp_v4_connect"`
|
||||||
TcpV6Connect *ebpf.ProgramSpec `ebpf:"tcp_v6_connect"`
|
TcpV6Connect *ebpf.ProgramSpec `ebpf:"tcp_v6_connect"`
|
||||||
|
UdpSendmsg *ebpf.ProgramSpec `ebpf:"udp_sendmsg"`
|
||||||
|
Udpv6Sendmsg *ebpf.ProgramSpec `ebpf:"udpv6_sendmsg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// bpfMapSpecs contains maps before they are loaded into the kernel.
|
// bpfMapSpecs contains maps before they are loaded into the kernel.
|
||||||
@@ -109,12 +112,16 @@ func (m *bpfMaps) Close() error {
|
|||||||
type bpfPrograms struct {
|
type bpfPrograms struct {
|
||||||
TcpV4Connect *ebpf.Program `ebpf:"tcp_v4_connect"`
|
TcpV4Connect *ebpf.Program `ebpf:"tcp_v4_connect"`
|
||||||
TcpV6Connect *ebpf.Program `ebpf:"tcp_v6_connect"`
|
TcpV6Connect *ebpf.Program `ebpf:"tcp_v6_connect"`
|
||||||
|
UdpSendmsg *ebpf.Program `ebpf:"udp_sendmsg"`
|
||||||
|
Udpv6Sendmsg *ebpf.Program `ebpf:"udpv6_sendmsg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *bpfPrograms) Close() error {
|
func (p *bpfPrograms) Close() error {
|
||||||
return _BpfClose(
|
return _BpfClose(
|
||||||
p.TcpV4Connect,
|
p.TcpV4Connect,
|
||||||
p.TcpV6Connect,
|
p.TcpV6Connect,
|
||||||
|
p.UdpSendmsg,
|
||||||
|
p.Udpv6Sendmsg,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ type bpfEvent struct {
|
|||||||
Dport uint16
|
Dport uint16
|
||||||
Pid uint32
|
Pid uint32
|
||||||
IpVersion uint8
|
IpVersion uint8
|
||||||
_ [3]byte
|
Protocol uint8
|
||||||
|
_ [2]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadBpf returns the embedded CollectionSpec for bpf.
|
// loadBpf returns the embedded CollectionSpec for bpf.
|
||||||
@@ -66,6 +67,8 @@ type bpfSpecs struct {
|
|||||||
type bpfProgramSpecs struct {
|
type bpfProgramSpecs struct {
|
||||||
TcpV4Connect *ebpf.ProgramSpec `ebpf:"tcp_v4_connect"`
|
TcpV4Connect *ebpf.ProgramSpec `ebpf:"tcp_v4_connect"`
|
||||||
TcpV6Connect *ebpf.ProgramSpec `ebpf:"tcp_v6_connect"`
|
TcpV6Connect *ebpf.ProgramSpec `ebpf:"tcp_v6_connect"`
|
||||||
|
UdpSendmsg *ebpf.ProgramSpec `ebpf:"udp_sendmsg"`
|
||||||
|
Udpv6Sendmsg *ebpf.ProgramSpec `ebpf:"udpv6_sendmsg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// bpfMapSpecs contains maps before they are loaded into the kernel.
|
// bpfMapSpecs contains maps before they are loaded into the kernel.
|
||||||
@@ -109,12 +112,16 @@ func (m *bpfMaps) Close() error {
|
|||||||
type bpfPrograms struct {
|
type bpfPrograms struct {
|
||||||
TcpV4Connect *ebpf.Program `ebpf:"tcp_v4_connect"`
|
TcpV4Connect *ebpf.Program `ebpf:"tcp_v4_connect"`
|
||||||
TcpV6Connect *ebpf.Program `ebpf:"tcp_v6_connect"`
|
TcpV6Connect *ebpf.Program `ebpf:"tcp_v6_connect"`
|
||||||
|
UdpSendmsg *ebpf.Program `ebpf:"udp_sendmsg"`
|
||||||
|
Udpv6Sendmsg *ebpf.Program `ebpf:"udpv6_sendmsg"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *bpfPrograms) Close() error {
|
func (p *bpfPrograms) Close() error {
|
||||||
return _BpfClose(
|
return _BpfClose(
|
||||||
p.TcpV4Connect,
|
p.TcpV4Connect,
|
||||||
p.TcpV6Connect,
|
p.TcpV6Connect,
|
||||||
|
p.UdpSendmsg,
|
||||||
|
p.Udpv6Sendmsg,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
package ebpf
|
package ebpf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
pmpacket "github.com/safing/portmaster/network/packet"
|
pmpacket "github.com/safing/portmaster/network/packet"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -13,19 +15,19 @@ type infoPacket struct {
|
|||||||
|
|
||||||
// LoadPacketData does nothing on Linux, as data is always fully parsed.
|
// LoadPacketData does nothing on Linux, as data is always fully parsed.
|
||||||
func (pkt *infoPacket) LoadPacketData() error {
|
func (pkt *infoPacket) LoadPacketData() error {
|
||||||
return nil // fmt.Errorf("can't load data info only packet")
|
return fmt.Errorf("can't load data in info only packet")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pkt *infoPacket) Accept() error {
|
func (pkt *infoPacket) Accept() error {
|
||||||
return nil // fmt.Errorf("can't accept info only packet")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pkt *infoPacket) Block() error {
|
func (pkt *infoPacket) Block() error {
|
||||||
return nil // fmt.Errorf("can't block info only packet")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pkt *infoPacket) Drop() error {
|
func (pkt *infoPacket) Drop() error {
|
||||||
return nil // fmt.Errorf("can't block info only packet")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pkt *infoPacket) PermanentAccept() error {
|
func (pkt *infoPacket) PermanentAccept() error {
|
||||||
@@ -37,13 +39,13 @@ func (pkt *infoPacket) PermanentBlock() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (pkt *infoPacket) PermanentDrop() error {
|
func (pkt *infoPacket) PermanentDrop() error {
|
||||||
return nil // fmt.Errorf("can't drop info only packet")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pkt *infoPacket) RerouteToNameserver() error {
|
func (pkt *infoPacket) RerouteToNameserver() error {
|
||||||
return nil // fmt.Errorf("can't reroute info only packet")
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pkt *infoPacket) RerouteToTunnel() error {
|
func (pkt *infoPacket) RerouteToTunnel() error {
|
||||||
return nil // fmt.Errorf("can't reroute info only packet")
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,105 +2,213 @@
|
|||||||
#include "bpf/bpf_helpers.h"
|
#include "bpf/bpf_helpers.h"
|
||||||
#include "bpf/bpf_tracing.h"
|
#include "bpf/bpf_tracing.h"
|
||||||
|
|
||||||
typedef unsigned char u8;
|
// IP Version
|
||||||
typedef short int s16;
|
|
||||||
typedef short unsigned int u16;
|
|
||||||
typedef int s32;
|
|
||||||
typedef unsigned int u32;
|
|
||||||
typedef long long int s64;
|
|
||||||
typedef long long unsigned int u64;
|
|
||||||
typedef u16 le16;
|
|
||||||
typedef u16 be16;
|
|
||||||
typedef u32 be32;
|
|
||||||
typedef u64 be64;
|
|
||||||
typedef u32 wsum;
|
|
||||||
|
|
||||||
|
|
||||||
#define AF_INET 2
|
#define AF_INET 2
|
||||||
#define AF_INET6 10
|
#define AF_INET6 10
|
||||||
#define TASK_COMM_LEN 16
|
|
||||||
|
|
||||||
char __license[] SEC("license") = "Dual MIT/GPL";
|
// Protocols
|
||||||
|
#define TCP 6
|
||||||
|
#define UDP 17
|
||||||
|
#define UDPLite 136
|
||||||
|
|
||||||
struct
|
char __license[] SEC("license") = "GPL";
|
||||||
{
|
|
||||||
|
// Ring buffer for all connection events
|
||||||
|
struct {
|
||||||
__uint(type, BPF_MAP_TYPE_RINGBUF);
|
__uint(type, BPF_MAP_TYPE_RINGBUF);
|
||||||
__uint(max_entries, 1 << 24);
|
__uint(max_entries, 1 << 24);
|
||||||
} events SEC(".maps");
|
} events SEC(".maps");
|
||||||
|
|
||||||
/**
|
// Event struct that will be sent to Go on each new connection. (The name should be the same as the go generate command)
|
||||||
* The sample submitted to userspace over a ring buffer.
|
struct Event {
|
||||||
* Emit struct event's type info into the ELF's BTF so bpf2go
|
u32 saddr[4];
|
||||||
* can generate a Go type from it.
|
u32 daddr[4];
|
||||||
*/
|
|
||||||
struct event {
|
|
||||||
be32 saddr[4];
|
|
||||||
be32 daddr[4];
|
|
||||||
u16 sport;
|
u16 sport;
|
||||||
u16 dport;
|
u16 dport;
|
||||||
u32 pid;
|
u32 pid;
|
||||||
u8 ipVersion;
|
u8 ipVersion;
|
||||||
|
u8 protocol;
|
||||||
};
|
};
|
||||||
struct event *unused __attribute__((unused));
|
struct Event *unused __attribute__((unused));
|
||||||
|
|
||||||
|
// Fexit of tcp_v4_connect will be executed when equivalent kernel function returns.
|
||||||
|
// In the kernel function all IPs and ports are set and then tcp_connect is called. tcp_v4_connect -> tcp_connect -> [this-function]
|
||||||
SEC("fexit/tcp_v4_connect")
|
SEC("fexit/tcp_v4_connect")
|
||||||
int BPF_PROG(tcp_v4_connect, struct sock *sk) {
|
int BPF_PROG(tcp_v4_connect, struct sock *sk) {
|
||||||
|
// Ignore everything else then IPv4
|
||||||
if (sk->__sk_common.skc_family != AF_INET) {
|
if (sk->__sk_common.skc_family != AF_INET) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure it's tcp sock
|
||||||
struct tcp_sock *ts = bpf_skc_to_tcp_sock(sk);
|
struct tcp_sock *ts = bpf_skc_to_tcp_sock(sk);
|
||||||
if (!ts) {
|
if (!ts) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct event *tcp_info;
|
// Alloc space for the event
|
||||||
tcp_info = bpf_ringbuf_reserve(&events, sizeof(struct event), 0);
|
struct Event *tcp_info;
|
||||||
|
tcp_info = bpf_ringbuf_reserve(&events, sizeof(struct Event), 0);
|
||||||
if (!tcp_info) {
|
if (!tcp_info) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read PID
|
||||||
tcp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
|
tcp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
|
||||||
|
|
||||||
|
// Set src and dist ports
|
||||||
tcp_info->dport = sk->__sk_common.skc_dport;
|
tcp_info->dport = sk->__sk_common.skc_dport;
|
||||||
tcp_info->sport = sk->__sk_common.skc_num;
|
tcp_info->sport = sk->__sk_common.skc_num;
|
||||||
|
|
||||||
|
// Set src and dist IPs
|
||||||
tcp_info->saddr[0] = __builtin_bswap32(sk->__sk_common.skc_rcv_saddr);
|
tcp_info->saddr[0] = __builtin_bswap32(sk->__sk_common.skc_rcv_saddr);
|
||||||
tcp_info->daddr[0] = __builtin_bswap32(sk->__sk_common.skc_daddr);
|
tcp_info->daddr[0] = __builtin_bswap32(sk->__sk_common.skc_daddr);
|
||||||
|
|
||||||
|
// Set IP version
|
||||||
tcp_info->ipVersion = 4;
|
tcp_info->ipVersion = 4;
|
||||||
|
|
||||||
|
// Set protocol
|
||||||
|
tcp_info->protocol = TCP;
|
||||||
|
|
||||||
|
// Send event
|
||||||
bpf_ringbuf_submit(tcp_info, 0);
|
bpf_ringbuf_submit(tcp_info, 0);
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Fexit(function exit) of tcp_v6_connect will be executed when equivalent kernel function returns.
|
||||||
|
// In the kernel function all IPs and ports are set and then tcp_connect is called. tcp_v6_connect -> tcp_connect -> [this-function]
|
||||||
SEC("fexit/tcp_v6_connect")
|
SEC("fexit/tcp_v6_connect")
|
||||||
int BPF_PROG(tcp_v6_connect, struct sock *sk) {
|
int BPF_PROG(tcp_v6_connect, struct sock *sk) {
|
||||||
|
// Ignore everything else then IPv6
|
||||||
if (sk->__sk_common.skc_family != AF_INET6) {
|
if (sk->__sk_common.skc_family != AF_INET6) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct tcp_sock *ts = bpf_skc_to_tcp_sock(sk);
|
// Make sure its a tcp6 sock
|
||||||
|
struct tcp6_sock *ts = bpf_skc_to_tcp6_sock(sk);
|
||||||
if (!ts) {
|
if (!ts) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct event *tcp_info;
|
// Alloc space for the event
|
||||||
tcp_info = bpf_ringbuf_reserve(&events, sizeof(struct event), 0);
|
struct Event *tcp_info;
|
||||||
|
tcp_info = bpf_ringbuf_reserve(&events, sizeof(struct Event), 0);
|
||||||
if (!tcp_info) {
|
if (!tcp_info) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read PID
|
||||||
tcp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
|
tcp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
|
||||||
|
|
||||||
|
// Set src and dist ports
|
||||||
|
tcp_info->dport = sk->__sk_common.skc_dport;
|
||||||
|
tcp_info->sport = sk->__sk_common.skc_num;
|
||||||
|
|
||||||
|
// Set src and dist IPs
|
||||||
for(int i = 0; i < 4; i++) {
|
for(int i = 0; i < 4; i++) {
|
||||||
tcp_info->saddr[i] = __builtin_bswap32(sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32[i]);
|
tcp_info->saddr[i] = __builtin_bswap32(sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32[i]);
|
||||||
}
|
}
|
||||||
for(int i = 0; i < 4; i++) {
|
for(int i = 0; i < 4; i++) {
|
||||||
tcp_info->daddr[i] = __builtin_bswap32(sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32[i]);
|
tcp_info->daddr[i] = __builtin_bswap32(sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32[i]);
|
||||||
}
|
}
|
||||||
tcp_info->dport = sk->__sk_common.skc_dport;
|
|
||||||
tcp_info->sport = sk->__sk_common.skc_num;
|
// Set IP version
|
||||||
tcp_info->ipVersion = 6;
|
tcp_info->ipVersion = 6;
|
||||||
|
|
||||||
|
// Set protocol
|
||||||
|
tcp_info->protocol = TCP;
|
||||||
|
|
||||||
|
// Send event
|
||||||
bpf_ringbuf_submit(tcp_info, 0);
|
bpf_ringbuf_submit(tcp_info, 0);
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
// SEC("fentry/udp_sendmsg")
|
// Fentry(function enter) of udp_sendmsg will be executed before equivalent kernel function is called.
|
||||||
|
// [this-function] -> udp_sendmsg
|
||||||
|
SEC("fentry/udp_sendmsg")
|
||||||
|
int BPF_PROG(udp_sendmsg, struct sock *sk) {
|
||||||
|
// Ignore everything else then IPv4
|
||||||
|
if (sk->__sk_common.skc_family != AF_INET) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate space for the event.
|
||||||
|
struct Event *udp_info;
|
||||||
|
udp_info = bpf_ringbuf_reserve(&events, sizeof(struct Event), 0);
|
||||||
|
if (!udp_info) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read PID
|
||||||
|
udp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
|
||||||
|
|
||||||
|
// Set src and dist ports
|
||||||
|
udp_info->dport = sk->__sk_common.skc_dport;
|
||||||
|
udp_info->sport = sk->__sk_common.skc_num;
|
||||||
|
|
||||||
|
// Set src and dist IPs
|
||||||
|
udp_info->saddr[0] = __builtin_bswap32(sk->__sk_common.skc_rcv_saddr);
|
||||||
|
udp_info->daddr[0] = __builtin_bswap32(sk->__sk_common.skc_daddr);
|
||||||
|
|
||||||
|
// Set IP version
|
||||||
|
udp_info->ipVersion = 4;
|
||||||
|
|
||||||
|
// Set protocol. No way to detect udplite for ipv4
|
||||||
|
udp_info->protocol = UDP;
|
||||||
|
|
||||||
|
// Send event
|
||||||
|
bpf_ringbuf_submit(udp_info, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fentry(function enter) of udpv6_sendmsg will be executed before equivalent kernel function is called.
|
||||||
|
// [this-function] -> udpv6_sendmsg
|
||||||
|
SEC("fentry/udpv6_sendmsg")
|
||||||
|
int BPF_PROG(udpv6_sendmsg, struct sock *sk) {
|
||||||
|
// Ignore everything else then IPv6
|
||||||
|
if (sk->__sk_common.skc_family != AF_INET6) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure its udp6 socket
|
||||||
|
struct udp6_sock *us = bpf_skc_to_udp6_sock(sk);
|
||||||
|
if (!us) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate space for the event.
|
||||||
|
struct Event *udp_info;
|
||||||
|
udp_info = bpf_ringbuf_reserve(&events, sizeof(struct Event), 0);
|
||||||
|
if (!udp_info) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read PID
|
||||||
|
udp_info->pid = __builtin_bswap32((u32)bpf_get_current_pid_tgid());
|
||||||
|
|
||||||
|
// Set src and dist ports
|
||||||
|
udp_info->dport = sk->__sk_common.skc_dport;
|
||||||
|
udp_info->sport = sk->__sk_common.skc_num;
|
||||||
|
|
||||||
|
// Set src and dist IPs
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
udp_info->saddr[i] = __builtin_bswap32(sk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32[i]);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 4; i++) {
|
||||||
|
udp_info->daddr[i] = __builtin_bswap32(sk->__sk_common.skc_v6_daddr.in6_u.u6_addr32[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// IP version
|
||||||
|
udp_info->ipVersion = 6;
|
||||||
|
|
||||||
|
// Set protocol for UDPLite
|
||||||
|
if(us->udp.pcflag == 0) {
|
||||||
|
udp_info->protocol = UDP;
|
||||||
|
} else {
|
||||||
|
udp_info->protocol = UDPLite;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send event
|
||||||
|
bpf_ringbuf_submit(udp_info, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"net"
|
"net"
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
@@ -15,7 +14,7 @@ import (
|
|||||||
"github.com/safing/portmaster/network/packet"
|
"github.com/safing/portmaster/network/packet"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -cflags "-O2 -g -Wall -Werror" -type event bpf program/monitor.c
|
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -cflags "-O2 -g -Wall -Werror" -type Event bpf program/monitor.c
|
||||||
var stopper chan struct{}
|
var stopper chan struct{}
|
||||||
|
|
||||||
func StartEBPFWorker(ch chan packet.Packet) {
|
func StartEBPFWorker(ch chan packet.Packet) {
|
||||||
@@ -51,6 +50,15 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
|||||||
}
|
}
|
||||||
defer linkv6.Close()
|
defer linkv6.Close()
|
||||||
|
|
||||||
|
// Create a link to the tcp_v6_connect program.
|
||||||
|
linkudp, err := link.AttachTracing(link.TracingOptions{
|
||||||
|
Program: objs.bpfPrograms.UdpSendmsg,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("ebpf: failed to attach to udp_sendmsg: %s ", err)
|
||||||
|
}
|
||||||
|
defer linkudp.Close()
|
||||||
|
|
||||||
rd, err := ringbuf.NewReader(objs.bpfMaps.Events)
|
rd, err := ringbuf.NewReader(objs.bpfMaps.Events)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("ebpf: failed to open ring buffer: %s", err)
|
log.Errorf("ebpf: failed to open ring buffer: %s", err)
|
||||||
@@ -83,22 +91,23 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
|||||||
log.Errorf("ebpf: failed to parse ringbuf event: %s", err)
|
log.Errorf("ebpf: failed to parse ringbuf event: %s", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
ipVersion := packet.IPVersion(event.IpVersion)
|
|
||||||
log.Debugf("ebpf: pid:%d connection %s -> %s ", int(event.Pid), intToIP(event.Saddr, ipVersion).String()+":"+fmt.Sprintf("%d", event.Sport), intToIP(event.Daddr, ipVersion).String()+":"+fmt.Sprintf("%d", event.Dport))
|
|
||||||
pack := &infoPacket{}
|
|
||||||
|
|
||||||
pack.SetPacketInfo(packet.Info{
|
info := packet.Info{
|
||||||
Inbound: false,
|
Inbound: false,
|
||||||
InTunnel: false,
|
InTunnel: false,
|
||||||
Version: packet.IPVersion(event.IpVersion),
|
Version: packet.IPVersion(event.IpVersion),
|
||||||
Protocol: packet.TCP,
|
Protocol: packet.IPProtocol(event.Protocol),
|
||||||
SrcPort: event.Sport,
|
SrcPort: event.Sport,
|
||||||
DstPort: event.Dport,
|
DstPort: event.Dport,
|
||||||
Src: intToIP(event.Saddr, ipVersion),
|
Src: arrayToIP(event.Saddr, packet.IPVersion(event.IpVersion)),
|
||||||
Dst: intToIP(event.Daddr, ipVersion),
|
Dst: arrayToIP(event.Daddr, packet.IPVersion(event.IpVersion)),
|
||||||
PID: event.Pid,
|
PID: event.Pid,
|
||||||
})
|
}
|
||||||
ch <- pack
|
log.Debugf("ebpf: PID: %d conn: %s:%d -> %s:%d %s %s", info.PID, info.LocalIP(), info.LocalPort(), info.RemoteIP(), info.LocalPort(), info.Version.String(), info.Protocol.String())
|
||||||
|
|
||||||
|
p := &infoPacket{}
|
||||||
|
p.SetPacketInfo(info)
|
||||||
|
ch <- p
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@@ -107,8 +116,8 @@ func StopEBPFWorker() {
|
|||||||
close(stopper)
|
close(stopper)
|
||||||
}
|
}
|
||||||
|
|
||||||
// intToIP converts IPv4 number to net.IP
|
// arrayToIP converts IPv4 number to net.IP
|
||||||
func intToIP(ipNum [4]uint32, ipVersion packet.IPVersion) net.IP {
|
func arrayToIP(ipNum [4]uint32, ipVersion packet.IPVersion) net.IP {
|
||||||
if ipVersion == packet.IPv4 {
|
if ipVersion == packet.IPv4 {
|
||||||
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 4)
|
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 4)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ func GetProcessByConnection(ctx context.Context, pktInfo *packet.Info) (process
|
|||||||
return nil, pktInfo.Inbound, err
|
return nil, pktInfo.Inbound, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Tracer(ctx).Tracef("process: pid already set in packet (by ebpf or kext ALE layer)")
|
log.Tracer(ctx).Tracef("process: pid already set in packet (by ebpf or kext)")
|
||||||
pid = int(pktInfo.PID)
|
pid = int(pktInfo.PID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user