/*
 * Header for file which contained RAW icmp functions
 */
#define STATUS_FAILED 0xFFFF
#define DEF_PACKET_SIZE 32
#define MAX_PACKET 65535

#define ICMP_MIN_SIZE    8
/* ICMP types */
#define ICMP_ECHO        8
#define ICMP_ECHOREPLY    0

/* IP header */
typedef struct iphdr {
    unsigned int     h_len:4;             /* Length of the header */
    unsigned int     version:4;            /* Version of IP    */
    unsigned char     tos;                 /* Type of service */
    unsigned short     total_len;          /* Total length of the packet */
    unsigned short     ident;              /* Unique identifier */
    unsigned short     frag_and_flags;     /* flags */
    unsigned char      ttl;                /* TTL */
    unsigned char     proto;               /* protocol (TCP, UDP etc) */
    unsigned short     checksum;           /* IP checksum */
    unsigned int     source_ip;
    unsigned int     destination_ip;
}ip_header;

/* ICMP header */
typedef struct _ihdr {
  uint8_t    i_type;
  uint8_t    i_code; /* type sub code */
  uint16_t    i_cksum;
  uint16_t    i_id;
  uint16_t    i_seq;
  /* This is not the std header, but we reserve space for time */
  uint32_t    timestamp;
}icmp_header;

struct recving_echoes_params
{
    struct config *     common_params;
    uint32_t             dst_ip;
    CRITICAL_SECTION *     critical_section;
    uint32_t *             unfinished_echoes;
};

#define xmalloc(s) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (s))
#define xfree(p)   HeapFree (GetProcessHeap(), 0, (p))

/* Send 'packets_count' ICMP-echoes to host 'ip_addr'. 
 * 'critical_section' - must be not null.     Pointer to a critical section 
 * in which a meter increase in requests that do not have the answers.
 * 'unfinished_echoes' - pointer to counter of unfinished echoes
 */
uint32_t send_echoes(uint32_t ip_addr, int32_t data_size, int32_t packets_count, 
                        CRITICAL_SECTION * critical_section, uint32_t * unfinished_echoes);
/* Receive 'packets_count' ICMP-echoes to host 'ip_addr'. 
 * 'critical_section' - must be not null.     Pointer to a critical section 
 * in which a reduction of meter requests that do not have the answers.
 * 'unfinished_echoes' - pointer to counter of unfinished echoes
 */
uint32_t recv_echoes(uint32_t ip_addr, int32_t data_size, int32_t packets_count, 
                        CRITICAL_SECTION * critical_section, uint32_t * unfinished_echoes);
/* Wrapper function for running  recv_echoes() in separate thread */
unsigned __stdcall recving_echoes_threads( void* arg );