Network Tracing
Tracking network connections
open() ve read() gibi, network bağlantılarının da bir deneme (entry) ve bir sonuç (exit) aşaması vardır. Bu event’leri ilişkilendirmek için entry noktasında veriyi saklayıp exit noktasında geri alırız.
connect syscall
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
Entry noktasında (sys_enter_connect):
ctx->args[0]= socket file descriptorctx->args[1]=sockaddrstruct’ına pointer (user space)
Exit noktasında (sys_exit_connect):
ctx->ret == 0- Bağlantı başarılıctx->ret < 0- Bağlantı başarısız (errno value)
sockaddr struct’ını okuma
ctx->args[1]’deki addr pointer’ı user space belleğine işaret eder. Güvenli bir şekilde kopyalamak için bpf_probe_read_user() kullanmanız gerekir:
struct sockaddr_in addr;
bpf_probe_read_user(&addr, sizeof(addr), (void *)ctx->args[1]);
IPv4 bağlantıları için (sin_family == 2):
struct sockaddr_in {
u16 sin_family; // AF_INET = 2
u16 sin_port; // Port (network byte order!)
u32 sin_addr; // IP address
char __pad[8];
};
Port ve IP network byte order (big-endian) formatındadır. Host order’a dönüştürmek için helper fonksiyonu kullanın:
u16 port = bpf_ntohs(addr.sin_port);
Görev
Bir program birden fazla port’a bağlanmayı deniyor. Çoğu bağlantı başarısız oluyor, ancak biri başarılı. Başarılı olan bağlantının port’unu gönderin.
Yapmanız gereken:
connectentry noktasında:sockaddr_instruct’ını okuyun ve port’u geçici bir map’te saklayınconnectexit noktasında: Bağlantının başarılı olup olmadığını kontrol edin (ret == 0), ardından port’u gönderin
Başlangıç kodu takip etmeniz gereken yapıyı içerir.
Insert or update map entry
- Args:
void* mappointer to mapconst void* keypointer to keyconst void* valuepointer to valueu64 flagsBPF_ANY (create or update), BPF_NOEXIST (create only), or BPF_EXIST (update only)
Get value from map by key
- Args:
void* mappointer to mapconst void* keypointer to key
Remove entry from map
- Args:
void* mappointer to mapconst void* keypointer to key to delete