diff --git a/observation/src/bindsnoop/bindsnoop.bpf.c b/observation/src/bindsnoop/bindsnoop.bpf.c index 9d1aa85e0f5b85ba6250bc952746d7d6399b5bc9..17a3d69af1fb8d5a0250009728870f39b7b20b79 100644 --- a/observation/src/bindsnoop/bindsnoop.bpf.c +++ b/observation/src/bindsnoop/bindsnoop.bpf.c @@ -14,6 +14,33 @@ const volatile pid_t target_pid = 0; const volatile bool ignore_errors = true; const volatile bool filter_by_port = false; +struct { + __uint(type, BPF_MAP_TYPE_CGROUP_ARRAY); + __type(key, u32); + __type(value, u32); + __uint(max_entries, 1); +} cgroup_map SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, MAX_ENTRIES); + __type(key, __u32); + __type(value, struct socket *); +} sockets SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_HASH); + __uint(max_entries, MAX_PORTS); + __type(key, __u16); + __type(value, __u16); +} ports SEC(".maps"); + +struct { + __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); + __type(key, __u32); + __type(value, __u32); +} events SEC(".maps"); + static int probe_entry(struct pt_regs *ctx, struct socket *socket) { __u64 pid_tgid = bpf_get_current_pid_tgid(); diff --git a/observation/src/bindsnoop/bindsnoop.c b/observation/src/bindsnoop/bindsnoop.c index 8cb65a493876f7773423cd75dbf0e5dd8a556afd..e515e03410ce10537db966657773cd97347875b0 100644 --- a/observation/src/bindsnoop/bindsnoop.c +++ b/observation/src/bindsnoop/bindsnoop.c @@ -23,6 +23,25 @@ static volatile sig_atomic_t exiting; const char *argp_program_version = "bindsnoop 0.1"; const char *argp_program_bug_address = "Jackie Liu "; +const char argp_program_doc[] = +"Trace bind syscalls.\n" +"\n" +"USAGE: bindsnoop [-h] [-t] [-x] [-p PID] [-P ports] [-c CG]\n" +"\n" +"EXAMPLES:\n" +" bindsnoop # trace all bind syscall\n" +" bindsnoop -t # include timestamps\n" +" bindsnoop -x # include errors on output\n" +" bindsnoop -p 1216 # only trace PID 1216\n" +" bindsnoop -c CG # Trace process under cgroupsPath CG\n" +" bindsnoop -P 80,81 # only trace port 80 and 81\n" +"\n" +"Socket options are reported as:\n" +" SOL_IP IP_FREEBIND F....\n" +" SOL_IP IP_TRANSPARENT .T...\n" +" SOL_IP IP_BIND_ADDRESS_NO_PORT ..N..\n" +" SOL_SOCKET SO_REUSEADDR ...R.\n" +" SOL_SOCKET SO_REUSEPORT ....r\n"; static const struct argp_option opts[] = { { "timestamp", 't', NULL, 0, "Include timestamp on output" }, @@ -33,4 +52,51 @@ static const struct argp_option opts[] = { { "verbose", 'v', NULL, 0, "Verbose debug output" }, { NULL, 'h', NULL, OPTION_HIDDEN, "Show the full help" }, {} -}; \ No newline at end of file +}; + +static error_t parse_arg(int key, char *arg, struct argp_state *state) +{ + char *port; + + switch (key) { + case 'p': + env.target_pid = argp_parse_pid(key, arg, state); + break; + case 'c': + env.cgroupspath = arg; + env.cg = true; + break; + case 'P': + if (!arg) { + warning("No ports specified\n"); + argp_usage(state); + } + env.target_ports = strdup(arg); + port = strtok(arg, ","); + while (port) { + int port_num = strtol(port, NULL, 10); + if (errno || port_num <= 0 || port_num > 65536) { + warning("Invalid ports: %s\n", arg); + argp_usage(state); + } + port = strtok(NULL, ","); + } + break; + case 'x': + env.ignore_errors = false; + break; + case 't': + env.emit_timestamp = true; + break; + case 'v': + env.verbose = true; + break; + case 'h': + argp_state_help(state, stderr, ARGP_HELP_STD_HELP); + break; + default: + return ARGP_ERR_UNKNOWN; + } + + return 0; +}