static __always_inline int nf_conntrack_tuple_to_conntrack_tuple()

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;
}