0001
0002
0003 #include "bpf_iter.h"
0004 #include "bpf_tracing_net.h"
0005 #include <bpf/bpf_helpers.h>
0006 #include <bpf/bpf_endian.h>
0007
0008 char _license[] SEC("license") = "GPL";
0009
0010 static long sock_i_ino(const struct sock *sk)
0011 {
0012 const struct socket *sk_socket = sk->sk_socket;
0013 const struct inode *inode;
0014 unsigned long ino;
0015
0016 if (!sk_socket)
0017 return 0;
0018
0019 inode = &container_of(sk_socket, struct socket_alloc, socket)->vfs_inode;
0020 bpf_probe_read_kernel(&ino, sizeof(ino), &inode->i_ino);
0021 return ino;
0022 }
0023
0024 SEC("iter/unix")
0025 int dump_unix(struct bpf_iter__unix *ctx)
0026 {
0027 struct unix_sock *unix_sk = ctx->unix_sk;
0028 struct sock *sk = (struct sock *)unix_sk;
0029 struct seq_file *seq;
0030 __u32 seq_num;
0031
0032 if (!unix_sk)
0033 return 0;
0034
0035 seq = ctx->meta->seq;
0036 seq_num = ctx->meta->seq_num;
0037 if (seq_num == 0)
0038 BPF_SEQ_PRINTF(seq, "Num RefCount Protocol Flags Type St Inode Path\n");
0039
0040 BPF_SEQ_PRINTF(seq, "%pK: %08X %08X %08X %04X %02X %8lu",
0041 unix_sk,
0042 sk->sk_refcnt.refs.counter,
0043 0,
0044 sk->sk_state == TCP_LISTEN ? __SO_ACCEPTCON : 0,
0045 sk->sk_type,
0046 sk->sk_socket ?
0047 (sk->sk_state == TCP_ESTABLISHED ? SS_CONNECTED : SS_UNCONNECTED) :
0048 (sk->sk_state == TCP_ESTABLISHED ? SS_CONNECTING : SS_DISCONNECTING),
0049 sock_i_ino(sk));
0050
0051 if (unix_sk->addr) {
0052 if (unix_sk->addr->name->sun_path[0]) {
0053 BPF_SEQ_PRINTF(seq, " %s", unix_sk->addr->name->sun_path);
0054 } else {
0055
0056
0057
0058
0059 __u64 i, len;
0060
0061 len = unix_sk->addr->len - sizeof(short);
0062
0063 BPF_SEQ_PRINTF(seq, " @");
0064
0065 for (i = 1; i < len; i++) {
0066
0067 if (i >= sizeof(struct sockaddr_un))
0068 break;
0069
0070 BPF_SEQ_PRINTF(seq, "%c",
0071 unix_sk->addr->name->sun_path[i] ?:
0072 '@');
0073 }
0074 }
0075 }
0076
0077 BPF_SEQ_PRINTF(seq, "\n");
0078
0079 return 0;
0080 }