Update project
This commit is contained in:
		
							parent
							
								
									b45084ec06
								
							
						
					
					
						commit
						1f53a2b4d2
					
				
							
								
								
									
										9
									
								
								common.h
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										9
									
								
								common.h
									
									
									
									
									
								
							@ -1,11 +1,18 @@
 | 
				
			|||||||
#ifndef H_COMMON
 | 
					#ifndef H_COMMON
 | 
				
			||||||
#define H_COMMON
 | 
					#define H_COMMON
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef unsigned char __u8;
 | 
				
			||||||
 | 
					typedef unsigned short __u16;
 | 
				
			||||||
 | 
					typedef unsigned int __u32;
 | 
				
			||||||
 | 
					typedef unsigned long long __u64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct reset {
 | 
					struct reset {
 | 
				
			||||||
    __u8 saddr[4];
 | 
					    __u8 saddr[4];
 | 
				
			||||||
    __u8 daddr[4];
 | 
					    __u8 daddr[4];
 | 
				
			||||||
    __u16 sport;
 | 
					    __u16 sport;
 | 
				
			||||||
    __u16 dport;
 | 
					    __u16 dport;
 | 
				
			||||||
};
 | 
					    __u16 family;
 | 
				
			||||||
 | 
					    __u16 proto;
 | 
				
			||||||
 | 
					} __attribute__((packed));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										5
									
								
								exec.sh
									
									
									
									
									
										Executable file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										5
									
								
								exec.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					clang-11 -g -O2 -target bpf -c tp_tcp.c -o tp_tcp.o && \
 | 
				
			||||||
 | 
					gcc load_bpf.c -o load_bpf -lbpf && \
 | 
				
			||||||
 | 
					sudo ./load_bpf
 | 
				
			||||||
							
								
								
									
										24
									
								
								influxdb.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										24
									
								
								influxdb.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					import influxdb_client
 | 
				
			||||||
 | 
					from influxdb_client import InfluxDBClient, Point, WritePrecision
 | 
				
			||||||
 | 
					from influxdb_client.client.write_api import SYNCHRONOUS
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#token = os.environ.get("dQV0BbJvy7W9Bool6FGh1ryb_uXBNqZB8BlJqb8yC4yNB8RTDSooT5hixoqMf8cBeXUXTRUdmkwlxnkI9PCsBA==")
 | 
				
			||||||
 | 
					token = os.environ.get("sySU58aCfMdTGtBTttduzSS_x_4CBI1twpicYw4Idq9abZWGsAXdbvww2wWmwmLDTtrALAx4Q0wZK9PUIr4ejg==")
 | 
				
			||||||
 | 
					org = "gbucchino"
 | 
				
			||||||
 | 
					url = "http://192.168.1.68:8086"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					write_client = influxdb_client.InfluxDBClient(url=url, token=token, org=org)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bucket="tcp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					write_api = write_client.write_api(write_options=SYNCHRONOUS)
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					for value in range(5):
 | 
				
			||||||
 | 
					    point = (
 | 
				
			||||||
 | 
					      Point("measurement1")
 | 
				
			||||||
 | 
					      .tag("tagname1", "tagvalue1")
 | 
				
			||||||
 | 
					      .field("field1", value)
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    write_api.write(bucket=bucket, org="gbucchino", record=point)
 | 
				
			||||||
 | 
					    time.sleep(1) # separate points by 1 second
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								load_bpf
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								load_bpf
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										73
									
								
								load_bpf.c
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										73
									
								
								load_bpf.c
									
									
									
									
									
								
							@ -5,6 +5,7 @@
 | 
				
			|||||||
#include <sys/socket.h>
 | 
					#include <sys/socket.h>
 | 
				
			||||||
#include <arpa/inet.h>
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
#include "common.h"
 | 
					#include "common.h"
 | 
				
			||||||
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void clean_obj(struct bpf_object *obj){
 | 
					static void clean_obj(struct bpf_object *obj){
 | 
				
			||||||
    printf("Cleaning\n");
 | 
					    printf("Cleaning\n");
 | 
				
			||||||
@ -18,8 +19,12 @@ int main(void){
 | 
				
			|||||||
    struct reset s_reset;
 | 
					    struct reset s_reset;
 | 
				
			||||||
    int err;
 | 
					    int err;
 | 
				
			||||||
    int map_fd;
 | 
					    int map_fd;
 | 
				
			||||||
    long long stats;
 | 
					    int map_fd_filter_family;
 | 
				
			||||||
 | 
					    int map_fd_filter_sport;
 | 
				
			||||||
 | 
					    int map_fd_index;
 | 
				
			||||||
    int keys = 0;
 | 
					    int keys = 0;
 | 
				
			||||||
 | 
					    int indexPackets = 0;
 | 
				
			||||||
 | 
					    int index = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    obj = bpf_object__open_file(fileObj, NULL);
 | 
					    obj = bpf_object__open_file(fileObj, NULL);
 | 
				
			||||||
    if (!obj){
 | 
					    if (!obj){
 | 
				
			||||||
@ -27,19 +32,20 @@ int main(void){
 | 
				
			|||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    //LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_MMAPABLE);
 | 
					    //LIBBPF_OPTS(bpf_map_create_opts, opts, .map_flags = BPF_F_MMAPABLE);
 | 
				
			||||||
    map_fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(int), sizeof(struct reset), 4096, BPF_ANY);
 | 
					    //map_fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(int), sizeof(struct reset), 4096, BPF_ANY);
 | 
				
			||||||
    printf("Create map: %d\n", map_fd);
 | 
					    //map_fd = bpf_create_map(BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(struct reset), 4096, BPF_ANY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    err = bpf_object__load(obj);
 | 
					    err = bpf_object__load(obj);
 | 
				
			||||||
    printf("Object loaded: %d\n", err);
 | 
					 | 
				
			||||||
    if (err){
 | 
					    if (err){
 | 
				
			||||||
        printf("Failed to load object\n");
 | 
					        printf("Failed to load object\n");
 | 
				
			||||||
 | 
					        clean_obj(obj);
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    program = bpf_object__find_program_by_name(obj, "tcp_retransmit");
 | 
					    program = bpf_object__find_program_by_name(obj, "tcp_retransmit");
 | 
				
			||||||
    if (!program){
 | 
					    if (!program){
 | 
				
			||||||
        printf("Failed to find the program\n");
 | 
					        printf("Failed to find the program\n");
 | 
				
			||||||
 | 
					        clean_obj(obj);
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -51,7 +57,25 @@ int main(void){
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    map_fd = bpf_object__find_map_fd_by_name(obj, "tcp_reset_stats");
 | 
					    map_fd = bpf_object__find_map_fd_by_name(obj, "tcp_reset_stats");
 | 
				
			||||||
    printf("Map fd: %d\n", map_fd);
 | 
					    if (map_fd < 0){
 | 
				
			||||||
 | 
					        printf("Failed to find the map 'tcp_reset_stats'\n");
 | 
				
			||||||
 | 
					        clean_obj(obj);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    map_fd_filter_family = bpf_object__find_map_fd_by_name(obj, "filter_family");
 | 
				
			||||||
 | 
					    if (map_fd_filter_family < 0){
 | 
				
			||||||
 | 
					        printf("Failed to find the map 'filter_family'\n");
 | 
				
			||||||
 | 
					        clean_obj(obj);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    map_fd_index = bpf_object__find_map_fd_by_name(obj, "tcp_stats_index");
 | 
				
			||||||
 | 
					    if (map_fd_index < 0){
 | 
				
			||||||
 | 
					        printf("Failed to find the map 'tcp_stats_index'\n");
 | 
				
			||||||
 | 
					        clean_obj(obj);
 | 
				
			||||||
 | 
					        return -1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct bpf_link *link = bpf_program__attach(program);
 | 
					    struct bpf_link *link = bpf_program__attach(program);
 | 
				
			||||||
    if (!link){
 | 
					    if (!link){
 | 
				
			||||||
@ -59,15 +83,40 @@ int main(void){
 | 
				
			|||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Sepcify our filters
 | 
				
			||||||
 | 
					    /*
 | 
				
			||||||
 | 
					     * IPv4: AF_INET  -> 2
 | 
				
			||||||
 | 
					     * IPv6: AF_INET6 -> 10
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    __s16 f = AF_INET;
 | 
				
			||||||
 | 
					    err = bpf_map_update_elem(map_fd_filter_family, &keys, &f, BPF_ANY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    while(1){
 | 
					    while(1){
 | 
				
			||||||
        int e = bpf_map_lookup_elem(map_fd, &keys, &s_reset);
 | 
					        // Get the index
 | 
				
			||||||
        if (e == 0){
 | 
					        // and we compare with the local variable
 | 
				
			||||||
            //printf("%lld\n", stats);
 | 
					        // If it's different, we get the new variable
 | 
				
			||||||
            struct in_addr *src = (struct in_addr*)&s_reset.saddr;
 | 
					        err = bpf_map_lookup_elem(map_fd_index, &keys, &indexPackets);
 | 
				
			||||||
            struct in_addr *dest = (struct in_addr*)&s_reset.daddr;
 | 
					
 | 
				
			||||||
            printf("Sport: %d; dport: %d %s %s\n", s_reset.sport, s_reset.dport, inet_ntoa(*src), inet_ntoa(*dest));
 | 
					        // We have a new packet
 | 
				
			||||||
 | 
					        if (indexPackets > index){
 | 
				
			||||||
 | 
					            index = indexPackets;
 | 
				
			||||||
 | 
					            printf("Index: %d %d\n", index, indexPackets);    
 | 
				
			||||||
 | 
					            err = bpf_map_lookup_elem(map_fd, &keys, &s_reset);
 | 
				
			||||||
 | 
					            if (err == 0){
 | 
				
			||||||
 | 
					                struct in_addr *src = (struct in_addr*)&s_reset.saddr;
 | 
				
			||||||
 | 
					                struct in_addr *dest = (struct in_addr*)&s_reset.daddr;
 | 
				
			||||||
 | 
					                char *s = inet_ntoa(*src);
 | 
				
			||||||
 | 
					                char tmp[35];
 | 
				
			||||||
 | 
					                memcpy(tmp, s, 35);
 | 
				
			||||||
 | 
					                char *d = inet_ntoa(*dest);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                printf("Sport: %d; dport: %d %d %d %s - %s\n", s_reset.sport, s_reset.dport, s_reset.family, s_reset.proto, tmp, d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            memset(&s_reset, 0, sizeof(struct reset));
 | 
				
			||||||
 | 
					            //sleep(1);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
         
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								main
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								main
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										21
									
								
								main.c
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										21
									
								
								main.c
									
									
									
									
									
								
							@ -1,12 +1,25 @@
 | 
				
			|||||||
#define BPF_NO_GLOBAL_DATA
 | 
					#define BPF_NO_GLOBAL_DATA
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <linux/bpf.h>
 | 
					#include "ic.h"
 | 
				
			||||||
#include <bpf/bpf_helpers.h>
 | 
					 | 
				
			||||||
#include <bpf/bpf_tracing.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char *argv[], char *argp[]){
 | 
					int main(int argc, char *argv[], char *argp[]){
 | 
				
			||||||
    printf("Hello world\n");
 | 
					    printf("Hello world\n");
 | 
				
			||||||
    execve("/usr/bin/ls", argv, argp);
 | 
					    char buf[300];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ic_influx_database("192.168.1.68", 8086, "tcp");
 | 
				
			||||||
 | 
					    ic_influx_userpw("admin", "Geta,Fte#");
 | 
				
			||||||
 | 
					    ic_debug(2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    snprintf(buf, 300, "host=192.168.1.68");
 | 
				
			||||||
 | 
					    ic_tags(buf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ic_measure("tcp_reset");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ic_string("ipsrc", "192.168.1.1");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ic_measureend();
 | 
				
			||||||
 | 
					    ic_push();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										9
									
								
								main.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										9
									
								
								main.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					#!/usr/bin/env python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from bcc import BPF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					with open("tp_tcp.c", 'r') as f:
 | 
				
			||||||
 | 
					    data = f.read()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					b = BPF(text=data)
 | 
				
			||||||
 | 
					#b = BPF(src_file="tp_tcp_py.c")
 | 
				
			||||||
							
								
								
									
										30
									
								
								prometheus.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										30
									
								
								prometheus.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,30 @@
 | 
				
			|||||||
 | 
					from prometheus_client import start_http_server, Summary, Counter
 | 
				
			||||||
 | 
					import random
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Create a metric to track time spent and requests made.
 | 
				
			||||||
 | 
					#REQUEST_TIME = Summary('request_processing_seconds', 'Time spent processing request', 'foo')
 | 
				
			||||||
 | 
					#REQUEST_TIME = Summary('request_processing_seconds', 'foo')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Decorate function with metric.
 | 
				
			||||||
 | 
					#@REQUEST_TIME.time()
 | 
				
			||||||
 | 
					#def process_request(t):
 | 
				
			||||||
 | 
					#    """A dummy function that takes some time."""
 | 
				
			||||||
 | 
					#    time.sleep(t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					c = Counter("tcp_reset_stats", "TCP RST stats")
 | 
				
			||||||
 | 
					def tcp_rst_stats():
 | 
				
			||||||
 | 
					    c.inc()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    # Start up the server to expose the metrics.
 | 
				
			||||||
 | 
					    start_http_server(8000)
 | 
				
			||||||
 | 
					    # Generate some requests.
 | 
				
			||||||
 | 
					    while True:
 | 
				
			||||||
 | 
					        # process_request(random.random())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Count
 | 
				
			||||||
 | 
					        print("Inc")
 | 
				
			||||||
 | 
					        tcp_rst_stats()
 | 
				
			||||||
 | 
					        time.sleep(30)
 | 
				
			||||||
							
								
								
									
										124
									
								
								tp_tcp.c
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										124
									
								
								tp_tcp.c
									
									
									
									
									
								
							@ -1,6 +1,7 @@
 | 
				
			|||||||
#define BPF_NO_GLOBAL_DATA
 | 
					#define BPF_NO_GLOBAL_DATA
 | 
				
			||||||
//#define __TARGET_ARCH_x86
 | 
					//#define __TARGET_ARCH_x86
 | 
				
			||||||
#include "vmlinux.h"
 | 
					#include "vmlinux.h"
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
#include <bpf/bpf_helpers.h>
 | 
					#include <bpf/bpf_helpers.h>
 | 
				
			||||||
#include <bpf/bpf_tracing.h>
 | 
					#include <bpf/bpf_tracing.h>
 | 
				
			||||||
#include <bpf/bpf_core_read.h>
 | 
					#include <bpf/bpf_core_read.h>
 | 
				
			||||||
@ -9,11 +10,11 @@
 | 
				
			|||||||
char LICENSE[] SEC("license") = "Dual BSD/GPL";
 | 
					char LICENSE[] SEC("license") = "Dual BSD/GPL";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct ctx_reset {
 | 
					struct ctx_receive_reset {
 | 
				
			||||||
    __u16 common_type;
 | 
					    __u16 common_type; // unsigned short
 | 
				
			||||||
    __u8 common_flags;
 | 
					    __u8 common_flags; // unsigned char
 | 
				
			||||||
    __u8 common_count;
 | 
					    __u8 common_count; // unsigned char 
 | 
				
			||||||
    __s32 pid;
 | 
					    __s32 pid;         // int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const void *skaddr;
 | 
					    const void *skaddr;
 | 
				
			||||||
    __u16 sport; 
 | 
					    __u16 sport; 
 | 
				
			||||||
@ -25,17 +26,59 @@ struct ctx_reset {
 | 
				
			|||||||
    __u8 daddr_v6[16];
 | 
					    __u8 daddr_v6[16];
 | 
				
			||||||
    __u64 sock_cookie;
 | 
					    __u64 sock_cookie;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					struct ctx_send_reset {
 | 
				
			||||||
 | 
					    __u16 common_type; // unsigned short
 | 
				
			||||||
 | 
					    __u8 common_flags; // unsigned char
 | 
				
			||||||
 | 
					    __u8 common_count; // unsigned char
 | 
				
			||||||
 | 
					    __s32 pid;         // int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const void *skbaddr;
 | 
				
			||||||
 | 
					    const void *skaddr;
 | 
				
			||||||
 | 
					    __s32 state;        // int
 | 
				
			||||||
 | 
					    __u16 sport; 
 | 
				
			||||||
 | 
					    __u16 dport;
 | 
				
			||||||
 | 
					    __u8 saddr[4];
 | 
				
			||||||
 | 
					    __u8 daddr[4];
 | 
				
			||||||
 | 
					    __u8 saddr_v6[16];
 | 
				
			||||||
 | 
					    __u8 daddr_v6[16];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct {
 | 
					struct {
 | 
				
			||||||
//    __uint(type, BPF_MAP_TYPE_ARRAY);
 | 
					    __uint(type, BPF_MAP_TYPE_ARRAY);
 | 
				
			||||||
    __uint(type, BPF_MAP_TYPE_HASH);
 | 
					 | 
				
			||||||
    __uint(max_entries, 4096);
 | 
					    __uint(max_entries, 4096);
 | 
				
			||||||
    __type(key, int);
 | 
					    __type(key, 1);
 | 
				
			||||||
    __type(value, sizeof(struct reset));
 | 
					    __type(value, __s32);
 | 
				
			||||||
 | 
					} tcp_stats_index SEC(".maps");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct {
 | 
				
			||||||
 | 
					    __uint(type, BPF_MAP_TYPE_ARRAY);
 | 
				
			||||||
 | 
					    __uint(max_entries, 4096);
 | 
				
			||||||
 | 
					    __type(key, 4);
 | 
				
			||||||
 | 
					    __type(value, struct reset);
 | 
				
			||||||
} tcp_reset_stats SEC(".maps");
 | 
					} tcp_reset_stats SEC(".maps");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct {
 | 
				
			||||||
 | 
					    __uint(type, BPF_MAP_TYPE_ARRAY);
 | 
				
			||||||
 | 
					    __uint(max_entries, 1);
 | 
				
			||||||
 | 
					    __type(key, __s32);
 | 
				
			||||||
 | 
					    __type(value, __u16);
 | 
				
			||||||
 | 
					} filter_family SEC(".maps");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct {
 | 
				
			||||||
 | 
					    __uint(type, BPF_MAP_TYPE_ARRAY);
 | 
				
			||||||
 | 
					    __uint(max_entries, 1);
 | 
				
			||||||
 | 
					    __type(key, __s32);
 | 
				
			||||||
 | 
					    __type(value, __u16);
 | 
				
			||||||
 | 
					} filter_sport SEC(".maps");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// sudo tcpdump -i any 'tcp[13] & 4 != 0' -n -> filter TCP reset flags
 | 
					// sudo tcpdump -i any 'tcp[13] & 4 != 0' -n -> filter TCP reset flags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This project do not trace any sniffing ports, because, the tracepoint tcp:tcp_send_reset
 | 
				
			||||||
 | 
					 * works only for an establish socket, but, if you have a lot of TCP RST, you can have 
 | 
				
			||||||
 | 
					 * an issue with your system
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Identify all tracepoint available
 | 
					 * Identify all tracepoint available
 | 
				
			||||||
 *   - cat /sys/kernel/tracing/available_events
 | 
					 *   - cat /sys/kernel/tracing/available_events
 | 
				
			||||||
@ -53,33 +96,54 @@ struct {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//SEC("tp/tcp_retransmit_synack")
 | 
					//SEC("tp/tcp_retransmit_synack")
 | 
				
			||||||
SEC("tracepoint/tcp/tcp_receive_reset")
 | 
					//SEC("tracepoint/tcp/tcp_receive_reset")
 | 
				
			||||||
//int tcp_retransmit(struct sock *sk){
 | 
					SEC("tracepoint/tcp/tcp_send_reset")
 | 
				
			||||||
int tcp_retransmit(struct ctx_reset *ctx){
 | 
					int tcp_retransmit(struct ctx_send_reset *ctx){
 | 
				
			||||||
    long long *stats;
 | 
					    struct reset s_reset = {};
 | 
				
			||||||
    struct reset *s_reset;
 | 
					    int *index;
 | 
				
			||||||
    int keys = 0;
 | 
					    int keys = 0;
 | 
				
			||||||
 | 
					    struct sock *sk;
 | 
				
			||||||
 | 
					    __u16 family;
 | 
				
			||||||
 | 
					    __s16 *f_family;
 | 
				
			||||||
 | 
					    __u16 proto;
 | 
				
			||||||
 | 
					    int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s_reset = bpf_map_lookup_elem(&tcp_reset_stats, &keys);
 | 
					    memset(&s_reset, 0, sizeof(struct reset));
 | 
				
			||||||
    if (!s_reset)
 | 
					
 | 
				
			||||||
 | 
					    // Get filter
 | 
				
			||||||
 | 
					    sk = (struct sock*)ctx->skaddr;
 | 
				
			||||||
 | 
					    f_family = bpf_map_lookup_elem(&filter_family, &keys);
 | 
				
			||||||
 | 
					    if (!f_family)
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!ctx)
 | 
					    index = bpf_map_lookup_elem(&tcp_stats_index, &keys);
 | 
				
			||||||
 | 
					    if (!index)
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //*stats += 1;
 | 
					    
 | 
				
			||||||
    s_reset->saddr[0] = ctx->saddr[0];
 | 
					    // Get the family of the socket
 | 
				
			||||||
    s_reset->saddr[1] = ctx->saddr[1];
 | 
					    bpf_probe_read_kernel(&family, sizeof(family), &sk->__sk_common.skc_family);
 | 
				
			||||||
    s_reset->saddr[2] = ctx->saddr[2];
 | 
					    if (family != *f_family)
 | 
				
			||||||
    s_reset->saddr[3] = ctx->saddr[3];
 | 
					        return 0;
 | 
				
			||||||
    /*s_reset->daddr[0] = ctx->daddr[0];
 | 
					 | 
				
			||||||
    s_reset->daddr[1] = ctx->daddr[1];
 | 
					 | 
				
			||||||
    s_reset->daddr[2] = ctx->daddr[2];
 | 
					 | 
				
			||||||
    s_reset->daddr[3] = ctx->daddr[3];*/
 | 
					 | 
				
			||||||
    s_reset->sport = ctx->sport;
 | 
					 | 
				
			||||||
    s_reset->dport = ctx->dport;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //bpf_printk("BPF detected TCP received reset %d - %d %d\n", *stats, dport, sport);
 | 
					    // Get and update the index in the map
 | 
				
			||||||
    bpf_printk("BPF detected TCP received reset %d %d\n", s_reset->sport, s_reset->dport);
 | 
					    *index += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Proto type: here it's 6 (TCP)
 | 
				
			||||||
 | 
					    bpf_probe_read_kernel(&proto, sizeof(proto), &sk->sk_protocol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(s_reset.saddr, ctx->saddr, 4);
 | 
				
			||||||
 | 
					    memcpy(s_reset.daddr, ctx->daddr, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //bpf_probe_read_kernel(&s_reset.saddr, 4, &ctx->saddr);
 | 
				
			||||||
 | 
					    //bpf_probe_read_kernel(&s_reset.daddr, 4, &ctx->daddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s_reset.sport = ctx->sport;
 | 
				
			||||||
 | 
					    s_reset.dport = ctx->dport;
 | 
				
			||||||
 | 
					    s_reset.family = family;
 | 
				
			||||||
 | 
					    s_reset.proto = proto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bpf_printk("BPF detected TCP send reset %d %d", s_reset.sport, s_reset.dport);
 | 
				
			||||||
 | 
					    bpf_map_update_elem(&tcp_reset_stats, &keys, &s_reset, BPF_ANY);
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								tp_tcp.o
									
									
									
									
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										
											BIN
										
									
								
								tp_tcp.o
									
									
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										149
									
								
								tp_tcp_py.c
									
									
									
									
									
										Normal file
									
								
							
							
								
								
								
								
								
									
									
								
							
						
						
									
										149
									
								
								tp_tcp_py.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,149 @@
 | 
				
			|||||||
 | 
					#define BPF_NO_GLOBAL_DATA
 | 
				
			||||||
 | 
					//#define __TARGET_ARCH_x86
 | 
				
			||||||
 | 
					#include "vmlinux.h"
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <bpf/bpf_helpers.h>
 | 
				
			||||||
 | 
					#include <bpf/bpf_tracing.h>
 | 
				
			||||||
 | 
					#include <bpf/bpf_core_read.h>
 | 
				
			||||||
 | 
					#include "common.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char LICENSE[] SEC("license") = "Dual BSD/GPL";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct ctx_receive_reset {
 | 
				
			||||||
 | 
					    __u16 common_type; // unsigned short
 | 
				
			||||||
 | 
					    __u8 common_flags; // unsigned char
 | 
				
			||||||
 | 
					    __u8 common_count; // unsigned char 
 | 
				
			||||||
 | 
					    __s32 pid;         // int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const void *skaddr;
 | 
				
			||||||
 | 
					    __u16 sport; 
 | 
				
			||||||
 | 
					    __u16 dport;
 | 
				
			||||||
 | 
					    __u16 family;
 | 
				
			||||||
 | 
					    __u8 saddr[4];
 | 
				
			||||||
 | 
					    __u8 daddr[4];
 | 
				
			||||||
 | 
					    __u8 saddr_v6[16];
 | 
				
			||||||
 | 
					    __u8 daddr_v6[16];
 | 
				
			||||||
 | 
					    __u64 sock_cookie;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					struct ctx_send_reset {
 | 
				
			||||||
 | 
					    __u16 common_type; // unsigned short
 | 
				
			||||||
 | 
					    __u8 common_flags; // unsigned char
 | 
				
			||||||
 | 
					    __u8 common_count; // unsigned char
 | 
				
			||||||
 | 
					    __s32 pid;         // int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const void *skbaddr;
 | 
				
			||||||
 | 
					    const void *skaddr;
 | 
				
			||||||
 | 
					    __s32 state;        // int
 | 
				
			||||||
 | 
					    __u16 sport; 
 | 
				
			||||||
 | 
					    __u16 dport;
 | 
				
			||||||
 | 
					    __u8 saddr[4];
 | 
				
			||||||
 | 
					    __u8 daddr[4];
 | 
				
			||||||
 | 
					    __u8 saddr_v6[16];
 | 
				
			||||||
 | 
					    __u8 daddr_v6[16];
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct {
 | 
				
			||||||
 | 
					    __uint(type, BPF_MAP_TYPE_ARRAY);
 | 
				
			||||||
 | 
					    __uint(max_entries, 4096);
 | 
				
			||||||
 | 
					    __type(key, 1);
 | 
				
			||||||
 | 
					    __type(value, __s32);
 | 
				
			||||||
 | 
					} tcp_stats_index SEC(".maps");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct {
 | 
				
			||||||
 | 
					    __uint(type, BPF_MAP_TYPE_ARRAY);
 | 
				
			||||||
 | 
					    __uint(max_entries, 4096);
 | 
				
			||||||
 | 
					    __type(key, 4);
 | 
				
			||||||
 | 
					    __type(value, struct reset);
 | 
				
			||||||
 | 
					} tcp_reset_stats SEC(".maps");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct {
 | 
				
			||||||
 | 
					    __uint(type, BPF_MAP_TYPE_ARRAY);
 | 
				
			||||||
 | 
					    __uint(max_entries, 1);
 | 
				
			||||||
 | 
					    __type(key, __s32);
 | 
				
			||||||
 | 
					    __type(value, __u16);
 | 
				
			||||||
 | 
					} filter_family SEC(".maps");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct {
 | 
				
			||||||
 | 
					    __uint(type, BPF_MAP_TYPE_ARRAY);
 | 
				
			||||||
 | 
					    __uint(max_entries, 1);
 | 
				
			||||||
 | 
					    __type(key, __s32);
 | 
				
			||||||
 | 
					    __type(value, __u16);
 | 
				
			||||||
 | 
					} filter_sport SEC(".maps");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// sudo tcpdump -i any 'tcp[13] & 4 != 0' -n -> filter TCP reset flags
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * This project do not trace any sniffing ports, because, the tracepoint tcp:tcp_send_reset
 | 
				
			||||||
 | 
					 * works only for an establish socket, but, if you have a lot of TCP RST, you can have 
 | 
				
			||||||
 | 
					 * an issue with your system
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Identify all tracepoint available
 | 
				
			||||||
 | 
					 *   - cat /sys/kernel/tracing/available_events
 | 
				
			||||||
 | 
					 * Enable an event:
 | 
				
			||||||
 | 
					 *   - echo 'tcp_receive_reset' >> /sys/kernel/tracing/set_event -> important to add the '>>'
 | 
				
			||||||
 | 
					 * Docs: https://docs.kernel.org/trace/events.html
 | 
				
			||||||
 | 
					 * https://events.linuxfoundation.org/wp-content/uploads/2022/10/elena-zannoni-tracing-tutorial-LF-2021.pdf
 | 
				
			||||||
 | 
					 * https://docs.kernel.org/trace/tracepoints.html
 | 
				
			||||||
 | 
					 * Why we need to detect RST:
 | 
				
			||||||
 | 
					 * When we scan the port, the scanner send an SYN flag and if the port is block, we receive a RST flag:
 | 
				
			||||||
 | 
					 * listening on any, link-type LINUX_SLL2 (Linux cooked v2), snapshot length 262144 bytes
 | 
				
			||||||
 | 
					10:48:28.531295 lo    In  IP localhost.43961 > localhost.tproxy: Flags [S], seq 2197047013, win 1024, options [mss 1460], length 0
 | 
				
			||||||
 | 
					10:48:28.531306 lo    In  IP localhost.tproxy > localhost.43961: Flags [R.], seq 0, ack 2197047014, win 0, length 0
 | 
				
			||||||
 | 
					 * But we can also block all receive RST: iptables -I INPUT -p tcp --dport <port> -j REJECT --reject-with tcp-reset
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//SEC("tp/tcp_retransmit_synack")
 | 
				
			||||||
 | 
					//SEC("tracepoint/tcp/tcp_receive_reset")
 | 
				
			||||||
 | 
					//SEC("tracepoint/tcp/tcp_send_reset")
 | 
				
			||||||
 | 
					int tcp_retransmit(struct ctx_send_reset *ctx){
 | 
				
			||||||
 | 
					    struct reset s_reset = {};
 | 
				
			||||||
 | 
					    int *index;
 | 
				
			||||||
 | 
					    int keys = 0;
 | 
				
			||||||
 | 
					    struct sock *sk;
 | 
				
			||||||
 | 
					    __u16 family;
 | 
				
			||||||
 | 
					    __s16 *f_family;
 | 
				
			||||||
 | 
					    __u16 proto;
 | 
				
			||||||
 | 
					    int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memset(&s_reset, 0, sizeof(struct reset));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get filter
 | 
				
			||||||
 | 
					    sk = (struct sock*)ctx->skaddr;
 | 
				
			||||||
 | 
					    f_family = bpf_map_lookup_elem(&filter_family, &keys);
 | 
				
			||||||
 | 
					    if (!f_family)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    index = bpf_map_lookup_elem(&tcp_stats_index, &keys);
 | 
				
			||||||
 | 
					    if (!index)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Get the family of the socket
 | 
				
			||||||
 | 
					    bpf_probe_read_kernel(&family, sizeof(family), &sk->__sk_common.skc_family);
 | 
				
			||||||
 | 
					    if (family != *f_family)
 | 
				
			||||||
 | 
					        return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Get and update the index in the map
 | 
				
			||||||
 | 
					    *index += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Proto type: here it's 6 (TCP)
 | 
				
			||||||
 | 
					    bpf_probe_read_kernel(&proto, sizeof(proto), &sk->sk_protocol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    memcpy(s_reset.saddr, ctx->saddr, 4);
 | 
				
			||||||
 | 
					    memcpy(s_reset.daddr, ctx->daddr, 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //bpf_probe_read_kernel(&s_reset.saddr, 4, &ctx->saddr);
 | 
				
			||||||
 | 
					    //bpf_probe_read_kernel(&s_reset.daddr, 4, &ctx->daddr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s_reset.sport = ctx->sport;
 | 
				
			||||||
 | 
					    s_reset.dport = ctx->dport;
 | 
				
			||||||
 | 
					    s_reset.family = family;
 | 
				
			||||||
 | 
					    s_reset.proto = proto;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bpf_printk("BPF detected TCP send reset %d %d", s_reset.sport, s_reset.dport);
 | 
				
			||||||
 | 
					    bpf_map_update_elem(&tcp_reset_stats, &keys, &s_reset, BPF_ANY);
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user