/* ============================================================================
 * bpf_types.h — Structures partagées entre les programmes eBPF (C) et Go
 * ============================================================================ */

#pragma once

/* vmlinux.h (inclus dans les .c) fournit déjà tous les types kernel (__u32, etc.).
 * N'inclure linux/types.h que si vmlinux.h n'est pas présent. */
#ifndef __VMLINUX_H__
#include <linux/types.h>
#endif
#include <bpf/bpf_helpers.h>

/* Constantes TC (linux/pkt_cls.h) — non incluses via vmlinux.h */
#ifndef TC_ACT_OK
#define TC_ACT_UNSPEC   (-1)
#define TC_ACT_OK       0
#define TC_ACT_RECLASSIFY 1
#define TC_ACT_SHOT     2
#define TC_ACT_PIPE     3
#define TC_ACT_STOLEN   4
#define TC_ACT_QUEUED   5
#define TC_ACT_REPEAT   6
#define TC_ACT_REDIRECT 7
#endif

/* ---------------------------------------------------------------------------
 * Événement TCP SYN : émis pour chaque nouvelle connexion TCP observée
 * ---------------------------------------------------------------------------*/
struct tcp_syn_event {
    __u32 src_ip;               /* adresse source (host byte order, via bpf_ntohl) */
    __u32 dst_ip;               /* adresse destination (host byte order, via bpf_ntohl) */
    __u16 src_port;             /* port source (host byte order) */
    __u16 dst_port;             /* port destination (host byte order) */
    __u8  ttl;                  /* TTL IP */
    __u8  df_bit;               /* bit Don't Fragment (1 = DF activé) */
    __u16 ip_id;                /* champ identification IP */
    __u16 window_size;          /* fenêtre TCP initiale */
    __u8  window_scale;         /* facteur d'échelle (0xFF = absent) */
    __u16 mss;                  /* MSS TCP (0 = absent) */
    __u8  tcp_options_raw[40];  /* options TCP brutes */
    __u8  tcp_options_len;      /* longueur des options TCP */
    __u64 timestamp_ns;         /* horodatage kernel en nanosecondes */
} __attribute__((packed));

/* ---------------------------------------------------------------------------
 * Événement TLS ClientHello : émis quand un ClientHello TLS est détecté
 * ---------------------------------------------------------------------------*/
struct tls_hello_event {
    __u32 src_ip;               /* adresse source (host byte order, via bpf_ntohl) */
    __u16 src_port;             /* port source (host byte order) */
    __u8  payload[2048];         /* payload ClientHello brut (capturé jusqu'à 2048 octets) */
    __u16 payload_len;          /* longueur effective du payload */
    __u64 timestamp_ns;         /* horodatage kernel */
} __attribute__((packed));

/* ---------------------------------------------------------------------------
 * Événement SSL data : émis par les uprobes SSL_read/SSL_write
 * ---------------------------------------------------------------------------*/
struct ssl_data_event {
    __u64 pid_tgid;             /* PID+TGID du processus */
    __u32 fd;                   /* descripteur de fichier socket */
    __u32 src_ip;               /* IP source (rempli via accept_map) */
    __u16 src_port;             /* port source */
    __u8  data[4096];           /* données déchiffrées */
    __u32 data_len;             /* longueur effective des données */
    __u64 timestamp_ns;         /* horodatage kernel */
    __u8  direction;            /* 0 = lecture (client→serveur), 1 = écriture */
} __attribute__((packed));

/* ---------------------------------------------------------------------------
 * Événement accept : émis lors de chaque appel accept4 réussi
 * ---------------------------------------------------------------------------*/
struct accept_event {
    __u64 pid_tgid;             /* PID+TGID du processus */
    __u32 fd;                   /* nouveau fd retourné par accept4 */
    __u32 src_ip;               /* adresse IP du client (peer) */
    __u16 src_port;             /* port du client */
    __u64 timestamp_ns;         /* horodatage kernel */
} __attribute__((packed));

/* ---------------------------------------------------------------------------
 * Événement HTTP en clair : émis pour chaque segment TCP porteur d'un
 * payload HTTP (port 80 ou 8080). Un seul segment par requête est capturé
 * (le premier, qui contient la request-line et les en-têtes).
 * ---------------------------------------------------------------------------*/
struct http_plain_event {
    __u32 src_ip;               /* adresse source (host byte order) */
    __u32 dst_ip;               /* adresse destination (host byte order) */
    __u16 src_port;             /* port source (host byte order) */
    __u16 dst_port;             /* port destination 80 ou 8080 */
    __u8  payload[4096];        /* payload TCP brut (request-line + headers) */
    __u16 payload_len;          /* longueur effective du payload copié */
    __u64 timestamp_ns;         /* horodatage kernel */
} __attribute__((packed));

/* ---------------------------------------------------------------------------
 * Arguments sauvegardés à l'entrée de SSL_read (pour l'uretprobe)
 * ---------------------------------------------------------------------------*/
struct ssl_read_args {
    __u64 ssl_ptr;              /* pointeur vers la structure SSL */
    __u64 buf_ptr;              /* pointeur vers le buffer de réception */
    __u32 num;                  /* taille maximale demandée */
} __attribute__((packed));

/* ---------------------------------------------------------------------------
 * Informations de connexion associées à un pointeur SSL
 * ---------------------------------------------------------------------------*/
struct ssl_conn_info {
    __u32 fd;                   /* descripteur de fichier socket */
    __u32 src_ip;               /* IP source du client */
    __u16 src_port;             /* port source du client */
} __attribute__((packed));

/* ---------------------------------------------------------------------------
 * Clé composite pour accept_map : pid_tgid + fd
 * ---------------------------------------------------------------------------*/
struct accept_key {
    __u64 pid_tgid;             /* PID+TGID */
    __u32 fd;                   /* descripteur de fichier */
} __attribute__((packed));

/* ===========================================================================
 * Déclarations des maps eBPF avec annotations BTF
 * ===========================================================================*/

/* Ring buffer : événements TCP SYN (16 MB) */
struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 1 << 24);
} rb_tcp_syn SEC(".maps");

/* Ring buffer : événements TLS ClientHello (16 MB) */
struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 1 << 24);
} rb_tls_hello SEC(".maps");

/* Ring buffer : données SSL déchiffrées (64 MB, plus volumineux) */
struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 1 << 26);
} rb_ssl_data SEC(".maps");

/* Ring buffer : événements accept4 (4 MB) */
struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 1 << 22);
} rb_accept SEC(".maps");

/* Ring buffer : payload HTTP en clair port 80/8080 (32 MB) */
struct {
    __uint(type, BPF_MAP_TYPE_RINGBUF);
    __uint(max_entries, 1 << 25);
} rb_http_plain SEC(".maps");

/* Hash map : pid_tgid → ssl_read_args (arguments SSL_read entry) */
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 10240);
    __type(key, __u64);
    __type(value, struct ssl_read_args);
} ssl_args_map SEC(".maps");

/* Hash map : ssl_ptr → ssl_conn_info (connexion associée au SSL*) */
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 10240);
    __type(key, __u64);
    __type(value, struct ssl_conn_info);
} ssl_conn_map SEC(".maps");

/* Hash map : {pid_tgid, fd} → accept_event (pour corrélation SSL) */
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 10240);
    __type(key, struct accept_key);
    __type(value, struct accept_event);
} accept_map SEC(".maps");

/* Hash map secondaire : fd uniquement → ssl_conn_info (pour SSL_set_fd) */
struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 10240);
    __type(key, __u32);
    __type(value, struct ssl_conn_info);
} fd_conn_map SEC(".maps");

