You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

330 lines
14 KiB

/**
@file dns.h
@brief Implement Simple Domain Name System Protocol
*/
#ifndef __DNS_H
#define __DNS_H
/*
<Message Format>
+---------------------+
| Header |
+---------------------+
| Question | the question for the name server
+---------------------+
| Answer | Resource Records answering the question
+---------------------+
| Authority | Resource Records pointing toward an authority
+---------------------+
| Additional | Resource Records holding additional information
+---------------------+
As follow, example of DNS Standard Query
+---------------------------------------------------+
Header | OPCODE=SQUERY |
+---------------------------------------------------+
Question | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=A |
+---------------------------------------------------+
Answer | <empty> |
+---------------------------------------------------+
Authority | <empty> |
+---------------------------------------------------+
Additional | <empty> |
+---------------------------------------------------+
As follow, example of DNS response
+---------------------------------------------------+
Header | OPCODE=SQUERY, RESPONSE, AA |
+---------------------------------------------------+
Question | QNAME=SRI-NIC.ARPA., QCLASS=IN, QTYPE=A |
+---------------------------------------------------+
Answer | SRI-NIC.ARPA. 86400 IN A 26.0.0.73 |
| 86400 IN A 10.0.0.51 |
+---------------------------------------------------+
Authority | <empty> |
+---------------------------------------------------+
Additional | <empty> |
+---------------------------------------------------+
*/
/* QCLASS values
CLASS fields appear in resource records. The following CLASS mnemonics
and values are defined:
*/
/* CLASS */
#define CLASS_IN 1 /**< the Internet */
#define CLASS_CS 2 /**< the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */
#define CLASS_CH 3 /**< the CHAOS class */
#define CLASS_HS 4 /**< Hesiod [Dyer 87] */
/* QCLASS */
#define QCLASS_ANY 255 /**< any class */
/* QTYPE values
TYPE fields are used in resource records. Note that these types are a subset of QTYPEs.
*/
/* TYPE */
#define TYPE_A 1 /**< The ARPA Internet */
#define TYPE_NS 2 /**< an authoritative name server */
#define TYPE_MD 3 /**< a mail destination (Obsolete - use MX) */
#define TYPE_MF 4 /**< a mail forwarder (Obsolete - use MX) */
#define TYPE_CNAME 5 /**< the canonical name for an alias */
#define TYPE_SOA 6 /**< marks the start of a zone of authority */
#define TYPE_MB 7 /**< a mailbox domain name (EXPERIMENTAL) */
#define TYPE_MG 8 /**< a mail group member (EXPERIMENTAL) */
#define TYPE_MR 9 /**< a mail rename domain name (EXPERIMENTAL)*/
#define TYPE_NULL 10 /**< a null RR (EXPERIMENTAL) */
#define TYPE_WKS 11 /**< a well known service description */
#define TYPE_PTR 12 /**< a domain name pointer */
#define TYPE_HINFO 13 /**< host information */
#define TYPE_MINFO 14 /**< mailbox or mail list information */
#define TYPE_MX 15 /**< mail exchange */
#define TYPE_TXT 16 /**< text strings */
/* QTYPE */
#define QTYPE_AXFR 252 /**< A request for a transfer of an entire zone */
#define QTYPE_MAILB 253 /**< A request for mailbox-related records (MB, MG or MR) */
#define QTYPE_MAILA 254 /**< A request for mail agent RRs (Obsolete - see MX) */
#define QTYPE_TYPE_ALL 255 /**< A request for all records */
#define INITRTT 2000L /**< Initial smoothed response time */
#define MAXCNAME 10 /**< Maximum amount of cname recursion */
/* Round trip timing parameters */
#define AGAIN 8 /**< Average RTT gain = 1/8 */
#define LAGAIN 3 /**< Log2(AGAIN) */
#define DGAIN 4 /**< Mean deviation gain = 1/4 */
#define LDGAIN 2 /**< log2(DGAIN) */
#define IPPORT_DOMAIN 53
/* Header for all domain messages */
/*
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
*/
/*A four bit field that specifies kind of query in this
message. This value is set by the originator of a query
and copied into the response. The values are:
*/
#define OP_QUERY 0 /**< a standard query (QUERY) */
#define OP_IQUREY 1 /**< an inverse query (IQUERY) */
#define OP_STATUS 2 /**< a server status request (STATUS)*/
/* A one bit field that specifies whether this message is a query (0), or a response (1). */
#define QR_QUERY 0
#define QR_RESPONSE 1
/* Response code - this 4 bit field is set as part of
responses. The values have the following interpretation:
*/
#define RC_NO_ERROR 0 /**< No error condition */
#define RC_FORMAT_ERROR 1 /**< Format error - The name server was unable to interpret the query. */
#define RC_SERVER_FAIL 2 /**< Server failure - The name server was unable to process this query due to a problem with the name server. */
#define RC_NAME_ERROR 3 /**< Name Error - Meaningful only for responses from an authoritative name server, this code signifies that the domain name referenced in the query does not exist.*/
#define RC_NOT_IMPL 4 /**< Not Implemented - The name server does not support the requested kind of query.*/
#define RC_REFUSED 5 /**< Refused - The name server refuses to perform the specified operation for policy reasons.
For example, a name server may not wish to provide the information to the particular requester,
or a name server may not wish to perform a particular operation (e.g., zone */
#define DHDR_SIZE 12
/**
@brief Header for all domain messages
*/
typedef struct _DHDR
{
u_int id; /**< Identification */
u_char flag0;
u_char flag1;
u_int qdcount; /**< Question count */
u_int ancount; /**< Answer count */
u_int nscount; /**< Authority (name server) count */
u_int arcount; /**< Additional record count */
}DHDR;
/* rd : Recursion desired , tc : Truncation, aa : Authoratative answer, opcode : op code = OP_QUREY, OP_IQUREY, OP_STAUTS, qr : Query/Response */
#define MAKE_FLAG0(qr,op,aa,tc,rd) ( ((qr & 0x01) << 7) + ((op & 0x0F) << 3) + ((aa & 0x01) << 2) + ((tc & 0x01) << 1) + (rd & 0x01) )
/* rcode : Response code, z : Reserved for future use. Must be zero in all queries and responses, */
/* ra : Recursion Available - this be is set or cleared in a response, and denotes whether recursive query support is available in the name server.*/
#define MAKE_FLAG1(ra,z,rcode) ( ((ra & 0x01) << 7) + ((z & 0x07) << 4) + (rcode & 0x0F) )
/*
<QUESTION FORMAT >
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ QNAME /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where:
QNAME a domain name represented as a sequence of labels, where
each label consists of a length octet followed by that
number of octets. The domain name terminates with the
zero length octet for the null label of the root. Note
that this field may be an odd number of octets; no
padding is used.
QTYPE a two octet code which specifies the type of the query.
The values for this field include all codes valid for a
TYPE field, together with some more general codes which
can match more than one type of RR.
QCLASS a two octet code that specifies the class of the query.
For example, the QCLASS field is IN for the Internet.
*/
/**
@brief QUESTION FORMAT
*/
typedef struct _QUESTION
{
// char* qname; // Variable length data
u_int qtype;
u_int qclass;
}DQST;
/*
Resource record format
The answer, authority, and additional sections all share the same
format: a variable number of resource records, where the number of
records is specified in the corresponding count field in the header.
Each resource record has the following format:
1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ /
/ NAME /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
/ RDATA /
/ /
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where:
NAME a domain name to which this resource record pertains.
In order to reduce the size of messages, the domain system utilizes a
compression scheme which eliminates the repetition of domain names in a
message. In this scheme, an entire domain name or a list of labels at
the end of a domain name is replaced with a pointer to a prior occurance
of the same name.
The pointer takes the form of a two octet sequence:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| 1 1| OFFSET |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
The first two bits are ones. This allows a pointer to be distinguished
from a label, since the label must begin with two zero bits because
labels are restricted to 63 octets or less. (The 10 and 01 combinations
are reserved for future use.) The OFFSET field specifies an offset from
the start of the message (i.e., the first octet of the ID field in the
domain header). A zero offset specifies the first byte of the ID field,
etc.
The compression scheme allows a domain name in a message to be
represented as either:
- a sequence of labels ending in a zero octet
- a pointer
- a sequence of labels ending with a pointer
TYPE two octets containing one of the RR type codes. This
field specifies the meaning of the data in the RDATA
field.
CLASS two octets which specify the class of the data in the
RDATA field.
TTL a 32 bit unsigned integer that specifies the time
interval (in seconds) that the resource record may be
cached before it should be discarded. Zero values are
interpreted to mean that the RR can only be used for the
transaction in progress, and should not be cached.
RDLENGTH an unsigned 16 bit integer that specifies the length in
octets of the RDATA field.
RDATA a variable length string of octets that describes the
resource. The format of this information varies
according to the TYPE and CLASS of the resource record.
For example, the if the TYPE is A and the CLASS is IN,
the RDATA field is a 4 octet ARPA Internet address.
*/
#define COMPRESSION_SCHEME 0xC0
/**
@brief Resource record format
The answer, authority, and additional sections all share the same
format: a variable number of resource records, where the number of
records is specified in the corresponding count field in the header.
Each resource record has the following format:
*/
typedef struct _RESOURCE_RECORD
{
// char* _name; // Variable length data
u_int _type;
u_int _class;
u_int _ttl;
u_int _rdlen;
// char* _rdata; // Variable length data
}DRR;
#define MAX_DNSMSG_SIZE 512 /**< Maximum size of DNS message */
#define MAX_DOMAINNAME_LEN 50 /**< Maximum size of domain name */
#define MAX_QNAME_LEN 128 /**< Maximum size of qname */
typedef enum _QUERYDATA{BYNAME,BYIP}QUERYDATA; /* Query type */
/* Resolve domain name or ip address from DNS server */
extern u_char dns_query(SOCKET s, u_long dnsip, u_char * domain_name, u_long* domain_ip,QUERYDATA querydata, u_int elapse);
extern int gethostbyaddr(u_long ipaddr,char* domain); // gethostbyaddr function retrieves the host domain name corresponding to a network address
extern u_long gethostbyname(char* hostname); // gethostbyname function retrieves host ip address corresponding to a host name
#endif