Projects/3BIT/winter-semester/ISA/include/network.h
2026-04-14 19:28:46 +02:00

794 lines
28 KiB
C

/*
* ==================================================================================
* Network Interface Header - Raw Socket ICMP/ICMPv6 Operations
*
* ISA Project
* Author: Roman Necas (xnecasr00)
* Date: 13. October 2025
*
* PURPOSE:
* This header defines the network interface layer for the ICMP covert channel
* file transfer application. It provides abstractions for raw socket operations,
* supporting both IPv4 (ICMP) and IPv6 (ICMPv6) Echo-Request/Reply messages.
*
* RESPONSIBILITIES:
* - Raw socket creation and management (requires root privileges)
* - ICMP packet transmission and reception
* - Address family abstraction (IPv4/IPv6)
* - Timeout handling for reliable communication
* - Network statistics tracking
* - Checksum calculation for ICMPv4 packets
*
* PROTOCOL SUPPORT:
* - IPv4: ICMP Echo-Request (type 8) / Echo-Reply (type 0)
* - IPv6: ICMPv6 Echo-Request (type 128) / Echo-Reply (type 129)
*
* RAW SOCKET REQUIREMENTS:
* - Requires CAP_NET_RAW capability or root privileges
* - Uses IPPROTO_ICMP for IPv4, IPPROTO_ICMPV6 for IPv6
* - IPv4: Application must calculate ICMP checksum
* - IPv6: Kernel automatically calculates ICMPv6 checksum (RFC 3542)
*
* KEY FEATURES:
* - Dual-stack support (IPv4/IPv6) with automatic detection
* - Hostname resolution via getaddrinfo()
* - Configurable send/receive timeouts
* - Non-blocking receive mode for server operation
* - MTU discovery for optimal packet sizing
* - Comprehensive error handling with detailed diagnostics
* ==================================================================================
*/
#ifndef NETWORK_H
#define NETWORK_H
#include "common.h"
/*
* ==================================================================================
* NETWORK INTERFACE STRUCTURE
* ==================================================================================
*/
/*
* network_interface_t - Network layer state management
*
* This structure encapsulates all state required for ICMP socket operations.
* It abstracts the differences between IPv4 and IPv6, providing a unified
* interface for packet transmission and reception.
*
* LIFECYCLE:
* 1. Allocated by caller (typically on stack or in session structure)
* 2. Initialized by network_init() - creates raw socket, resolves destination
* 3. Configured by network_set_timeout() if custom timeouts needed
* 4. Used for network_send_packet() and network_recv_packet() operations
* 5. Cleaned up by network_cleanup() (closes socket)
*
* USAGE PATTERNS:
*
* Client mode:
* network_interface_t net;
* network_init(&net, "192.168.1.100");
* network_send_packet(&net, packet, packet_len);
* network_recv_packet(&net, buffer, buffer_len, &src_addr, &src_addr_len);
* network_cleanup(&net);
*
* Server mode:
* network_interface_t net;
* network_init(&net, NULL); // No destination for server
* network_recv_packet_nonblocking(&net, buffer, buffer_len, &src_addr, &src_addr_len);
* network_send_reply(&net, payload, payload_len, &src_addr, src_addr_len);
* network_cleanup(&net);
*
* THREAD SAFETY:
* This structure is NOT thread-safe. Each thread should have its own instance.
*
* SECURITY NOTES:
* - Raw socket operations require elevated privileges
* - Socket is bound to ICMP protocol only - cannot send arbitrary IP packets
* - Timeouts prevent indefinite blocking on malicious/slow peers
*/
typedef struct {
/*
* sockfd - Primary raw ICMP socket file descriptor
*
* Client mode: Single socket (IPv4 or IPv6) based on destination address
* - IPv4: socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
* - IPv6: socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)
*
* Server mode: IPv4 socket (used with sockfd_v6 for dual-stack)
* - Always: socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
*
* Values:
* - >= 0: Valid socket descriptor
* - -1: Invalid/uninitialized socket
*
* Closed by network_cleanup() using SAFE_CLOSE macro.
*/
int sockfd;
/*
* sockfd_v6 - IPv6 socket file descriptor (server mode only)
*
* Client mode: Not used (always -1)
* Server mode: IPv6 socket for dual-stack support
* - socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)
*
* This enables server to receive both IPv4 (ICMP) and IPv6 (ICMPv6) packets
* simultaneously. The server uses select() to poll both sockfd and sockfd_v6.
*
* Values:
* - >= 0: Valid IPv6 socket (server mode)
* - -1: Not used (client mode) or uninitialized
*
* Closed by network_cleanup() using SAFE_CLOSE macro.
*/
int sockfd_v6;
/*
* dest_addr - Destination address storage (IPv4 or IPv6)
*
* This is a polymorphic structure capable of holding both sockaddr_in (IPv4)
* and sockaddr_in6 (IPv6) addresses. The actual type is determined by the
* addr_family field.
*
* Structure layout:
* - sockaddr_storage is guaranteed to be large enough for any socket address
* - Size: Typically 128 bytes (platform-dependent)
* - Alignment: Suitable for casting to sockaddr_in or sockaddr_in6
*
* Population:
* - Client mode: Populated by network_init() via getaddrinfo()
* - Server mode: Populated by network_recv_packet() from incoming packets
*
* Usage:
* struct sockaddr_in *sin = (struct sockaddr_in *)&net->dest_addr;
* sin->sin_port; // Access IPv4 fields
*
* struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&net->dest_addr;
* sin6->sin6_port; // Access IPv6 fields
*/
struct sockaddr_storage dest_addr;
/*
* dest_addr_len - Actual length of dest_addr structure
*
* This field specifies the actual size of the address stored in dest_addr.
* It is required because dest_addr is a generic storage structure that can
* hold addresses of different sizes.
*
* Typical values:
* - IPv4: sizeof(struct sockaddr_in) = 16 bytes
* - IPv6: sizeof(struct sockaddr_in6) = 28 bytes
*
* Used by:
* - sendto() to specify destination address size
* - recvfrom() to receive actual address size (pass as pointer)
*/
socklen_t dest_addr_len;
/*
* addr_family - Address family indicator
*
* Specifies whether this interface is operating in IPv4 or IPv6 mode.
* This determines which socket protocol, address structures, and ICMP
* message types are used.
*
* Values:
* - AF_INET (2): IPv4 address family
* * Uses IPPROTO_ICMP
* * Uses struct sockaddr_in
* * ICMP Echo-Request (type 8) / Echo-Reply (type 0)
*
* - AF_INET6 (10): IPv6 address family
* * Uses IPPROTO_ICMPV6
* * Uses struct sockaddr_in6
* * ICMPv6 Echo-Request (type 128) / Echo-Reply (type 129)
*
* Determined automatically by network_init() based on getaddrinfo() results.
*/
int addr_family;
/*
* send_timeout - Send operation timeout in seconds
*
* Maximum time to wait for send operations to complete before returning error.
* This timeout is set using setsockopt() with SO_SNDTIMEO option.
*
* Purpose:
* - Prevents indefinite blocking if network is congested
* - Allows application to retry or abort transfer
*
* Default: INITIAL_TIMEOUT (2 seconds)
* Range: 1-300 seconds (validated by argument parser)
*
* Note: Send operations on raw sockets rarely block, as the kernel typically
* queues outgoing packets. Timeout mainly protects against kernel buffer exhaustion.
*/
int send_timeout;
/*
* recv_timeout - Receive operation timeout in seconds
*
* Maximum time to wait for incoming packets before returning EAGAIN/EWOULDBLOCK.
* This timeout is set using setsockopt() with SO_RCVTIMEO option.
*
* Purpose:
* - Enables retry logic with exponential backoff
* - Prevents infinite waiting for lost/dropped packets
* - Critical for client mode when waiting for ACK responses
*
* Default: INITIAL_TIMEOUT (2 seconds)
* Range: 1-300 seconds
*
* Client mode usage:
* - Wait for ACK after sending DATA packet
* - If timeout occurs, increment retry counter and resend
* - Timeout value increases exponentially: 2s → 4s → 8s → 16s → 32s (capped at MAX_TIMEOUT)
*
* Server mode usage:
* - Use non-blocking receive (network_recv_packet_nonblocking)
* - Timeout is less critical as server waits indefinitely
*/
int recv_timeout;
} network_interface_t;
/*
* ==================================================================================
* NETWORK STATISTICS STRUCTURE
* ==================================================================================
*/
/*
* network_stats_t - Network performance and error metrics
*
* This structure tracks comprehensive statistics about network operations during
* a file transfer session. It is used for:
* - Debugging network issues
* - Performance analysis
* - Identifying reliability problems (high retransmissions, checksum errors)
* - User feedback (display transfer progress)
*
* LIFECYCLE:
* 1. Initialized by network_init_stats() (zeros all fields)
* 2. Updated by network_update_stats() after each send/receive operation
* 3. Displayed by network_print_stats() at end of transfer
*
* USAGE:
* network_stats_t stats;
* network_init_stats(&stats);
* // ... perform transfers ...
* network_update_stats(&stats, 1, packet_len, 0); // Sent packet
* network_update_stats(&stats, 0, 0, 1); // Retransmission
* network_print_stats(&stats);
*
* All counters are 64-bit to prevent overflow even for very large transfers
* (e.g., 10 GB file = ~7.5 million 1400-byte packets).
*/
typedef struct {
/*
* packets_sent - Total number of packets transmitted
*
* Incremented for every successful call to network_send_packet() or
* network_send_reply(). Includes both original transmissions and
* retransmissions (counted separately in retransmissions field).
*
* Example values:
* - 1 MB file: ~750 packets (1400-byte payload)
* - 10 MB file: ~7500 packets
*/
uint64_t packets_sent;
/*
* packets_received - Total number of packets received
*
* Incremented for every successful call to network_recv_packet() or
* network_recv_packet_nonblocking() that returns valid data. Includes
* both valid and invalid packets (invalid counted in checksum_errors).
*
* Client mode: Primarily ACK responses from server
* Server mode: DATA packets from client, END packet
*/
uint64_t packets_received;
/*
* bytes_sent - Total bytes transmitted at network layer
*
* Cumulative sum of all packet sizes sent, including:
* - ICMP header (8 bytes)
* - IFTP header (24 bytes)
* - IFTP payload (0-1400 bytes)
*
* Does NOT include:
* - IP header (added by kernel)
* - Link layer headers (Ethernet, etc.)
*
* Used to calculate transfer throughput and verify file size.
*/
uint64_t bytes_sent;
/*
* bytes_received - Total bytes received at network layer
*
* Cumulative sum of all packet sizes received. Includes all received
* packets, even those discarded due to checksum errors or protocol
* violations.
*/
uint64_t bytes_received;
/*
* retransmissions - Number of packet retransmissions
*
* Incremented whenever a packet is sent more than once due to:
* - Timeout waiting for ACK
* - NACK response from peer
* - Checksum error detection
*
* High retransmission count indicates:
* - Network congestion or packet loss
* - Peer overload (slow processing)
* - Aggressive timeout settings
*
* Normal values: 0-5% of packets_sent
* Problematic: >10% of packets_sent
*/
uint64_t retransmissions;
/*
* checksum_errors - Number of checksum validation failures
*
* Incremented when received packet has invalid CRC32 checksum in IFTP
* header. Indicates:
* - Network corruption (rare on wired networks)
* - Software bugs in sender
* - Malicious packet injection
*
* Should be 0 in normal operation. Any non-zero value requires investigation.
*/
uint64_t checksum_errors;
/*
* timeouts - Number of timeout events
*
* Incremented when network_recv_packet() returns timeout error (EAGAIN/
* EWOULDBLOCK) after waiting recv_timeout seconds. Indicates:
* - Packet loss
* - Peer failure or slowdown
* - Network path issues
*
* Client mode: Timeout waiting for ACK triggers retransmission
* Server mode: Timeout waiting for next DATA packet (logged but not critical)
*
* Normal values: Similar to retransmissions count
*/
uint64_t timeouts;
} network_stats_t;
/*
* ==================================================================================
* CORE NETWORK FUNCTIONS
* ==================================================================================
*/
/*
* network_init - Initialize network interface and create raw ICMP socket
*
* This function sets up the network interface for ICMP communication. It performs
* the following operations:
*
* 1. Creates raw socket (requires root privileges):
* - IPv4: socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)
* - IPv6: socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)
*
* 2. Resolves destination address (client mode only):
* - Accepts IPv4 addresses: "192.168.1.100"
* - Accepts IPv6 addresses: "::1", "fe80::1"
* - Accepts hostnames: "example.com"
* - Uses getaddrinfo() for resolution
*
* 3. Sets default timeouts (2 seconds send, 2 seconds receive)
*
* 4. Initializes network_interface_t structure fields
*
* PRIVILEGE REQUIREMENTS:
* Raw sockets require CAP_NET_RAW capability or effective UID 0 (root).
* The application verifies root privileges in argument parser before calling
* this function.
*
* ERROR HANDLING:
* - Returns -1 and sets error context on failure
* - Common errors:
* * EPERM: Insufficient privileges for raw socket
* * EPROTONOSUPPORT: ICMP protocol not supported by kernel
* * EAI_*: getaddrinfo() resolution failures
*
* @param net: Network interface structure to initialize (output parameter)
* @param dest_address: Destination IP address or hostname (NULL for server mode)
*
* @return:
* 0: Success - socket created and destination resolved
* -1: Failure - error details in error context
*/
int network_init(network_interface_t *net, const char *dest_address);
/*
* network_send_packet - Send ICMP packet to destination
*
* Transmits a complete ICMP packet to the destination address stored in the
* network interface structure. The packet must already contain:
* - ICMP header (8 bytes) with correct type, code, checksum
* - IFTP header (24 bytes) with protocol fields
* - Optional payload (0-1400 bytes)
*
* CHECKSUM HANDLING:
* - IPv4: Caller MUST calculate ICMP checksum using network_calculate_icmp_checksum()
* - IPv6: Checksum field MUST be 0, kernel calculates automatically (RFC 3542)
*
* SEND BEHAVIOR:
* - Uses sendto() syscall with destination from net->dest_addr
* - Blocks until packet is accepted by kernel (rarely blocks in practice)
* - Respects SO_SNDTIMEO timeout if configured
* - Returns number of bytes accepted by kernel (not necessarily transmitted)
*
* MTU CONSIDERATIONS:
* This function does NOT perform fragmentation. Caller must ensure packet_len
* does not exceed path MTU (typically 1500 bytes). Use network_get_mtu() to
* query MTU if needed.
*
* ERROR HANDLING:
* - EMSGSIZE: Packet too large for MTU (reduce payload size)
* - ENETUNREACH: Network unreachable (routing problem)
* - EHOSTUNREACH: Host unreachable (no route to destination)
* - EAGAIN: Send buffer full (temporary, retry)
*
* @param net: Initialized network interface
* @param packet: Complete ICMP packet with headers and payload
* @param packet_len: Total packet length in bytes (ICMP + IFTP + payload)
*
* @return:
* >0: Number of bytes sent (should equal packet_len)
* -1: Error occurred (details in error context)
*/
int network_send_packet(network_interface_t *net, const void *packet, size_t packet_len);
/*
* network_recv_packet - Receive ICMP packet (blocking with timeout)
*
* Receives an ICMP packet from the network interface. This function blocks
* until a packet arrives or the receive timeout expires (configured via
* network_set_timeout() or defaults to INITIAL_TIMEOUT).
*
* RECEIVE BEHAVIOR:
* - Uses recvfrom() syscall
* - Blocks until packet arrives or timeout (SO_RCVTIMEO)
* - Returns source address of sender (useful for server replies)
* - May receive packets destined for other ICMP applications (filtering required)
*
* PACKET FILTERING:
* This function returns ALL ICMP Echo-Request/Reply packets received by the
* kernel, not just those for this application. Caller MUST:
* 1. Verify ICMP type (Echo-Request/Reply)
* 2. Verify IFTP magic number (0xDEADBEEF)
* 3. Verify session ID matches expected session
* 4. Verify CRC32 checksum
*
* IPv4 BEHAVIOR:
* - Receives packets WITH IP header prepended (use IPPROTO_ICMP)
* - Caller must skip IP header (typically 20 bytes) to access ICMP header
* - IP header length varies (check IHL field)
*
* IPv6 BEHAVIOR:
* - Receives packets WITHOUT IPv6 header (kernel strips it)
* - First byte in buffer is ICMPv6 header
*
* TIMEOUT HANDLING:
* - Returns -1 with errno = EAGAIN or EWOULDBLOCK on timeout
* - Caller should check errno and retry if appropriate
* - Client mode: Timeout waiting for ACK triggers retransmission
*
* @param net: Initialized network interface
* @param buffer: Buffer to receive packet data (min MAX_BUFFER_SIZE = 2048 bytes)
* @param buffer_len: Size of receive buffer
* @param src_addr: Output parameter for source address of received packet (can be NULL)
* @param src_addr_len: Input/output parameter for src_addr length (can be NULL)
*
* @return:
* >0: Number of bytes received (total packet size including headers)
* 0: Connection closed (rare for raw sockets)
* -1: Error occurred (check errno for timeout vs. real error)
*/
int network_recv_packet(network_interface_t *net, void *buffer, size_t buffer_len,
struct sockaddr_storage *src_addr, socklen_t *src_addr_len);
/*
* network_recv_packet_nonblocking - Receive ICMP packet (non-blocking)
*
* Same as network_recv_packet() but sets socket to non-blocking mode before
* receiving. This function returns immediately if no packet is available.
*
* PURPOSE:
* Used primarily in server mode where we want to:
* - Poll for incoming packets without blocking forever
* - Process multiple concurrent sessions
* - Implement session timeouts
*
* BEHAVIOR:
* 1. Sets socket to non-blocking mode (fcntl F_SETFL O_NONBLOCK)
* 2. Calls recvfrom() which returns immediately
* 3. Restores socket to blocking mode
*
* RETURN VALUES:
* - >0: Packet received (length in bytes)
* - -1 with errno = EAGAIN/EWOULDBLOCK: No packet available (NOT an error)
* - -1 with other errno: Real error occurred
*
* @param net: Initialized network interface
* @param buffer: Buffer to receive packet data
* @param buffer_len: Size of receive buffer
* @param src_addr: Output parameter for source address (can be NULL)
* @param src_addr_len: Input/output parameter for src_addr length (can be NULL)
*
* @return:
* >0: Number of bytes received
* -1: No packet available (errno = EAGAIN) or error
*/
int network_recv_packet_nonblocking(network_interface_t *net, void *buffer, size_t buffer_len,
struct sockaddr_storage *src_addr, socklen_t *src_addr_len);
/*
* network_send_reply - Send ICMP Echo Reply to specific address
*
* Convenience function for server mode to send ICMP Echo Reply packets back
* to a client. This is used to send ACK/NACK responses after receiving DATA
* packets.
*
* BEHAVIOR:
* - Creates ICMP Echo Reply packet (type 0 for IPv4, type 129 for IPv6)
* - Sets ICMP ID and sequence from original request (stored in payload)
* - Calculates checksum (IPv4 only)
* - Sends to specified destination address
*
* DIFFERENCE FROM network_send_packet():
* - network_send_packet(): Sends to net->dest_addr (client mode)
* - network_send_reply(): Sends to specified address (server mode)
*
* @param net: Initialized network interface
* @param payload: IFTP packet payload (contains ACK/NACK response)
* @param payload_len: Length of payload
* @param dest_addr: Destination address (client that sent the request)
* @param dest_addr_len: Length of destination address
*
* @return:
* >0: Number of bytes sent
* -1: Error occurred
*/
int network_send_reply(network_interface_t *net, const void *payload, size_t payload_len,
const struct sockaddr_storage *dest_addr, socklen_t dest_addr_len);
/*
* network_cleanup - Clean up network interface and close socket
*
* Releases all resources associated with the network interface. This function:
* 1. Closes raw socket using SAFE_CLOSE macro
* 2. Zeros network_interface_t structure
*
* SAFE TO CALL MULTIPLE TIMES:
* Uses SAFE_CLOSE which sets sockfd = -1 after closing, making subsequent
* calls safe no-ops.
*
* MUST BE CALLED:
* Failure to call this function leaks a file descriptor. Always call in
* cleanup paths, even on error.
*
* @param net: Network interface to clean up
*/
void network_cleanup(network_interface_t *net);
/*
* ==================================================================================
* NETWORK UTILITY FUNCTIONS
* ==================================================================================
*/
/*
* network_set_timeout - Configure send and receive timeouts
*
* Updates the socket timeout values using setsockopt() with SO_SNDTIMEO and
* SO_RCVTIMEO options. Timeouts are specified in seconds and converted to
* struct timeval internally.
*
* TIMEOUT EFFECTS:
* - Send timeout: Maximum time to wait for send buffer space
* - Receive timeout: Maximum time to wait for incoming packet
*
* DEFAULT VALUES:
* Both timeouts default to INITIAL_TIMEOUT (2 seconds) set by network_init().
*
* EXPONENTIAL BACKOFF:
* Client mode typically increases recv_timeout on each retry:
* Attempt 1: 2 seconds
* Attempt 2: 4 seconds
* Attempt 3: 8 seconds
* Attempt 4: 16 seconds
* Attempt 5: 30 seconds (capped at MAX_TIMEOUT)
*
* @param net: Network interface to configure
* @param send_timeout: Send timeout in seconds (1-300)
* @param recv_timeout: Receive timeout in seconds (1-300)
*
* @return:
* 0: Success
* -1: Error setting socket options
*/
int network_set_timeout(network_interface_t *net, int send_timeout, int recv_timeout);
/*
* network_get_mtu - Query path MTU to destination
*
* Attempts to determine the Maximum Transmission Unit (MTU) for the path to
* the destination address. This is useful for optimizing packet size to avoid
* IP-level fragmentation.
*
* METHODS:
* 1. Query IP_MTU socket option (Linux-specific)
* 2. Parse /proc/sys/net/ipv4/route (fallback)
* 3. Return default 1500 if unable to determine
*
* TYPICAL MTU VALUES:
* - Ethernet: 1500 bytes
* - PPPoE: 1492 bytes
* - VPN: 1400 bytes
* - Internet (safe minimum): 576 bytes
*
* USAGE:
* This application uses fixed MAX_PAYLOAD_SIZE = 1400 bytes which is
* conservative and should work on all networks. This function is provided
* for future optimization but not currently used.
*
* @param net: Initialized network interface
* @param dest_address: Destination IP address or hostname
*
* @return:
* >0: Path MTU in bytes
* -1: Unable to determine MTU
*/
int network_get_mtu(network_interface_t *net, const char *dest_address);
/*
* network_addr_to_string - Convert socket address to string representation
*
* Converts sockaddr_storage (IPv4 or IPv6) to human-readable string format
* using inet_ntop().
*
* OUTPUT FORMATS:
* - IPv4: "192.168.1.100"
* - IPv6: "fe80::1", "2001:db8::1"
*
* BUFFER SIZE:
* Caller must provide buffer of at least INET6_ADDRSTRLEN (46) bytes to
* accommodate longest possible IPv6 address string.
*
* @param addr: Socket address to convert
* @param buffer: Output buffer for string representation
* @param buffer_size: Size of output buffer (min INET6_ADDRSTRLEN)
*
* @return:
* Pointer to buffer on success
* NULL on error
*/
const char *network_addr_to_string(const struct sockaddr_storage *addr, char *buffer, size_t buffer_size);
/*
* network_compare_addresses - Compare two socket addresses for equality
*
* Compares two socket addresses to determine if they refer to the same host.
* Handles both IPv4 and IPv6 addresses correctly.
*
* COMPARISON:
* - Checks address family matches (AF_INET vs AF_INET6)
* - Compares address bytes using memcmp()
* - Ignores port numbers
* - IPv6 scope ID is NOT compared
*
* USAGE:
* Server mode uses this to verify that ACK responses come from the same
* client that sent the original request (prevents hijacking).
*
* @param addr1: First address to compare
* @param addr2: Second address to compare
*
* @return:
* 0: Addresses are equal
* -1: Addresses differ or comparison error
*/
int network_compare_addresses(const struct sockaddr_storage *addr1, const struct sockaddr_storage *addr2);
/*
* ==================================================================================
* STATISTICS FUNCTIONS
* ==================================================================================
*/
/*
* network_init_stats - Initialize statistics structure to zero
*
* Zeros all fields in network_stats_t structure. Should be called once at
* the beginning of a transfer session.
*
* @param stats: Statistics structure to initialize
*/
void network_init_stats(network_stats_t *stats);
/*
* network_update_stats - Update statistics after network operation
*
* Updates statistics counters based on the result of a network operation.
* This function is called after each successful send or receive.
*
* @param stats: Statistics structure to update
* @param sent: 1 if operation was a send, 0 if receive
* @param bytes: Number of bytes sent or received
* @param retransmit: 1 if this was a retransmission, 0 otherwise
*/
void network_update_stats(network_stats_t *stats, int sent, size_t bytes, int retransmit);
/*
* network_print_stats - Display statistics summary to stdout
*
* Prints a formatted summary of network statistics including:
* - Total packets and bytes sent/received
* - Retransmission count and percentage
* - Checksum error count
* - Timeout count
*
* OUTPUT EXAMPLE:
* Network Statistics:
* - Packets sent: 750
* - Packets received: 750
* - Bytes sent: 1050000 (1.00 MB)
* - Bytes received: 18000 (0.02 MB)
* - Retransmissions: 5 (0.67%)
* - Checksum errors: 0
* - Timeouts: 5
*
* @param stats: Statistics structure to display
*/
void network_print_stats(const network_stats_t *stats);
/*
* ==================================================================================
* CHECKSUM FUNCTIONS
* ==================================================================================
*/
/*
* network_calculate_icmp_checksum - Calculate ICMPv4 checksum
*
* Computes the Internet Checksum (RFC 1071) for an ICMPv4 packet. This is
* the standard 16-bit one's complement checksum used by IP, ICMP, UDP, TCP.
*
* ALGORITHM (RFC 1071):
* 1. Set checksum field to 0
* 2. Sum all 16-bit words in the packet
* 3. Add carry bits to the sum
* 4. Take one's complement (~sum)
*
* USAGE:
* IPv4 ICMP packets MUST have checksum calculated by application:
* icmp_hdr->checksum = 0;
* icmp_hdr->checksum = network_calculate_icmp_checksum(packet, packet_len);
*
* IPv6 ICMPv6 packets MUST NOT use this function - kernel calculates automatically.
*
* PADDING:
* If packet length is odd, a zero byte is appended for checksum calculation
* only (not transmitted).
*
* @param data: ICMP packet data (starting at ICMP header)
* @param len: Length of packet in bytes
*
* @return: 16-bit checksum value (in network byte order, ready to use)
*/
uint16_t network_calculate_icmp_checksum(const void *data, size_t len);
#endif /* NETWORK_H */