Make default pid to be -1 and remove unsafe code
This commit is contained in:
@@ -1,17 +1,17 @@
|
|||||||
package ebpf
|
package ebpf
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/cilium/ebpf"
|
"github.com/cilium/ebpf"
|
||||||
"github.com/cilium/ebpf/link"
|
"github.com/cilium/ebpf/link"
|
||||||
"github.com/cilium/ebpf/rlimit"
|
"github.com/cilium/ebpf/rlimit"
|
||||||
"github.com/safing/portbase/log"
|
"github.com/safing/portbase/log"
|
||||||
|
"github.com/safing/portmaster/network/packet"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -28,6 +28,7 @@ var ebpfInterface = struct {
|
|||||||
objs: bpfObjects{},
|
objs: bpfObjects{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetupBandwidthInterface initializes the ebpf interface and starts gattering bandwidth information for all connections.
|
||||||
func SetupBandwidthInterface() error {
|
func SetupBandwidthInterface() error {
|
||||||
|
|
||||||
// Allow the current process to lock memory for eBPF resources.
|
// Allow the current process to lock memory for eBPF resources.
|
||||||
@@ -141,6 +142,7 @@ func ShutdownBandwithInterface() {
|
|||||||
ebpfInterface.objs.Close()
|
ebpfInterface.objs.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// findCgroupPath returns the default unified path of the cgroup
|
||||||
func findCgroupPath() (string, error) {
|
func findCgroupPath() (string, error) {
|
||||||
cgroupPath := "/sys/fs/cgroup"
|
cgroupPath := "/sys/fs/cgroup"
|
||||||
|
|
||||||
@@ -156,24 +158,31 @@ func findCgroupPath() (string, error) {
|
|||||||
return cgroupPath, nil
|
return cgroupPath, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// printBandwidthData prints the contencs of the shared map in the ebpf program.
|
||||||
func printBandwidthData() {
|
func printBandwidthData() {
|
||||||
iter := ebpfInterface.objs.bpfMaps.PmBandwidthMap.Iterate()
|
iter := ebpfInterface.objs.bpfMaps.PmBandwidthMap.Iterate()
|
||||||
var skKey bpfSkKey
|
var skKey bpfSkKey
|
||||||
var skInfo bpfSkInfo
|
var skInfo bpfSkInfo
|
||||||
for iter.Next(&skKey, &skInfo) {
|
for iter.Next(&skKey, &skInfo) {
|
||||||
log.Debugf("Connection: %d %s:%d %s:%d %d %d", skKey.Protocol,
|
log.Debugf("Connection: %d %s:%d %s:%d %d %d", skKey.Protocol,
|
||||||
arrayToIP(skKey.SrcIp, skKey.Ipv6).String(), skKey.SrcPort,
|
convertArrayToIPv4(skKey.SrcIp, packet.IPVersion(skKey.Ipv6)).String(), skKey.SrcPort,
|
||||||
arrayToIP(skKey.DstIp, skKey.Ipv6).String(), skKey.DstPort,
|
convertArrayToIPv4(skKey.DstIp, packet.IPVersion(skKey.Ipv6)).String(), skKey.DstPort,
|
||||||
skInfo.Rx, skInfo.Tx,
|
skInfo.Rx, skInfo.Tx,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// arrayToIP converts IP number array to net.IP
|
// convertArrayToIPv4 converts an array of uint32 values to an IPv4 net.IP address.
|
||||||
func arrayToIP(ipNum [4]uint32, ipv6 uint8) net.IP {
|
func convertArrayToIPv4(input [4]uint32, ipVersion packet.IPVersion) net.IP {
|
||||||
if ipv6 == 0 {
|
if ipVersion == packet.IPv4 {
|
||||||
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 4)
|
addressBuf := make([]byte, 4)
|
||||||
|
binary.LittleEndian.PutUint32(addressBuf, input[0])
|
||||||
|
return net.IP(addressBuf)
|
||||||
} else {
|
} else {
|
||||||
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 16)
|
addressBuf := make([]byte, 16)
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
binary.LittleEndian.PutUint32(addressBuf[i*4:i*4+4], input[i])
|
||||||
|
}
|
||||||
|
return net.IP(addressBuf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"errors"
|
"errors"
|
||||||
"net"
|
"net"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/cilium/ebpf/link"
|
"github.com/cilium/ebpf/link"
|
||||||
"github.com/cilium/ebpf/ringbuf"
|
"github.com/cilium/ebpf/ringbuf"
|
||||||
@@ -15,8 +14,10 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -cflags "-O2 -g -Wall -Werror" -type Event bpf ../programs/monitor.c
|
//go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc clang -cflags "-O2 -g -Wall -Werror" -type Event bpf ../programs/monitor.c
|
||||||
|
|
||||||
var stopper chan struct{}
|
var stopper chan struct{}
|
||||||
|
|
||||||
|
// StartEBPFWorker starts the ebpf worker.
|
||||||
func StartEBPFWorker(ch chan packet.Packet) {
|
func StartEBPFWorker(ch chan packet.Packet) {
|
||||||
stopper = make(chan struct{})
|
stopper = make(chan struct{})
|
||||||
go func() {
|
go func() {
|
||||||
@@ -32,7 +33,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
|||||||
log.Errorf("ebpf: failed to load ebpf object: %s", err)
|
log.Errorf("ebpf: failed to load ebpf object: %s", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer objs.Close()
|
defer objs.Close() //nolint:errcheck
|
||||||
|
|
||||||
// Create a link to the tcp_connect program.
|
// Create a link to the tcp_connect program.
|
||||||
linkTCPConnect, err := link.AttachTracing(link.TracingOptions{
|
linkTCPConnect, err := link.AttachTracing(link.TracingOptions{
|
||||||
@@ -42,7 +43,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
|||||||
log.Errorf("ebpf: failed to attach to tcp_v4_connect: %s ", err)
|
log.Errorf("ebpf: failed to attach to tcp_v4_connect: %s ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer linkTCPConnect.Close()
|
defer linkTCPConnect.Close() //nolint:errcheck
|
||||||
|
|
||||||
// Create a link to the udp_v4_connect program.
|
// Create a link to the udp_v4_connect program.
|
||||||
linkUDPV4, err := link.AttachTracing(link.TracingOptions{
|
linkUDPV4, err := link.AttachTracing(link.TracingOptions{
|
||||||
@@ -52,7 +53,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
|||||||
log.Errorf("ebpf: failed to attach to udp_v4_connect: %s ", err)
|
log.Errorf("ebpf: failed to attach to udp_v4_connect: %s ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer linkUDPV4.Close()
|
defer linkUDPV4.Close() //nolint:errcheck
|
||||||
|
|
||||||
// Create a link to the udp_v6_connect program.
|
// Create a link to the udp_v6_connect program.
|
||||||
linkUDPV6, err := link.AttachTracing(link.TracingOptions{
|
linkUDPV6, err := link.AttachTracing(link.TracingOptions{
|
||||||
@@ -62,7 +63,7 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
|||||||
log.Errorf("ebpf: failed to attach to udp_v6_connect: %s ", err)
|
log.Errorf("ebpf: failed to attach to udp_v6_connect: %s ", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer linkUDPV6.Close()
|
defer linkUDPV6.Close() //nolint:errcheck
|
||||||
|
|
||||||
rd, err := ringbuf.NewReader(objs.bpfMaps.PmConnectionEvents)
|
rd, err := ringbuf.NewReader(objs.bpfMaps.PmConnectionEvents)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -105,8 +106,8 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
|||||||
Protocol: packet.IPProtocol(event.Protocol),
|
Protocol: packet.IPProtocol(event.Protocol),
|
||||||
SrcPort: event.Sport,
|
SrcPort: event.Sport,
|
||||||
DstPort: event.Dport,
|
DstPort: event.Dport,
|
||||||
Src: arrayToIP(event.Saddr, packet.IPVersion(event.IpVersion)),
|
Src: convertArrayToIPv4(event.Saddr, packet.IPVersion(event.IpVersion)),
|
||||||
Dst: arrayToIP(event.Daddr, packet.IPVersion(event.IpVersion)),
|
Dst: convertArrayToIPv4(event.Daddr, packet.IPVersion(event.IpVersion)),
|
||||||
PID: int(event.Pid),
|
PID: int(event.Pid),
|
||||||
}
|
}
|
||||||
if isEventValid(event) {
|
if isEventValid(event) {
|
||||||
@@ -123,19 +124,30 @@ func StartEBPFWorker(ch chan packet.Packet) {
|
|||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StopEBPFWorker stops the ebpf worker.
|
||||||
func StopEBPFWorker() {
|
func StopEBPFWorker() {
|
||||||
close(stopper)
|
close(stopper)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isEventValid checks whether the given bpfEvent is valid or not.
|
||||||
|
// It returns true if the event is valid, otherwise false.
|
||||||
func isEventValid(event bpfEvent) bool {
|
func isEventValid(event bpfEvent) bool {
|
||||||
|
// Check if the destination port is 0
|
||||||
if event.Dport == 0 {
|
if event.Dport == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the source port is 0
|
||||||
if event.Sport == 0 {
|
if event.Sport == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the process ID is 0
|
||||||
|
if event.Pid == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the IP version is IPv4
|
||||||
if event.IpVersion == 4 {
|
if event.IpVersion == 4 {
|
||||||
if event.Saddr[0] == 0 {
|
if event.Saddr[0] == 0 {
|
||||||
return false
|
return false
|
||||||
@@ -148,11 +160,17 @@ func isEventValid(event bpfEvent) bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// arrayToIP converts IP number array to net.IP
|
// convertArrayToIPv4 converts an array of uint32 values to an IPv4 net.IP address.
|
||||||
func arrayToIP(ipNum [4]uint32, ipVersion packet.IPVersion) net.IP {
|
func convertArrayToIPv4(input [4]uint32, ipVersion packet.IPVersion) net.IP {
|
||||||
if ipVersion == packet.IPv4 {
|
if ipVersion == packet.IPv4 {
|
||||||
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 4)
|
addressBuf := make([]byte, 4)
|
||||||
|
binary.LittleEndian.PutUint32(addressBuf, input[0])
|
||||||
|
return net.IP(addressBuf)
|
||||||
} else {
|
} else {
|
||||||
return unsafe.Slice((*byte)(unsafe.Pointer(&ipNum)), 16)
|
addressBuf := make([]byte, 16)
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
binary.LittleEndian.PutUint32(addressBuf[i*4:i*4+4], input[i])
|
||||||
|
}
|
||||||
|
return net.IP(addressBuf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ func GetProcessByRequestOrigin(ar *api.Request) (*Process, error) {
|
|||||||
Protocol: packet.TCP,
|
Protocol: packet.TCP,
|
||||||
Src: remoteIP, // source as in the process we are looking for
|
Src: remoteIP, // source as in the process we are looking for
|
||||||
SrcPort: remotePort, // source as in the process we are looking for
|
SrcPort: remotePort, // source as in the process we are looking for
|
||||||
|
PID: -1,
|
||||||
}
|
}
|
||||||
|
|
||||||
pid, _, err := GetPidOfConnection(ar.Context(), pkt)
|
pid, _, err := GetPidOfConnection(ar.Context(), pkt)
|
||||||
|
|||||||
Reference in New Issue
Block a user