bpf/accesslog/syscalls/connect.c (100 lines of code) (raw):
// Licensed to Apache Software Foundation (ASF) under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. Apache Software Foundation (ASF) licenses this file to you under
// the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "api.h"
#include "socket.h"
#include "socket_opts.h"
#include "../process/process.h"
#include "../common/connection.h"
static __inline void process_connect(void *ctx, __u64 id, struct connect_args_t *connect_args, long ret) {
bool success = true;
if (ret < 0 && ret != -EINPROGRESS) {
success = false;
}
if (connect_args->fd < 0) {
return;
}
__u32 tgid = id >> 32;
struct sock *sock = connect_args->sock;
struct socket *s = _(sock->sk_socket);
submit_new_connection(ctx, success, SOCKET_OPTS_TYPE_CONNECT, tgid, connect_args->fd, connect_args->start_nacs, connect_args->addr, s, &connect_args->remote, 0);
}
static __inline void process_accept(void *ctx, __u64 id, struct accept_args_t *accept_args, long ret) {
int fd = (int) ret;
__u32 tgid = id >> 32;
struct socket *s = accept_args->socket;
submit_new_connection(ctx, true, SOCKET_OPTS_TYPE_ACCEPT, tgid, fd, accept_args->start_nacs, accept_args->addr, s, NULL, 0);
}
SEC("tracepoint/syscalls/sys_enter_connect")
int tracepoint_enter_connect(struct syscall_trace_enter *ctx) {
uint64_t id = bpf_get_current_pid_tgid();
if (tgid_should_trace(id >> 32) == false) {
return 0;
}
struct connect_args_t connect_args = {};
connect_args.fd = (__u32)ctx->args[0];
connect_args.addr = (struct sockaddr *)ctx->args[1];
connect_args.start_nacs = bpf_ktime_get_ns();
bpf_map_update_elem(&conecting_args, &id, &connect_args, 0);
return 0;
}
SEC("tracepoint/syscalls/sys_exit_connect")
int tracepoint_exit_connect(struct syscall_trace_exit *ctx) {
__u64 id = bpf_get_current_pid_tgid();
struct connect_args_t *connect_args;
connect_args = bpf_map_lookup_elem(&conecting_args, &id);
if (connect_args) {
process_connect(ctx, id, connect_args, ctx->ret);
}
bpf_map_delete_elem(&conecting_args, &id);
return 0;
}
SEC("kprobe/tcp_connect")
int tcp_connect(struct pt_regs *ctx) {
__u64 id = bpf_get_current_pid_tgid();
struct connect_args_t *connect_args = bpf_map_lookup_elem(&conecting_args, &id);;
if (connect_args) {
connect_args->sock = (void *)PT_REGS_PARM1(ctx);
}
return 0;
}
SEC("tracepoint/syscalls/sys_enter_accept")
int tracepoint_enter_accept(struct syscall_trace_enter *ctx) {
uint64_t id = bpf_get_current_pid_tgid();
if (tgid_should_trace(id >> 32) == false) {
return 0;
}
struct accept_args_t accept_args = {};
accept_args.addr = (struct sockaddr *)ctx->args[1];
accept_args.start_nacs = bpf_ktime_get_ns();
bpf_map_update_elem(&accepting_args, &id, &accept_args, 0);
return 0;
}
SEC("tracepoint/syscalls/sys_exit_accept")
int tracepoint_exit_accept(struct syscall_trace_exit *ctx) {
__u64 id = bpf_get_current_pid_tgid();
struct accept_args_t *accept_args = bpf_map_lookup_elem(&accepting_args, &id);
if (accept_args) {
process_accept(ctx, id, accept_args, ctx->ret);
}
bpf_map_delete_elem(&accepting_args, &id);
return 0;
}
SEC("kretprobe/sock_alloc")
int sock_alloc_ret(struct pt_regs *ctx) {
__u64 id = bpf_get_current_pid_tgid();
struct accept_args_t *accept_sock = bpf_map_lookup_elem(&accepting_args, &id);
if (accept_sock) {
struct socket *sock = (struct socket*)PT_REGS_RC(ctx);
accept_sock->socket = sock;
}
return 0;
}
SEC("kprobe/ip4_datagram_connect")
int ip4_udp_datagram_connect(struct pt_regs *ctx) {
__u64 id = bpf_get_current_pid_tgid();
struct connect_args_t *connect_args = bpf_map_lookup_elem(&conecting_args, &id);
if (connect_args) {
struct sock *sock = (struct sock*)PT_REGS_PARM1(ctx);
connect_args->sock = sock;
}
return 0;
}
#include "connect_conntrack.c"