in bpf/accesslog/syscalls/connect_conntrack.c [26:83]
static __always_inline int nf_conntrack_tuple_to_conntrack_tuple(struct connect_args_t *connect_args, conntrack_tuple_t *t, const struct nf_conntrack_tuple *ct) {
__builtin_memset(t, 0, sizeof(conntrack_tuple_t));
switch (ct->dst.protonum) {
case IPPROTO_TCP:
t->sport = ct->src.u.tcp.port;
t->dport = ct->dst.u.tcp.port;
break;
case IPPROTO_UDP:
t->sport = ct->src.u.udp.port;
t->dport = ct->dst.u.udp.port;
break;
default:
return 0;
}
t->sport = bpf_ntohs(t->sport);
t->dport = bpf_ntohs(t->dport);
if (t->sport == 0 || t->dport == 0) {
return 0;
}
if (ct->src.l3num == AF_INET) {
t->saddr_l = ct->src.u3.ip;
t->daddr_l = ct->dst.u3.ip;
if (!t->saddr_l || !t->daddr_l) {
return 0;
}
} else if (ct->src.l3num == AF_INET6) {
nf_conntrack_read_in6_addr(&t->saddr_h, &t->saddr_l, &ct->src.u3.in6);
nf_conntrack_read_in6_addr(&t->daddr_h, &t->daddr_l, &ct->dst.u3.in6);
if (!t->saddr_h || !t->saddr_l || !t->daddr_h || !t->daddr_l) {
return 0;
}
}
struct sock *sock = connect_args->sock;
struct socket *tmps = _(sock->sk_socket);
if (tmps != NULL) {
struct sock* s;
BPF_CORE_READ_INTO(&s, tmps, sk);
short unsigned int skc_family;
BPF_CORE_READ_INTO(&skc_family, s, __sk_common.skc_family);
if (skc_family == AF_INET) {
__u16 local_port;
BPF_CORE_READ_INTO(&local_port, s, __sk_common.skc_num);
__u32 local_addr_v4;
BPF_CORE_READ_INTO(&local_addr_v4, s, __sk_common.skc_rcv_saddr);
// make sure connntrack with the same socket address
if (local_addr_v4 != t->daddr_l || local_port != t->dport) {
return 0;
}
}
}
return 1;
}