/* 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 SIZE_DNS 12

#define IPv4_ETHERTYPE 0x800

#define IPv6_ETHERTYPE 0x86DD

#define UDP 17

#define DNS_PORT 53

/* 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; /* IP? ARP? RARP? etc */
};

/* IPv6 header. RFC 2460, section3. Reading /usr/include/netinet/ip6.h is
 * interesting */
struct sniff_ipv6 {
    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 */
};
#define IP_VERSION(ip)          (ntohl((ip)->ip_vtcfl) >> 28)

/* IPv4 header */
struct sniff_ipv4 {
    u_char          ip_vhl;     /* version << 4 | header length >> 2 */
    u_char          ip_tos;     /* type of service */
    u_short         ip_len;     /* total length */
    u_short         ip_id;      /* identification */
    u_short         ip_off;     /* fragment offset field */
#define IP_RF 0x8000            /* reserved fragment flag */
#define IP_DF 0x4000            /* dont fragment flag */
#define IP_MF 0x2000            /* more fragments flag */
#define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */
    u_char          ip_ttl;     /* time to live */
    u_char          ip_p;       /* protocol */
    u_short         ip_sum;     /* checksum */
    struct in_addr  ip_src, ip_dst;     /* source and dest address */
};
#define IP_HL(ip)               (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip)                (((ip)->ip_vhl) >> 4)

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

struct sniff_dns {
    /* RFC 1035, section 4.1 */
    uint16_t        query_id;
    uint16_t        codes;
    uint16_t        qdcount, ancount, nscount, arcount;
};
#define DNS_QR(dns)		((ntohs(dns->codes) & 0x8000) >> 15)
#define DNS_OPCODE(dns)	((ntohs(dns->codes) >> 11) & 0x000F)
#define DNS_RCODE(dns)	(ntohs(dns->codes) & 0x000F)
#define NXDOMAIN 3

