Skip to content

Instantly share code, notes, and snippets.

@trozet
Created February 9, 2024 17:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save trozet/a900192ce0a84396d466f27ce2796d0f to your computer and use it in GitHub Desktop.
Save trozet/a900192ce0a84396d466f27ce2796d0f to your computer and use it in GitHub Desktop.
chatgpt netlink socket ebpf
### ebpf
#include <linux/bpf.h>
#include <linux/if_ether.h>
#include <linux/ip.h>
#include <linux/in.h>
#include <linux/tcp.h>
struct data_t {
__u32 src_ip;
__u32 dst_ip;
};
BPF_HASH(ip_map, __u32, struct data_t);
int bpf_prog(struct __sk_buff *skb) {
struct data_t data = {};
struct ethhdr *eth = bpf_hdr_pointer(skb, 0);
if (eth->h_proto == __constant_htons(ETH_P_IP)) {
struct iphdr *ip = (struct iphdr *)(eth + 1);
if (ip->protocol == IPPROTO_TCP) {
data.src_ip = ip->saddr;
data.dst_ip = ip->daddr;
// Store the IP addresses in the map
ip_map.update(&data.src_ip, &data);
ip_map.update(&data.dst_ip, &data);
}
}
return 0;
}
### golang
package main
import (
"fmt"
"log"
"os"
"syscall"
"unsafe"
)
const (
SOCK_FILTER_ATTACH_BPF = 26 // syscall constant for attaching a BPF program to a socket
BPF_PROG_TYPE_SOCKET_FILTER = 1 // eBPF program type for socket filter
NETLINK_GENERIC = 16 // Replace this with the appropriate protocol value
)
func main() {
// Open the eBPF object file
file, err := os.Open("ebpf_program.o")
if err != nil {
log.Fatalf("failed to open eBPF object file: %v", err)
}
defer file.Close()
// Read the eBPF object file into memory
ebpfCode, err := io.ReadAll(file)
if err != nil {
log.Fatalf("failed to read eBPF object file: %v", err)
}
// Load the eBPF program
progFd, err := syscall.Bpf(syscall.BPF_PROG_LOAD, unsafe.Pointer(&syscall.BpfAttrProgLoad{
ProgType: BPF_PROG_TYPE_SOCKET_FILTER,
Insns: uintptr(unsafe.Pointer(&ebpfCode[0])),
License: uintptr(unsafe.Pointer(&[]byte("GPL")[0])),
LogLevel: 0,
LogSize: 0,
LogBuf: 0,
KernVersion: syscall.GetKernelVersion(),
}))
if err != nil {
log.Fatalf("failed to load eBPF program: %v", err)
}
defer syscall.Close(progFd)
// Create a netlink socket
fd, err := syscall.Socket(syscall.AF_NETLINK, syscall.SOCK_RAW, NETLINK_GENERIC)
if err != nil {
log.Fatalf("failed to create netlink socket: %v", err)
}
defer syscall.Close(fd)
// Attach the eBPF program as a socket filter to the netlink socket
if err := syscall.SetsockoptInt(fd, syscall.SOL_SOCKET, SOCK_FILTER_ATTACH_BPF, progFd); err != nil {
log.Fatalf("failed to attach eBPF program to socket: %v", err)
}
// Run your netlink socket code here (send/receive messages)
fmt.Println("Netlink socket with eBPF program attached created successfully")
// Wait for a signal to exit (you can add your own logic here)
var signalChan = make(chan os.Signal, 1)
<-signalChan
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment