/***************************************************************************
 *   Copyright (C) 2004-2008 by Giovanni Venturi                           *
 *   giovanni@ksniffer.org                                                 *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA  02110-1301, USA.          *
 ***************************************************************************/

#ifndef PACKETSTRUCTURES_H
#define PACKETSTRUCTURES_H

#include <ctype.h>
#include <stdlib.h>
#include <pcap.h>
#include <endian.h>

// Max packet dimention
#define IPMAX   65535
#define HDRMAX  64
#define PKTMAX  (IPMAX+HDRMAX)

// IP header structure
struct IpHdr
{
#if __BYTE_ORDER == __LITTLE_ENDIAN
    u_int8_t    ihl:4,
                version:4;
#elif __BYTE_ORDER == __BIG_ENDIAN
    u_int8_t    version:4,
                ihl:4;
#endif
    u_int8_t     tos;
    u_int16_t    tot_len;
    u_int16_t    id;
    u_int16_t    frag_off;
    u_int8_t     ttl;
    u_int8_t     protocol;
    u_int16_t    check;
    u_int32_t    saddr;
    u_int32_t    daddr;
};

// UDP header structure
struct UdpHdr
{
    u_int16_t    uh_sport;     // source port
    u_int16_t    uh_dport;     // destination port
    u_int16_t    uh_ulen;      // udp length
    u_int16_t    uh_sum;       // udp checksum
};

// TCP header structure
struct TcpHdr
{
    u_int16_t    th_sport;               // source port
    u_int16_t    th_dport;               // destination port
    u_int32_t    th_seq;                 // sequence number
    u_int32_t    th_ack;                 // acknowledgement number
#if __BYTE_ORDER == __LITTLE_ENDIAN
    u_int8_t    th_x2:4,                // (unused)
                th_off:4;               // data offset
#elif __BYTE_ORDER == __BIG_ENDIAN
    u_int8_t    th_off:4,               // data offset
                th_x2:4;                // (unused)
#endif
    u_int8_t    th_flags;
    u_int16_t   th_win;                 // window
    u_int16_t   th_sum;                 // checksum
    u_int16_t   th_urp;                 // urgent pointer
};

// ICMP header structure
struct IcmpHdr
{
    u_int8_t          type;
    u_int8_t          code;
    u_int16_t         checksum;
    union
    {
        struct
        {
            u_int16_t   id;
            u_int16_t   sequence;
        } echo; // called echo since it's the most used
        u_int32_t   gateway;
    } un;
};

struct ArpHdr
{
  unsigned short  ar_hrd;         // format of hardware address
  unsigned short  ar_pro;         // format of protocol address
  unsigned char   ar_hln;         // length of hardware address
  unsigned char   ar_pln;         // length of protocol address
  unsigned short  ar_op;          // ARP opcode (command)

  unsigned char   ar_sha[6];      // sender hardware address
  unsigned char   ar_sip[4];      // sender IP address
  unsigned char   ar_tha[6];      // target hardware address
  unsigned char   ar_tip[4];      // target IP address
};

typedef u_char packetType;
typedef packetType* ptrPacketType;
typedef bpf_u_int32 lengthTypePacket;

#endif
