ref: 272dec2602bfb557af9464d21426d195b8e8e1a5
dir: /common.h/
#include <openssl/x509v3.h>
#include <pcap.h>
/*
* each parser have at least these two
* they may have more functions internally and externally
*/
typedef struct
{
char *name;
int (*parse)();
void (*print)();
void (*free)();
}Parser;
extern pcap_t *handle;
extern struct bpf_program filter;
extern int debug;
/* common.c */
extern unsigned long pos;
extern const u_char *pkt;
extern ulong pktlen;
#define PKTHEAD pkt + pos
uint16_t get2(const u_char *octet);
uint32_t get4(const u_char *octet);
void get(const u_char *pkt, int size, ...);
void err(int fatal, char *fmt, ...);
void *emalloc(ulong size);
void *memdup(const void *src, ulong len);
/* ether.c */
enum
{
ETHER_LEN = 14,
ETHER_ADDR_LEN = 6,
/* sizes of each field in header */
ETHER_DST = ETHER_ADDR_LEN,
ETHER_SRC = ETHER_ADDR_LEN,
ETHER_TYPE = 2,
/* ether types */
ETHER_IP4 = 0x800,
ETHER_IP6 = 0x86dd,
};
typedef struct
{
uint32_t start;
uint8_t dst[ETHER_ADDR_LEN];
uint8_t src[ETHER_ADDR_LEN];
uint16_t type;
}Ether;
char* etherTypeToStr(uint16_t frame);
int parseEther(const u_char *pkt, Ether *e);
void printEther(Ether e);
extern Parser etherParser;
/* (ipv4) pkt.c */
enum
{
PKT_VHL = 1,
PKT_DSFIELD = 1,
PKT_LEN = 2,
PKT_ID = 2,
// PKT_FLAGS = 1, /* 3 bits */
PKT_FRAGOFFSET = 2, /* 12 bits */
PKT_TTL = 1,
PKT_PROTO = 1,
PKT_SUM = 2,
PKT_SRC = 4,
PKT_DST = 4,
/* packet types */
PKT_TCP = 6,
PKT_UDP = 17,
};
typedef struct
{
uint32_t start;
uint8_t version;
uint8_t headerlen;
uint8_t dsfield;
uint8_t len;
uint16_t id;
uint8_t flags;
uint16_t fragoffset;
uint8_t ttl;
uint8_t proto; /* UDP, TCP */
uint16_t sum; /* checksum of packet */
uint32_t srcip;
uint32_t dstip;
}Pkt;
#define IP4_HL(octet) (octet & 0x0f)
#define IP4_V(octet) (octet >> 4)
int parsePkt(const u_char *pkt, Pkt *p);
char* pktTypeToStr(const u_char pkt);
void printPkt(Pkt p);
extern Parser pktParser;
/* udp.c */
enum
{
/* udp stuff */
UDP_SIZE = 8,
UDP_SRCPORT = 2,
UDP_DSTPORT = 2,
UDP_LEN = 2,
UDP_SUM = 2,
};
typedef struct
{
uint32_t start;
uint16_t src;
uint16_t dst;
uint16_t len;
uint16_t sum;
}Udp;
int parseUdp(const u_char *pkt, Udp *udp);
void printUdp(Udp udp);
extern Parser udpParser;
/* tcp.c */
enum
{
/* tcp sizes */
TCP_SRCPORT = 2,
TCP_DSTPORT = 2,
TCP_SEQNUM = 4,
TCP_ACKNUM = 4,
TCP_OFFSET = 1, /* half a byte is used */
TCP_FLAGS = 1,
TCP_WINSIZE = 2,
TCP_SUM = 2,
TCP_URGPTR = 2,
TCP_OPTS = 2,
/* tcp flags @ 13 */
TCP_FLAG_ACK = 0x010,
TCP_FLAG_PSH = 0x008,
TCP_FLAG_SYN = 0x002,
TCP_FLAG_FIN = 0x001,
};
typedef struct
{
uint32_t start;
uint16_t src;
uint16_t dst;
uint32_t seq;
uint32_t ack;
uint16_t offset;
uint16_t flags;
uint16_t winsize;
uint8_t sum;
uint16_t urgentptr;
/* we don't care about options */
}Tcp;
int parseTcp(const u_char *pkt, Tcp *tcp);
void printTcp(Tcp tcp);
extern Parser tcpParser;
/*
* dns.c
* a maximum size of 255 for strings is assumed
*/
enum
{
/* dns */
DNS_ID = 2,
DNS_FLAGS = 2,
DNS_COUNT_QUERIES = 2,
DNS_COUNT_ANSWERS = 2,
DNS_COUNT_AUTH_RR = 2,
DNS_COUNT_ADD_RR = 2,
DNS_TYPE = 2,
DNS_CLASS = 2,
DNS_BACKREF = 2, /* that c0 ff thingi which back references */
DNS_TTL = 4,
DNS_LEN = 2,
/* dns flags bits @ 2 */
DNS_ISRESP = 0x8000,
DNS_OPCODE = 0x7800,
DNS_FLAGS_OPCODE_QUERY = 0x4000,
DNS_FLAGS_OPCODE_IQUERY = 0x2000,
DNS_FLAGS_OPCODE_STATUS = 0x1000, /* 2 bits */
DNS_FLAGS_OPCODE_NOTIFY = 0x0800,
DNS_AUTH = 0x0400,
DNS_TRUNCATED = 0x0200,
DNS_RD = 0x0100,
DNS_RA = 0x0080,
DNS_Z = 0x0040,
DNS_AD = 0x0020,
DNS_CD = 0x0010,
DNS_RCODE = 0x000F,
/* dns types */
DNS_TYPE_A = 1,
DNS_TYPE_CNAME = 5,
DNS_TYPE_SOA = 6,
DNS_TYPE_MX = 15,
DNS_TYPE_TXT = 16,
DNS_TYPE_AAAA = 28,
/* dns classes */
DNS_CLASS_IN = 1, /* lonely :( */
DNS_MAX_LEN = 255,
};
typedef struct
{
uint32_t start;
/* is it response or request */
uint16_t id;
uint16_t flags;
/* count(s) */
uint16_t nQueries;
uint16_t nAnswers;
uint16_t nAuthRR;
uint16_t nAddRR;
char domain[DNS_MAX_LEN+1];
uint16_t type;
uint16_t class;
uint32_t ttl;
uint32_t len;
union
{
/* A */
uint8_t ip[4];
/* AAAA */
uint16_t ip6[8];
/* CNAME */
u_char cname[DNS_MAX_LEN+1];
};
}Dns;
int parseDnsName(const u_char *pkt, char *buf, u_char len);
int parseDnsCname(const u_char *pkt, Dns *d, uint len);
int parseDns(const u_char *pkt, Dns *dns);
char* dnsClassToStr(uint16_t class);
char* dnsTypeToStr(uint16_t type);
void printDns(Dns dns);
extern Parser dnsParser;
/* der.c */
enum
{
/* der tags */
DER_TAG_INT = 0x2,
DER_TAG_BITSTR = 0x3,
DER_TAG_OCTSTR = 0x4,
DER_TAG_NULL = 0x5,
DER_TAG_OID = 0x6,
DER_TAG_UTF8STR = 0xc,
DER_TAG_SEQ = 0x10,
DER_TAG_SET = 0x11,
DER_TAG_PRINTSTR = 0x13,
DER_TAG_IA5STR = 0x16,
DER_TAG_UTCTIME = 0x17,
DER_TAG_GENERALTIME = 0x18,
DER_TAG_SEQOF = 0x30,
DER_TAG_SETOF = 0x31,
/* der tag classes */
DER_CLASS_UNIVERSAL = 0,
DER_CLASS_APPLICATION = 1,
DER_CLASS_CONTEXT = 2,
DER_CLASS_PRIVATE = 3,
DER_CN_MAX = 1024,
};
typedef struct
{
uint32_t start;
uint64_t len; /* of cert */
X509 *cert;
char *subject;
char *issuer;
char *commonName[DER_CN_MAX];
uint16_t nCommonName;
uint8_t selfsigned;
}Der;
int parseDer(const u_char *pkt, Der *der);
void printDer(Der der);
extern Parser derParser;
/* tls.c */
enum
{
/* tls record */
TLS_RECORD = 5,
TLS_RECORD_CONTENTTYPE = 1,
TLS_RECORD_VERSION = 2,
TLS_RECORD_LEN = 2,
/* tls record versions */
SSL_30 = 0x300,
TLS_10 = 0x301,
TLS_11 = 0x302,
TLS_12 = 0x303,
TLS_13 = 0x304,
/* tls 1.2 (client) handshake */
TLS_HANDSHAKE_HEADER = 4,
TLS_HANDSHAKE_TYPE = 1,
TLS_HANDSHAKE_LEN = 3,
TLS_HANDSHAKE_VERSION = 2,
TLS_HANDSHAKE_RANDOM = 32,
TLS_HANDSHAKE_SESSIONID_LEN = 1,
/* TLS_HANDSHAKE_SESSIONID = ??, */
TLS_HANDSHAKE_CIPHERS_LEN = 2,
/* TLS_HANDSHAKE_CIPHERS = ?? , */
TLS_HANDSHAKE_CIPHER = 2,
TLS_HANDSHAKE_COMP_LEN = 1,
TLS_HANDSHAKE_COMP = 1,
/* TLS_HANDSHAKE_COMPS = 1?, */
TLS_HANDSHAKE_EXTS_LEN = 2, /* number of all extensions */
TLS_HANDSHAKE_EXT_TYPE = 2,
TLS_HANDSHAKE_EXT_LEN = 2, /* (data) length of a specfic extension */
TLS_HANDSHAKE_CERTS_LEN = 3,
TLS_HANDSHAKE_CERT_LEN = 3,
/* tls 1.2 (server) handshake */
TLS_HANDSHAKE_COMPS = 1,
/* tls SNI */
TLS_SNI_LISTLEN = 2,
TLS_SNI_TYPE = 1,
TLS_SNI_LEN = 2,
/* tls supported versions */
TLS_SV_LEN = 1,
TLS_SV_DATA = 2,
/* tls handshake types */
TLS_HELLO_REQ = 0,
TLS_CLIENT_HELLO = 1,
TLS_SERVER_HELLO = 2,
TLS_NEW_TICKET = 4,
TLS_END_OF_EARLY_DATA = 5,
TLS_CERT = 11,
TLS_SERVER_KEY_EXCH = 12,
TLS_SERVER_HELLO_DONE = 14,
TLS_CERT_REQ = 13,
TLS_CLIENT_KEY_EXCH = 16,
TLS_FINISHED = 20,
TLS_CERT_STATUS = 22,
/* tls content types */
TLS_CTYPE_ALERT = 21,
TLS_CTYPE_HANDSHAKE = 22,
TLS_CTYPE_APPLICATION_DATA = 23,
TLS_CTYPE_HEARTBEAT = 24,
TLS_CTYPE_CID = 25, /* ? */
TLS_CTYPE_ACK = 26,
TLS_CTYPE_RTC = 27, /* ? */
/* tls extensions */
TLS_EXT_SNI = 0,
TLS_EXT_PADDING = 21,
TLS_EXT_SUPPORTED_VERS = 43,
};
typedef struct
{
uint32_t start;
char *name;
uint8_t len;
uint8_t *data;
}TlsTuple;
/* supported versions */
typedef struct
{
uint8_t len;
uint16_t *vers;
}TlsExtensionSv;
/* server name */
typedef struct
{
uint16_t listLen;
uint8_t type;
uint16_t len;
char *name;
}TlsExtensionSni;
typedef struct
{
uint32_t start;
uint16_t type;
uint16_t len;
union
{
TlsExtensionSv *sv;
TlsExtensionSni *sni;
u_char *data;
};
}TlsExtension;
typedef struct
{
uint32_t start;
uint32_t len;
Der *der;
}TlsCert;
typedef struct
{
uint32_t start;
uint8_t type;
uint32_t len;
uint16_t version;
uint8_t random[TLS_HANDSHAKE_RANDOM];
TlsTuple *sessionId;
union
{
/* client hello */
struct
{
TlsTuple *cipherSuits;
TlsTuple *compressionMethods;
};
/* server hello */
struct
{
uint16_t cipherSuit;
uint8_t compressionMethod;
};
/* cert */
struct
{
uint32_t certsLen;
uint32_t nCerts;
TlsCert *certs;
};
};
uint16_t extensionsLen; /* length of extentions in bytes */
uint16_t nExtensions; /* number of actual extentions */
TlsExtension *extensions;
}TlsHandshake;
typedef struct
{
uint32_t start;
uint8_t type;
uint16_t version; /* record version */
uint16_t len;
uint8_t nHandshakes;
TlsHandshake *handshakes;
}Tls;
int parseTlsTuple(const u_char *pkt, TlsTuple *tuple);
int parseTlsRecord(const u_char *pkt, Tls *tls);
int parseTlsExtensions(const u_char *pkt, TlsHandshake *hs);
int parseTlsHandshake(const u_char *pkt, TlsHandshake *hs);
int parseTls(const u_char *pkt, Tls *tls);
void printTlsTuple(TlsTuple tuple);
void printTlsHandshake(TlsHandshake hs);
void printTlsRecord(Tls tls);
void printTls(Tls tls);
void printTlsExtension(TlsExtension e);
void printTlsExtensions(TlsHandshake hs);
void freeTls(Tls *tls);
extern Parser tlsParser;