/*
 * ==================================================================================
 * Main Header - ICMP Covert Channel File Transfer Application
 *
 * ISA Project
 * Author: Roman Necas (xnecasr00)
 * Date: 13. October 2025
 *
 * PURPOSE:
 * This is the main application header that aggregates all modular headers and
 * defines the high-level application structures and entry points. It serves as
 * the central include point for the entire application.
 *
 * ARCHITECTURE:
 * This application follows a modular architecture with 9 core modules:
 *
 * 1. secret.c - Main entry point and mode selection (client vs server)
 * 2. argument_parser.c - Command-line argument processing
 * 3. network_interface.c - Raw ICMP socket operations
 * 4. protocol.c - IFTP (ICMP File Transfer Protocol) implementation
 * 5. crypto_engine.c - AES-256-CBC encryption/decryption
 * 6. file_manager.c - Chunk-based file I/O
 * 7. client_engine.c - Client transfer logic
 * 8. server_engine.c - Server reception logic
 * 9. state_machine.c - Protocol state machines
 * 10. error.c - Centralized error handling
 * 11. utils.c - Utility functions
 *
 * HEADER ORGANIZATION:
 * - common.h: Shared includes, constants, macros, config_t structure
 * - error.h: Error codes and error handling functions
 * - crypto.h: Cryptographic types and functions (AES-256-CBC)
 * - network.h: Network interface types and ICMP operations
 * - protocol.h: IFTP protocol structures and functions
 * - file_io.h: File manager types and functions
 * - state_machine.h: State machine types and functions
 * - secret.h: This header - aggregates all above, defines server_session_t
 *
 * APPLICATION MODES:
 * - Client mode: Send file via ICMP to specified destination
 *   Usage: secret -r <file> -s <ip|hostname>
 *
 * - Server mode: Listen for ICMP file transfers, save to current directory
 *   Usage: secret -l
 *
 * PROTOCOL OVERVIEW:
 * IFTP (ICMP File Transfer Protocol) is a custom protocol for reliable file
 * transfer over ICMP Echo-Request/Reply messages:
 *
 * 1. Client sends START packet with metadata (filename, size, IV, salt)
 * 2. Server responds with START-ACK
 * 3. Client sends DATA packets with encrypted file chunks
 * 4. Server responds with DATA-ACK for each chunk
 * 5. Client sends END packet when complete
 * 6. Server responds with END-ACK
 *
 * SECURITY FEATURES:
 * - AES-256-CBC encryption with PBKDF2 key derivation (600,000 iterations)
 * - CRC32 checksums for packet integrity
 * - Path traversal prevention (basename extraction)
 * - Secure session IDs (cryptographically random)
 * - Per-transfer unique IV and salt
 * ==================================================================================
 */

#ifndef SECRET_H
#define SECRET_H

/*
 * ==================================================================================
 * MODULAR HEADER INCLUDES
 * ==================================================================================
 */

/*
 * common.h - Common definitions, constants, and configuration structure
 *
 * Provides:
 * - Standard library includes (stdio.h, stdlib.h, string.h, etc.)
 * - Network includes (netinet/ip.h, netinet/icmp6.h, etc.)
 * - Application constants (MAX_PAYLOAD_SIZE, PBKDF2_ITERATIONS, etc.)
 * - Utility macros (SAFE_FREE, SAFE_CLOSE, MIN, MAX)
 * - config_t structure for command-line configuration
 */
#include "common.h"

/*
 * error.h - Error handling and reporting
 *
 * Provides:
 * - error_code_t enum with all error codes (ERR_SUCCESS, ERR_MEMORY_ALLOC, etc.)
 * - ERROR_SET macro for setting error context
 * - error_print_last() for printing errors to stderr
 * - Thread-safe error context management
 */
#include "error.h"

/*
 * crypto.h - Cryptographic operations
 *
 * Provides:
 * - crypto_engine_t structure for AES-256-CBC encryption state
 * - crypto_init(), crypto_encrypt(), crypto_decrypt() functions
 * - PBKDF2 key derivation with 600,000 iterations
 * - Secure memory wiping (crypto_secure_zero)
 */
#include "crypto.h"

/*
 * network.h - Network interface and ICMP operations
 *
 * Provides:
 * - network_interface_t structure for raw socket management
 * - network_init(), network_send_packet(), network_recv_packet() functions
 * - Dual-stack IPv4/IPv6 support
 * - ICMP checksum calculation (IPv4 only, kernel handles IPv6)
 * - Network statistics tracking (network_stats_t)
 */
#include "network.h"

/*
 * protocol.h - IFTP protocol implementation
 *
 * Provides:
 * - iftp_header_t structure (24-byte fixed-size header)
 * - iftp_metadata_t structure (filename, file_size, IV, salt)
 * - iftp_error_t enum for NACK error codes
 * - protocol_session_t structure for protocol state
 * - Message type constants (MSG_TYPE_START, MSG_TYPE_DATA, MSG_TYPE_END, etc.)
 * - protocol_create_*() functions for packet creation
 * - protocol_parse_*() functions for packet parsing
 * - CRC32 checksum validation
 */
#include "protocol.h"

/*
 * file_io.h - File management and I/O
 *
 * Provides:
 * - file_manager_t structure for chunk-based file I/O
 * - file_manager_open_read(), file_manager_read_chunk() for client
 * - file_manager_open_write(), file_manager_write_chunk() for server
 * - Path security functions (path_is_safe, file_manager_get_basename)
 * - File transfer statistics (file_transfer_stats_t)
 */
#include "file_io.h"

/*
 * state_machine.h - Protocol state machines
 *
 * Provides:
 * - client_state_machine_t for client-side state tracking
 * - server_state_machine_t for server-side state tracking
 * - client_state_t enum (CLIENT_IDLE, CLIENT_DATA_TRANSFER, etc.)
 * - server_state_t enum (SERVER_LISTENING, SERVER_RECEIVING_DATA, etc.)
 * - protocol_event_t enum (EVENT_TIMEOUT, EVENT_ACK_RECEIVED, etc.)
 * - State transition functions (client_sm_transition, server_sm_transition)
 * - Timeout handling with exponential backoff
 * - Error recovery logic
 */
#include "state_machine.h"

/*
 * ==================================================================================
 * SERVER SESSION STRUCTURE
 * ==================================================================================
 */

/*
 * server_session_t - Server-side session state for client connection
 *
 * This structure maintains all state required for a single file transfer session
 * on the server side. The server can handle multiple sessions concurrently by
 * maintaining an array of server_session_t structures, indexed by session_id.
 *
 * LIFECYCLE:
 * 1. Created when START packet received from new client
 * 2. Initialized with metadata from START packet
 * 3. Updated as DATA packets received
 * 4. Cleaned up when END packet received or session times out
 *
 * USAGE (Server):
 *   server_session_t sessions[MAX_SESSIONS];
 *   // On START packet:
 *   server_session_t *session = find_free_session(sessions);
 *   session->session_id = start_packet->session_id;
 *   session->expected_seq = 0;
 *   session->active = 1;
 *   memcpy(&session->client_addr, &src_addr, sizeof(src_addr));
 *   // On DATA packet:
 *   validate_session_id(packet, session);
 *   validate_sequence_number(packet, session);
 *   decrypt_and_write_chunk(packet, session);
 *   session->expected_seq++;
 *   // On END packet or timeout:
 *   cleanup_session(session);
 *
 * THREAD SAFETY:
 * This structure is NOT thread-safe. If server uses multiple threads to handle
 * concurrent sessions, each session must be protected by a mutex.
 *
 * MEMORY MANAGEMENT:
 * - reassembly_buffer and received_fragments are dynamically allocated
 * - Must call cleanup function to free these before discarding structure
 */
typedef struct {
    /*
     * session_id - Unique session identifier (16-bit)
     *
     * Extracted from START packet's IFTP header.
     * Used to match DATA/END packets to this session.
     *
     * Range: 0 to 65535
     * Generated by client using cryptographically secure random number.
     *
     * Multiple sessions can exist simultaneously if server handles multiple
     * clients concurrently. Each session MUST have unique session_id.
     */
    uint16_t session_id;

    /*
     * expected_seq - Expected sequence number in next DATA packet
     *
     * Initialized to 0 when START packet received.
     * Incremented after each valid DATA packet processed.
     *
     * Used to:
     * - Validate received DATA packet has correct seq_num
     * - Detect duplicate packets (seq_num < expected_seq) → ignore or resend ACK
     * - Detect skipped packets (seq_num > expected_seq) → NACK with SEQUENCE_ERROR
     *
     * Range: 0 to UINT32_MAX
     */
    uint32_t expected_seq;

    /*
     * reassembly_buffer - Buffer for reassembling fragmented packets
     *
     * Dynamically allocated buffer large enough to hold one complete chunk
     * (MAX_PAYLOAD_SIZE = 1400 bytes) that may arrive in multiple fragments.
     *
     * Allocation: malloc(MAX_PAYLOAD_SIZE) when session created
     * Deallocation: SAFE_FREE when session cleanup
     *
     * Usage:
     * - Fragment packets are assembled here before decryption
     * - Once all fragments for a chunk received, decrypt and write to file
     * - Buffer reused for each chunk
     *
     * Note: Current implementation may not use fragmentation (chunk_size ≤ 1400),
     * but this buffer enables future support for larger chunks.
     */
    uint8_t *reassembly_buffer;

    /*
     * received_fragments - Bitmap tracking received fragment numbers
     *
     * Dynamically allocated bitmap to track which fragments have been received
     * for the current chunk. Each bit represents one fragment number.
     *
     * Allocation: malloc(fragment_total / 8 + 1) when chunk reception starts
     * Deallocation: SAFE_FREE when chunk complete or session cleanup
     *
     * Usage:
     * - Set bit N when fragment N received
     * - Check if all fragments received: count set bits == fragment_total
     * - Prevents duplicate fragment processing
     *
     * Example (fragment_total = 3):
     * - Initially: [0, 0, 0]
     * - Fragment 0 received: [1, 0, 0]
     * - Fragment 2 received: [1, 0, 1]
     * - Fragment 1 received: [1, 1, 1] → all received, decrypt chunk
     */
    uint8_t *received_fragments;

    /*
     * file_size - Expected total file size in bytes
     *
     * Extracted from START packet metadata.
     * Used to:
     * - Validate transfer completion (bytes_written == file_size)
     * - Prevent buffer overflows (reject writes exceeding file_size)
     * - Calculate expected number of DATA packets
     * - Display progress percentage
     *
     * Range: 0 to UINT64_MAX (theoretical max ~16 exabytes)
     */
    uint64_t file_size;

    /*
     * filename - Basename of file being received
     *
     * Extracted from START packet metadata using file_manager_get_basename().
     * Directory components are stripped for security (path traversal prevention).
     *
     * Size: MAX_FILENAME_LEN + 1 (256 + 1 = 257 bytes)
     * Content: Null-terminated string, basename only
     *
     * Examples:
     * - Received: "/etc/passwd" → Stored: "passwd"
     * - Received: "../../../evil" → Stored: "evil"
     * - Received: "file.txt" → Stored: "file.txt"
     *
     * File is created in server's current working directory with this name.
     */
    char filename[MAX_FILENAME_LEN + 1];

    /*
     * crypto - Crypto engine for decryption
     *
     * Initialized when START packet received:
     * - Extracts IV and salt from metadata
     * - Derives key using PBKDF2 from login password
     * - Configures for decryption mode
     *
     * Used to decrypt each DATA packet payload.
     *
     * Must call crypto_cleanup() when session ends to securely wipe key material.
     */
    crypto_engine_t crypto;

    /*
     * file_mgr - File manager for writing received chunks
     *
     * Initialized when START packet received:
     * - Opens file for writing (file_manager_open_write)
     * - Sets expected file_size from metadata
     * - Tracks bytes_written progress
     *
     * Used to write decrypted chunks to disk.
     *
     * Must call file_manager_cleanup() when session ends to close file.
     */
    file_manager_t file_mgr;

    /*
     * client_addr - Source address of client
     *
     * Extracted from recvfrom() when START packet received.
     * Used to:
     * - Send ACK/NACK responses back to client
     * - Validate that DATA/END packets come from same client
     *   (prevents session hijacking)
     *
     * Type: sockaddr_storage (polymorphic, holds IPv4 or IPv6)
     * Size: 128 bytes (platform-dependent)
     *
     * Cast to sockaddr_in or sockaddr_in6 based on client_addr.ss_family:
     * - AF_INET: IPv4 client
     * - AF_INET6: IPv6 client
     */
    struct sockaddr_storage client_addr;

    /*
     * client_addr_len - Actual length of client_addr
     *
     * Typical values:
     * - IPv4: sizeof(struct sockaddr_in) = 16 bytes
     * - IPv6: sizeof(struct sockaddr_in6) = 28 bytes
     *
     * Used by sendto() when sending ACK/NACK to client.
     */
    socklen_t client_addr_len;

    /*
     * active - Session active flag
     *
     * Values:
     * - 1: Session active, processing packets
     * - 0: Session inactive, slot available for new client
     *
     * Set to 1 when START packet received and session initialized.
     * Set to 0 when:
     * - END packet received and ACK sent (success)
     * - Session timeout (client disconnected)
     * - Error occurred (file write failure, decryption error, etc.)
     *
     * Used by find_free_session() to locate available session slot.
     */
    int active;

    /*
     * session_start - Session start timestamp (Unix time)
     *
     * Set when START packet received using time(NULL).
     * Used to:
     * - Calculate total session duration
     * - Display session age
     * - Statistics reporting
     */
    time_t session_start;

    /*
     * last_activity - Last packet received timestamp
     *
     * Updated when valid packet received from client (START, DATA, or END).
     * Used to detect session timeout:
     *   if (time(NULL) - last_activity) > SESSION_TIMEOUT:
     *     cleanup_session(session)
     *
     * Default timeout: SESSION_TIMEOUT (30 seconds)
     *
     * Prevents resource leaks from clients that crash or disconnect without
     * sending END packet.
     */
    time_t last_activity;
} server_session_t;

/*
 * ==================================================================================
 * MAIN APPLICATION ENTRY POINTS
 * ==================================================================================
 */

/*
 * client_run - Execute client mode (send file)
 *
 * This function implements the complete client-side file transfer protocol:
 * 1. Initialize network interface (create raw ICMP socket)
 * 2. Open file for reading
 * 3. Initialize crypto engine (generate IV/salt, derive key)
 * 4. Send START packet with metadata
 * 5. Wait for START-ACK
 * 6. Loop: Read chunk → Encrypt → Send DATA → Wait for ACK
 * 7. Send END packet
 * 8. Wait for END-ACK
 * 9. Clean up resources
 *
 * ERROR HANDLING:
 * - Implements retry logic with exponential backoff (max 5 retries)
 * - Returns -1 on failure (network error, file error, max retries exceeded)
 * - Returns 0 on success
 *
 * REQUIRES:
 * - Root privileges (raw socket)
 * - Readable source file
 * - Network connectivity to destination
 *
 * @param config: Configuration structure with:
 *   - config->filename: Path to file to send
 *   - config->server_address: Destination IP or hostname
 *   - config->timeout: Initial timeout in seconds (default: 2)
 *
 * @return:
 *    0: Success - file transferred successfully
 *   -1: Failure - error details in error context (use error_print_last())
 */
int client_run(const config_t *config);

/*
 * server_run - Execute server mode (receive files)
 *
 * This function implements the complete server-side file reception protocol:
 * 1. Initialize network interface (create raw ICMP socket)
 * 2. Enter listening loop:
 *    a. Poll for incoming ICMP packets (non-blocking)
 *    b. Validate packet (magic number, CRC32)
 *    c. Match packet to session (or create new session for START)
 *    d. Process packet based on type:
 *       - START: Create session, extract metadata, open file, send START-ACK
 *       - DATA: Validate sequence, decrypt chunk, write to file, send DATA-ACK
 *       - END: Finalize file, send END-ACK, clean up session
 *    e. Check for session timeouts, clean up inactive sessions
 * 3. Handle signals (Ctrl+C) for graceful shutdown
 * 4. Clean up all active sessions before exit
 *
 * ERROR HANDLING:
 * - Sends NACK on recoverable errors (invalid sequence, checksum error)
 * - Cleans up session on unrecoverable errors (file write failure, decryption error)
 * - Continues listening after error (does not exit)
 * - Returns -1 only on fatal errors (socket creation failure)
 *
 * REQUIRES:
 * - Root privileges (raw socket)
 * - Write permission in current directory (for received files)
 *
 * @param config: Configuration structure (server_mode = 1)
 *
 * @return:
 *    0: Success - server shutdown gracefully
 *   -1: Failure - fatal error occurred (use error_print_last())
 */
int server_run(const config_t *config);

#endif /* SECRET_H */
