/* Ethernet addresses are 6 bytes */
#define ETHER_ADDR_LEN	6

/* Ethernet headers are always exactly 14 bytes */
#define SIZE_ETHERNET 14

#define SIZE_IPv6 40

#define SIZE_UDP 8

#define IPv6_ETHERTYPE 0x86DD

#define TCP 6
#define UDP 17
#define ICMP 58

#define SIZE_FRAGMENT_HDR 8

#define IP_VERSION(ip)		(ntohl((ip)->ip_vtcfl) >> 28)

/* Ethernet header */
struct sniff_ethernet {
    uint8_t         ether_dhost[ETHER_ADDR_LEN];        /* Destination host address */
    uint8_t         ether_shost[ETHER_ADDR_LEN];        /* Source host address */
    uint16_t        ether_type; /* IPv6? IPv4? etc */
};

        /* IPv6 header. RFC 2460, section3. Reading /usr/include/netinet/ip6.h is
         * interesting */
struct sniff_ip {
    uint32_t        ip_vtcfl;   /* version << 4 then traffic class and flow label */
    uint16_t        ip_len;     /* payload length */
    uint8_t         ip_nxt;     /* next header (protocol) */
    uint8_t         ip_hopl;    /* hop limit (ttl) */
    struct in6_addr ip_src, ip_dst;     /* source and dest address */
};

struct sniff_eh {
    uint8_t         eh_next;    /* next header (protocol) */
    uint8_t         eh_length;
};

struct sniff_frag {
    uint8_t         frag_next;  /* next header (protocol) */
    uint8_t         frag_reserved;
    uint16_t        frag_offset_res_m;  /* Fragment offset then Reserved then M flag 
                                         */
    uint32_t        frag_identification;
};
#define FRAG_OFFSET(frag) (ntohs(frag->frag_offset_res_m) >> 3)

/* UDP header */
struct sniff_udp {
    uint16_t        sport;      /* source port */
    uint16_t        dport;      /* destination port */
    uint16_t        udp_length;
    uint16_t        udp_sum;    /* checksum */
};

