/* * ================================================================================== * IFTP Protocol Header - ICMP File Transfer Protocol specification * * ISA Project * Author: Roman Necas (xnecasr00) * Date: 13. October 2025 * * PURPOSE: * This module defines IFTP (ICMP File Transfer Protocol), a custom application- * layer protocol for transferring encrypted files through ICMP Echo-Request/Reply * messages. IFTP provides reliable, ordered delivery with integrity checking. * * PROTOCOL OVERVIEW: * IFTP is layered on top of ICMP and provides: * - Session management (unique session IDs) * - Reliable delivery (sequence numbers, ACKs) * - Fragmentation support (for large files) * - Integrity checking (CRC32 checksums) * - Metadata transmission (filename, size, crypto parameters) * * PACKET STRUCTURE: * ┌─────────────────────────────────────────┐ * │ ICMP Header (8 bytes) │ * ├─────────────────────────────────────────┤ * │ IFTP Header (26 bytes) │ * │ - Magic, Session ID │ * │ - Message Type, Flags │ * │ - Sequence Number, Fragment Info │ * │ - Payload Length, CRC32 │ * ├─────────────────────────────────────────┤ * │ IFTP Payload (0-1400 bytes) │ * │ - START: iftp_metadata_t │ * │ - DATA: Encrypted file chunk │ * │ - END: Empty │ * │ - ACK/NACK: Optional error info │ * └─────────────────────────────────────────┘ * * TRANSFER FLOW: * 1. Client → Server: START packet (metadata: filename, size, IV, salt) * 2. Server → Client: ACK * 3. Client → Server: DATA packet(s) with encrypted file chunks * 4. Server → Client: ACK for each DATA packet * 5. Client → Server: END packet * 6. Server → Client: ACK * * ERROR HANDLING: * - NACK packets sent for errors (bad checksum, wrong sequence, etc.) * - Client retries on timeout or NACK with exponential backoff * - Maximum retry attempts enforced (MAX_RETRIES) * * MESSAGE TYPES: * - START (0x01): Initiate transfer with metadata * - DATA (0x02): Transfer encrypted file chunk * - END (0x03): Signal completion * - ACK (0x04): Acknowledge received packet * - NACK (0x05): Negative acknowledgment (error) * - HEARTBEAT (0x06): Keep-alive (reserved for future use) * ================================================================================== */ #ifndef PROTOCOL_H #define PROTOCOL_H #include "common.h" #include "crypto.h" /* * ================================================================================== * PROTOCOL CONSTANTS * ================================================================================== */ /* * IFTP Magic Number (0xDEADBEEF) * * This 32-bit value appears at the start of every IFTP header to identify * packets as belonging to our protocol. It helps: * - Distinguish IFTP packets from other ICMP traffic * - Detect corruption (if magic is wrong, packet is invalid) * * The value 0xDEADBEEF is commonly used in debugging/networking as it's * easily recognizable in hex dumps and unlikely to appear by accident. */ #define IFTP_MAGIC 0xDEADBEEF /* * ================================================================================== * MESSAGE TYPES * ================================================================================== */ /* * iftp_msg_type_t - IFTP message type enumeration * * Defines all possible message types in the IFTP protocol. Each message type * has a specific purpose in the file transfer process. */ typedef enum { /* * START (0x01) - Transfer initiation packet * * Sent by client to begin a new file transfer session. * Payload: iftp_metadata_t containing filename, size, IV, salt * Response: ACK from server * Sequence: Must be seq_num = 0 */ IFTP_START = 0x01, /* * DATA (0x02) - File data chunk packet * * Sent by client to transmit encrypted file data. * Payload: Encrypted file chunk (max 1400 bytes) * Response: ACK from server * Sequence: Increments for each DATA packet (1, 2, 3, ...) * Fragmentation: May be fragmented if chunk doesn't fit in one packet */ IFTP_DATA = 0x02, /* * END (0x03) - Transfer completion packet * * Sent by client to signal successful completion of file transfer. * Payload: Empty (payload_len = 0) * Response: ACK from server * Sequence: Final sequence number (after last DATA packet) */ IFTP_END = 0x03, /* * ACK (0x04) - Acknowledgment packet * * Sent by server to acknowledge receipt of START, DATA, or END packet. * Payload: Empty (payload_len = 0) * Sequence: Echoes the seq_num from the packet being acknowledged * Purpose: Confirms successful receipt and processing */ IFTP_ACK = 0x04, /* * NACK (0x05) - Negative acknowledgment packet * * Sent by server to indicate an error occurred. * Payload: iftp_error_t containing error code and message * Sequence: Echoes the seq_num from the failed packet * Causes: Checksum error, sequence mismatch, crypto error, etc. */ IFTP_NACK = 0x05, /* * HEARTBEAT (0x06) - Keep-alive message * * Reserved for future use to detect dead connections. * Not currently used in the implementation. */ IFTP_HEARTBEAT = 0x06 } iftp_msg_type_t; /* * ================================================================================== * PROTOCOL FLAGS * ================================================================================== */ /* * IFTP Control Flags * * 8-bit flag field in IFTP header for optional features. Multiple flags can * be combined using bitwise OR. Currently defined but not all are used. */ /* COMPRESSED flag (0x01) - Payload is compressed * Reserved for future use. Current implementation does not compress data. */ #define IFTP_FLAG_COMPRESSED 0x01 /* URGENT flag (0x02) - High priority packet * Reserved for future use. Not currently implemented. */ #define IFTP_FLAG_URGENT 0x02 /* FRAGMENTED flag (0x04) - Packet is part of a fragmented message * Set when a large encrypted chunk must be split across multiple ICMP packets. * fragment_current and fragment_total fields indicate fragment position. */ #define IFTP_FLAG_FRAGMENTED 0x04 /* ENCRYPTED flag (0x08) - Payload contains encrypted data * Set for DATA packets containing AES-encrypted file chunks. * Not set for START, END, ACK, NACK packets. */ #define IFTP_FLAG_ENCRYPTED 0x08 /* * ================================================================================== * IFTP HEADER STRUCTURE * ================================================================================== */ /* * iftp_header_t - IFTP protocol header (26 bytes fixed) * * This structure defines the fixed-size header that appears at the start of * every IFTP packet. The header is packed to ensure consistent layout across * platforms and compilers. * * MEMORY LAYOUT (26 bytes total): * Offset | Size | Field * -------|------|------------------ * 0 | 4 | magic (0xDEADBEEF) * 4 | 2 | session_id * 6 | 1 | msg_type * 7 | 1 | flags * 8 | 4 | seq_num * 12 | 4 | fragment_current * 16 | 4 | fragment_total * 20 | 2 | payload_len * 22 | 4 | crc32 * * PACKING: * __attribute__((packed)) ensures no padding bytes are inserted between fields. * This is critical for network protocols where exact byte layout matters. * * BYTE ORDER: * All multi-byte fields use network byte order (big-endian). * Use htons/htonl for writing, ntohs/ntohl for reading. */ typedef struct { /* * Magic number (4 bytes) - Protocol identifier * * Must always be 0xDEADBEEF. Used to: * - Identify IFTP packets among other ICMP traffic * - Detect header corruption * - Quick rejection of non-IFTP packets */ uint32_t magic; /* * Session ID (2 bytes) - Unique transfer session identifier * * Randomly generated by client at start of transfer. * Used to: * - Distinguish between concurrent transfers * - Detect stale packets from previous sessions * - Match ACKs to requests * * Generated by: generate_secure_session_id() using RAND_bytes() * Range: 1-65535 (0 is invalid) */ uint16_t session_id; /* * Message type (1 byte) - Type of IFTP message * * One of: START, DATA, END, ACK, NACK, HEARTBEAT * Determines how payload is interpreted. */ uint8_t msg_type; /* * Flags (1 byte) - Control flags * * Bitwise OR of IFTP_FLAG_* constants. * Currently used: FRAGMENTED, ENCRYPTED * Reserved: COMPRESSED, URGENT */ uint8_t flags; /* * Sequence number (4 bytes) - Packet ordering * * Used for: * - Ordering packets (especially DATA packets) * - Detecting duplicates * - Matching ACKs to requests * * Sequence: * - START: seq_num = 0 * - First DATA: seq_num = 1 * - Subsequent DATA: seq_num = 2, 3, 4, ... * - END: seq_num = (last DATA seq_num + 1) * - ACK: echoes seq_num of packet being acknowledged */ uint32_t seq_num; /* * Current fragment number (4 bytes) * * For FRAGMENTED packets: 0-based index of this fragment * For non-fragmented packets: 0 * * Example: If a 3000-byte encrypted chunk is split into 3 fragments: * Fragment 0: bytes 0-1399 * Fragment 1: bytes 1400-2799 * Fragment 2: bytes 2800-2999 */ uint32_t fragment_current; /* * Total fragment count (4 bytes) * * For FRAGMENTED packets: Total number of fragments in this message * For non-fragmented packets: 1 * * Server uses this to know when all fragments have been received. */ uint32_t fragment_total; /* * Payload length (2 bytes) - Actual bytes in payload * * Number of bytes following this header. * Range: 0-1400 bytes (MAX_PAYLOAD_SIZE) * * Examples: * - START: sizeof(iftp_metadata_t) (~350 bytes) * - DATA: Encrypted chunk size (variable, max 1400) * - END: 0 (no payload) * - ACK: 0 (no payload) * - NACK: sizeof(iftp_error_t) (~70 bytes) */ uint16_t payload_len; /* * CRC32 checksum (4 bytes) - Integrity verification * * CRC32 checksum of header + payload for corruption detection. * Calculated over: * 1. All header fields EXCEPT crc32 field itself (set to 0 during calc) * 2. Entire payload * * Algorithm: CRC-32 (polynomial 0xEDB88320) * Verification: Recalculate on receipt and compare * Mismatch: Send NACK with IFTP_ERROR_CHECKSUM_ERROR */ uint32_t crc32; } __attribute__((packed)) iftp_header_t; /* * ================================================================================== * IFTP METADATA STRUCTURE * ================================================================================== */ /* * iftp_metadata_t - File transfer metadata (START packet payload) * * This structure is transmitted in the payload of START packets to provide * the server with all information needed to receive and decrypt the file. * * SIZE: ~350 bytes (varies with filename length) * TRANSMISSION: Once per transfer, in START packet * USAGE: Server extracts this to initialize crypto engine and file writer */ typedef struct { /* * Filename (256 bytes) - Name of file being transferred * * Null-terminated string, max 255 chars + null. * Contains only the basename (no directory path). * * Security: Server validates this to prevent: * - Path traversal attacks (..) * - Absolute paths (/) * - Invalid characters * * Server may rename if file exists (appends _1, _2, etc.) */ char filename[MAX_FILENAME_LEN + 1]; /* * File size (8 bytes) - Total size of plaintext file * * Size in bytes of the original file before encryption. * Used by: * - Server to allocate buffer/track progress * - Client to calculate total packets needed * - Progress reporting * * Note: Encrypted size will be larger due to AES padding (up to 16 bytes) */ uint64_t file_size; /* * Initialization Vector (16 bytes) - AES-CBC IV * * Randomly generated IV for AES-256-CBC encryption. * Must be unique for each file transfer. * Generated by: RAND_bytes() on client * Used by: Server to initialize decryption (crypto_init) * * Security: IV does not need to be secret, only unpredictable. */ uint8_t iv[AES_IV_SIZE]; /* * PBKDF2 Salt (32 bytes) - Key derivation salt * * Randomly generated salt for PBKDF2 key derivation. * Ensures each transfer has a unique encryption key. * Generated by: RAND_bytes() on client * Used by: Server to derive decryption key from login * * Security: Salt does not need to be secret, only unique. */ uint8_t salt[PBKDF2_SALT_SIZE]; /* * Chunk size (4 bytes) - Size of encryption chunks * * Currently not used in implementation but reserved for: * - Configurable chunk sizes * - Adaptive sizing based on network conditions * - Future optimizations */ uint32_t chunk_size; /* * Compression type (1 byte) * * Reserved for future use. Currently always 0 (no compression). * Could indicate compression algorithm if IFTP_FLAG_COMPRESSED is used. */ uint8_t compression_type; /* * Reserved (7 bytes) - Padding for future extensions * * Set to zero. Available for future protocol extensions without * breaking compatibility. Could be used for: * - Additional crypto parameters * - Checksums * - Feature flags * - Timestamps */ uint8_t reserved[7]; } __attribute__((packed)) iftp_metadata_t; /* * ================================================================================== * ERROR HANDLING * ================================================================================== */ /* * iftp_error_code_t - Error codes for NACK packets * * Specific error codes sent in NACK packets to indicate why a packet failed. * Helps client understand what went wrong and whether retry might succeed. */ typedef enum { IFTP_ERROR_NONE = 0, /* No error (should not appear in NACK) */ IFTP_ERROR_INVALID_PACKET = 1, /* Malformed packet (bad header, etc.) */ IFTP_ERROR_SEQUENCE_ERROR = 2, /* Wrong sequence number (out of order) */ IFTP_ERROR_CHECKSUM_ERROR = 3, /* CRC32 validation failed (corruption) */ IFTP_ERROR_CRYPTO_ERROR = 4, /* Decryption failed (wrong key, padding) */ IFTP_ERROR_FILE_ERROR = 5, /* File I/O error (disk full, permissions) */ IFTP_ERROR_TIMEOUT = 6, /* Operation timed out */ IFTP_ERROR_SESSION_ERROR = 7 /* Invalid or expired session */ } iftp_error_code_t; /* * iftp_error_t - Error information structure (NACK packet payload) * * Detailed error information sent in NACK packet payload. * Helps client diagnose problems and decide on retry strategy. */ typedef struct { /* * Error code (1 byte) - Type of error that occurred * One of the iftp_error_code_t values */ uint8_t error_code; /* * Failed sequence number (4 bytes) - Which packet failed * Sequence number of the packet that caused this error */ uint32_t failed_seq_num; /* * Error message (64 bytes) - Human-readable description * Null-terminated string with additional details about the error * Example: "CRC mismatch: expected 0x12345678, got 0x87654321" */ char error_message[64]; } __attribute__((packed)) iftp_error_t; /* * ================================================================================== * PACKET CREATION AND PARSING * ================================================================================== */ /* * create_iftp_packet - Construct IFTP packet from header and payload * * Low-level function that combines header and payload into a complete packet. * Calculates and fills in the CRC32 checksum. * * @param header: Pointer to filled-in IFTP header * @param payload: Pointer to payload data (or NULL if no payload) * @param packet_buffer: Output buffer for complete packet * @param packet_len: Output parameter for total packet length * @return: 0 on success, -1 on error */ int create_iftp_packet(const iftp_header_t *header, const void *payload, uint8_t *packet_buffer, size_t *packet_len); /* * parse_iftp_packet - Extract header and payload from received packet * * Parses a received packet, validates magic/CRC, and extracts * header and payload into separate structures. * * VALIDATION: * - Checks magic number (0xDEADBEEF) * - Validates CRC32 checksum * - Validates payload length * * @param packet_buffer: Raw packet data from network * @param packet_len: Total packet length * @param header: Output parameter for parsed header * @param payload: Output buffer for payload data * @param payload_len: Output parameter for payload length * @return: 0 on success, -1 on error */ int parse_iftp_packet(const uint8_t *packet_buffer, size_t packet_len, iftp_header_t *header, uint8_t *payload, size_t *payload_len); /* * ================================================================================== * HIGH-LEVEL PACKET CREATION FUNCTIONS * ================================================================================== */ /* Create START packet with metadata */ int create_start_packet(uint16_t session_id, const iftp_metadata_t *metadata, uint8_t *packet_buffer, size_t *packet_len); /* Create DATA packet with file chunk */ int create_data_packet(uint16_t session_id, uint32_t seq_num, uint32_t frag_current, uint32_t frag_total, const void *data, size_t data_len, uint8_t *packet_buffer, size_t *packet_len); /* Create END packet (no payload) */ int create_end_packet(uint16_t session_id, uint32_t seq_num, uint8_t *packet_buffer, size_t *packet_len); /* Create ACK packet (no payload) */ int create_ack_packet(uint16_t session_id, uint32_t seq_num, uint8_t *packet_buffer, size_t *packet_len); /* Create NACK packet with error information */ int create_nack_packet(uint16_t session_id, uint32_t seq_num, iftp_error_code_t error_code, const char *error_message, uint8_t *packet_buffer, size_t *packet_len); /* Create HEARTBEAT packet (reserved for future use) */ int create_heartbeat_packet(uint16_t session_id, uint32_t seq_num, uint8_t *packet_buffer, size_t *packet_len); /* * ================================================================================== * UTILITY FUNCTIONS * ================================================================================== */ /* * calculate_crc32 - Compute CRC32 checksum * * Calculates CRC32 checksum using standard polynomial (0xEDB88320). * Used for integrity checking of IFTP packets. * * ALGORITHM: CRC-32 (used in Ethernet, ZIP, PNG, etc.) * * @param data: Data to checksum * @param len: Length of data in bytes * @return: 32-bit CRC value */ uint32_t calculate_crc32(const void *data, size_t len); /* * validate_iftp_header - Validate IFTP header fields * * Checks header for validity: * - Magic number matches IFTP_MAGIC * - Message type is valid * - Payload length is within bounds * * @param header: Header to validate * @return: 0 if valid, -1 if invalid */ int validate_iftp_header(const iftp_header_t *header); /* * iftp_msg_type_to_string - Convert message type to string * * Returns human-readable name for message type. * Useful for logging and debugging. * * @param msg_type: Message type enum value * @return: String representation (e.g., "START", "DATA", "ACK") */ const char *iftp_msg_type_to_string(iftp_msg_type_t msg_type); /* * iftp_error_to_string - Convert error code to string * * Returns human-readable description of error code. * * @param error_code: Error code enum value * @return: String description (e.g., "Checksum error", "Sequence error") */ const char *iftp_error_to_string(iftp_error_code_t error_code); /* * ================================================================================== * SESSION MANAGEMENT * ================================================================================== */ /* * protocol_session_t - Session state tracking * * Maintains protocol state for a transfer session. * Tracks sequence numbers and detects protocol violations. */ typedef struct { uint16_t session_id; /* Session identifier */ uint32_t next_seq_send; /* Next sequence number to send */ uint32_t next_seq_recv; /* Next sequence number expected */ uint32_t last_ack_sent; /* Last ACK sent */ uint32_t last_ack_recv; /* Last ACK received */ time_t last_activity; /* Last activity timestamp (for timeouts) */ } protocol_session_t; /* Initialize protocol session */ int protocol_session_init(protocol_session_t *session, uint16_t session_id); /* Update session after sending a packet */ int protocol_session_update_send(protocol_session_t *session, uint32_t seq_num); /* Update session after receiving a packet */ int protocol_session_update_recv(protocol_session_t *session, uint32_t seq_num); /* Check if session has timed out */ int protocol_session_check_timeout(const protocol_session_t *session, int timeout_seconds); #endif /* PROTOCOL_H */