Skip to content

Commit

Permalink
Fix getaddrinfo multiple adresses and hostname
Browse files Browse the repository at this point in the history
  • Loading branch information
calesanz committed Jan 25, 2022
1 parent 38d9747 commit 5dcb4a7
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 20 deletions.
3 changes: 2 additions & 1 deletion daemon/dns/ebpfhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func DnsListenerEbpf() error {
var event nameLookupEvent
for {
data := <-channel
log.Info("EBPF-DNS: LookupEvent %d %x", len(data), data)
log.Debug("EBPF-DNS: LookupEvent %d %x %x %x", len(data), data[:4], data[4:20], data[20:])
err := binary.Read(bytes.NewBuffer(data), binary.LittleEndian, &event)
if err != nil {
log.Warning("EBPF-DNS: Failed to decode ebpf nameLookupEvent: %s\n", err)
Expand All @@ -96,6 +96,7 @@ func DnsListenerEbpf() error {
// Convert C string (null-terminated) to Go string
host := string(event.Host[:bytes.IndexByte(event.Host[:], 0)])
var ip net.IP
// 2 -> AF_INET (ipv4)
if event.AddrType == 2 {
ip = net.IP(event.Ip[:4])
} else {
Expand Down
42 changes: 23 additions & 19 deletions ebpf_prog/opensnitch-dns.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,15 @@ struct bpf_map_def SEC("maps/events") events = {
SEC("uretprobe/gethostbyname")
int uretprobe__gethostbyname(struct pt_regs *ctx) {
// bpf_tracing_prinkt("Called gethostbyname %d\n",1);
struct nameLookupEvent data = {};
struct nameLookupEvent data = {0};

if (!PT_REGS_RC(ctx))
return 0;

struct hostent *host = (struct hostent *)PT_REGS_RC(ctx);
char * hostnameptr;
bpf_probe_read(&hostnameptr, sizeof(hostnameptr), &host->h_name);
bpf_probe_read_str(&data.host, sizeof(data.host), hostnameptr);

char **ips;
bpf_probe_read(&ips, sizeof(ips), &host->h_addr_list);
Expand All @@ -110,12 +113,16 @@ int uretprobe__gethostbyname(struct pt_regs *ctx) {
if (ip == NULL) {
return 0;
}
// FIXME data.host is still wrong
bpf_probe_read_user_str(&data.host, sizeof(data.host), &host->h_name);
bpf_probe_read_user(&data.ip, sizeof(data.ip), ip);
bpf_probe_read_user(&data.addr_type, sizeof(data.addr_type),
&host->h_addrtype);

if (data.addr_type == AF_INET) {
// Only copy the 4 relevant bytes
bpf_probe_read_user(&data.ip, 4, ip);
} else {
bpf_probe_read_user(&data.ip, sizeof(data.ip), ip);
}

bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &data,
sizeof(data));

Expand Down Expand Up @@ -182,41 +189,38 @@ int ret_addrinfo(struct pt_regs *ctx) {

#pragma clang loop unroll(full)
for (int i = 0; i < MAX_IPS; i++) {
// struct addrinfo * res = *res_p;
struct addrinfo *res;
bpf_probe_read(&res, sizeof(res), res_p);

// FIXME this does not seem to work correctly
if (res == NULL) {
break;
return 0;
}
// data.addr_type = res->ai_family;
bpf_probe_read(&data.addr_type, sizeof(data.addr_type),
&res->ai_family);

// AF_INET 2

if (data.addr_type == 2) {
if (data.addr_type == AF_INET) {
struct sockaddr_in *ipv4;
bpf_probe_read(&ipv4, sizeof(ipv4), &res->ai_addr);
// TODO copies other memory (sizeof(data.ip) could be replaced with
// 4)
bpf_probe_read_user(&data.ip, sizeof(data.ip), &ipv4->sin_addr);
} else {
// Only copy the 4 relevant bytes
bpf_probe_read_user(&data.ip, 4, &ipv4->sin_addr);
} else if(data.addr_type == AF_INET6) {
struct sockaddr_in6 *ipv6;
bpf_probe_read(&ipv6, sizeof(ipv6), &res->ai_addr);

bpf_probe_read_user(&data.ip, sizeof(data.ip), &ipv6->sin6_addr);
}
} else {
return 1;
}

bpf_probe_read_kernel_str(&data.host, sizeof(data.host),
&addrinfo_args->node);

bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &data,
sizeof(data));

// res_p = &res->ai_next;
bpf_probe_read(&res_p, sizeof(res_p), &res->ai_next);

struct addrinfo * next;
bpf_probe_read(&next, sizeof(next), &res->ai_next);
res_p = &next;
}

return 0;
Expand Down

0 comments on commit 5dcb4a7

Please sign in to comment.