in src/bpf.c [28:106]
int trace_sock_sendmsg(struct pt_regs *ctx)
{
// stash the sock ptr for lookup on return
// only if it is imds traffic
struct socket *skt = (struct socket *)PT_REGS_PARM1(ctx);
struct sock *sk = skt->sk;
if (sk->__sk_common.skc_daddr == IP_169_254_169_254) {
struct msghdr *msghdr = (struct msghdr *)PT_REGS_PARM2(ctx);
u32 zero = 0;
// pull in details
u32 daddr = sk->__sk_common.skc_daddr;
u16 dport = sk->__sk_common.skc_dport;
struct imds_http_data_t *data = imds_http_data.lookup(&zero);
if (!data) // this should never happen, just making the verifier happy
return 0;
#if defined(iter_iov) || defined (iter_iov_len)
const struct iovec * iov = msghdr->msg_iter.__iov;
#else
const struct iovec * iov = msghdr->msg_iter.iov;
#endif
const void *iovbase;
if (*(char *)iov->iov_base == '\0'){
iovbase = iov;
}
else{
iovbase = iov->iov_base;
}
const size_t iovlen = iov->iov_len > MAX_PKT ? MAX_PKT : iov->iov_len;
if (!iovlen) {
return 0;
}
//The size parameter in the line of code below seems to be incorrectly set
//however if we were to intuitively use the size of the payload itself as the size parameter by using iovlen (size of the payload)
//the interpreter will throw an invalid mem access error and the script will not run (most probably due to the method requiring a const value at compile time)
bpf_probe_read_str(data->pkt, sizeof(data->pkt), iovbase);
//check if payload is empty or not -> check char buffer -> if char buffer starts with a termination vales \0 => null buffer
if(data->pkt[0] == '\0'){
data->contains_payload = 0;
}
else{
data->contains_payload = 1;
}
data->pkt_size = iovlen;
struct task_struct *t = (struct task_struct *)bpf_get_current_task();
data->pid[0] = t->tgid;
bpf_probe_read(data->comm, TASK_COMM_LEN, t->comm);
// loops not supported in bpf
if (t->real_parent) {
struct task_struct *parent = t->real_parent;
data->pid[1] = parent->tgid;
bpf_probe_read(data->parent_comm, TASK_COMM_LEN, parent->comm);
if (parent->real_parent) {
struct task_struct *gparent = parent->real_parent;
data->pid[2] = gparent->tgid;
bpf_probe_read(data->gparent_comm, TASK_COMM_LEN, gparent->comm);
if (gparent->real_parent) {
struct task_struct *ggparent = gparent->real_parent;
bpf_probe_read(data->ggparent_comm, TASK_COMM_LEN, ggparent->comm);
data->pid[3] = ggparent->tgid;
}
}
}
imds_events.perf_submit(ctx, data, sizeof(struct imds_http_data_t));
}
return 0;
}