init
This commit is contained in:
+106
@@ -0,0 +1,106 @@
|
|||||||
|
#include <linux/bpf.h>
|
||||||
|
#define fuck_lsp
|
||||||
|
#include <bpf/bpf_endian.h>
|
||||||
|
#include <bpf/bpf_helpers.h>
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(a) sizeof(a) / sizeof(a[0])
|
||||||
|
|
||||||
|
#define ETH_HEADER_SIZE 14
|
||||||
|
|
||||||
|
#define ETHER_TYPE_FIELD_OFFSET 12
|
||||||
|
|
||||||
|
#define ETHER_TYPE_IPV4 0x0800
|
||||||
|
#define ETHER_TYPE_IPV6 0x86DD
|
||||||
|
|
||||||
|
#define IPV4_PROTOCOL_OFFSET 9
|
||||||
|
|
||||||
|
#define IPV6_NEXT_HEADER_OFFSET 6
|
||||||
|
|
||||||
|
#define IPV6_HEADER_SIZE 40
|
||||||
|
|
||||||
|
#define TCP_PROTO_ID 6
|
||||||
|
|
||||||
|
#define TCP_DST_PORT_OFFSET 2
|
||||||
|
|
||||||
|
#define TCP_FLAGS_OFFSET 13
|
||||||
|
|
||||||
|
#define SYN_MASK 0b00000010
|
||||||
|
|
||||||
|
#define LOW_PORT 4000
|
||||||
|
const __u16 open_ports[] = {4444};
|
||||||
|
#define HIGH_PORT 5000
|
||||||
|
|
||||||
|
char _license[] SEC("license") = "GPL";
|
||||||
|
|
||||||
|
static __always_inline const __u8 *get_tcp_data(const __u16 EtherType,
|
||||||
|
const __u8 *ip_packet_data,
|
||||||
|
const __u8 *data_end) {
|
||||||
|
if (EtherType == ETHER_TYPE_IPV4) {
|
||||||
|
|
||||||
|
// check protocol
|
||||||
|
const __u8 *protocol_id_ptr = ip_packet_data + IPV4_PROTOCOL_OFFSET;
|
||||||
|
if (protocol_id_ptr > data_end) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (*protocol_id_ptr == TCP_PROTO_ID) {
|
||||||
|
return ip_packet_data + ((*ip_packet_data & 0b00001111) * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (EtherType == ETHER_TYPE_IPV6) {
|
||||||
|
// check Next Header
|
||||||
|
const __u8 *protocol_id_ptr = ip_packet_data + IPV6_NEXT_HEADER_OFFSET;
|
||||||
|
if (protocol_id_ptr > data_end) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (*protocol_id_ptr == TCP_PROTO_ID) {
|
||||||
|
return ip_packet_data + IPV6_HEADER_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SEC("faker")
|
||||||
|
int xdp_drop_prog(struct xdp_md *ctx) {
|
||||||
|
const __u8 *data_end = (__u8 *)(long)ctx->data_end;
|
||||||
|
const __u8 *data = (__u8 *)(long)ctx->data;
|
||||||
|
|
||||||
|
const __u16 *EtherType_ptr = (__u16 *)(data + ETHER_TYPE_FIELD_OFFSET);
|
||||||
|
if (EtherType_ptr > (__u16 *)data_end) {
|
||||||
|
return XDP_PASS;
|
||||||
|
}
|
||||||
|
const __u16 EtherType = bpf_ntohs(*EtherType_ptr);
|
||||||
|
|
||||||
|
const __u8 *ip_packet_data = data + ETH_HEADER_SIZE;
|
||||||
|
|
||||||
|
const __u8 *tcp_packet_data =
|
||||||
|
get_tcp_data(EtherType, ip_packet_data, data_end);
|
||||||
|
if (!tcp_packet_data) {
|
||||||
|
return XDP_PASS;
|
||||||
|
} // return if not tcp or IP
|
||||||
|
|
||||||
|
const __u16 dst_port = bpf_ntohs(*(tcp_packet_data + TCP_DST_PORT_OFFSET));
|
||||||
|
|
||||||
|
if (dst_port < LOW_PORT) {
|
||||||
|
return XDP_PASS;
|
||||||
|
}
|
||||||
|
if (dst_port > HIGH_PORT) {
|
||||||
|
return XDP_PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (__u16 i = 0; i < ARRAY_SIZE(open_ports); i++) {
|
||||||
|
if (dst_port == open_ports[i]) {
|
||||||
|
return XDP_PASS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const __u8 tcp_flags = *(tcp_packet_data + TCP_FLAGS_OFFSET);
|
||||||
|
|
||||||
|
// check SYN
|
||||||
|
if (tcp_flags & SYN_MASK) {
|
||||||
|
if (bpf_get_prandom_u32() % 3 == 0) {
|
||||||
|
return XDP_DROP;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return XDP_PASS;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user