1#include <sys/socket.h>
2#include <netinet/in.h>
3#include <arpa/inet.h>
4#include "dns_construct.h"
5
6#if 0	//CMC for alignment 8/3/2001
7#define SET_UINT16_TO_N(buf, val, count) *(uint16*)buf = htons(val);count += 2; buf += 2
8#define SET_UINT32_TO_N(buf, val, count) *(uint32*)buf = htonl(val);count += 4; buf += 4
9#else
10#define SET_UINT16_TO_N(buf, val, count)		\
11{	unsigned char	tmp[2], i;			\
12	*(uint16*)&tmp = htons(val);			\
13	for ( i = 0; i < 2; i++ )			\
14		*((unsigned char *)buf+i) = tmp[i];	\
15	count += 2; 					\
16	buf += 2;					\
17}
18#define SET_UINT32_TO_N(buf, val, count)		\
19{	unsigned char	tmp[4], i;			\
20	*(uint32*)&tmp = htonl(val);			\
21	for ( i = 0; i < 4; i++ )			\
22		*((unsigned char *)buf+i) = tmp[i];	\
23	count += 4; 					\
24	buf += 4;					\
25}
26#endif
27/*****************************************************************************/
28/* this function encode the plain string in name to the domain name encoding
29 * see decode_domain_name for more details on what this function does. */
30int dns_construct_name(char *name, char *encoded_name)
31{
32  int i,j,k,n;
33
34  k = 0; /* k is the index to temp */
35  i = 0; /* i is the index to name */
36  while( name[i] ){
37
38	 /* find the dist to the next '.' or the end of the string and add it*/
39	 for( j = 0; name[i+j] && name[i+j] != '.'; j++);
40	 encoded_name[k++] = j;
41
42	 /* now copy the text till the next dot */
43	 for( n = 0; n < j; n++)
44		encoded_name[k++] = name[i+n];
45
46	 /* now move to the next dot */
47	 i += j + 1;
48
49	 /* check to see if last dot was not the end of the string */
50	 if(!name[i-1])break;
51  }
52  encoded_name[k++] = 0;
53  return k;
54}
55/*****************************************************************************/
56int dns_construct_header(dns_request_t *m)
57{
58  char *ptr = m->original_buf;
59  int dummy;
60
61  SET_UINT16_TO_N( ptr, m->message.header.id, dummy );
62  SET_UINT16_TO_N( ptr, m->message.header.flags.flags, dummy );
63  SET_UINT16_TO_N( ptr, m->message.header.qdcount, dummy );
64  SET_UINT16_TO_N( ptr, m->message.header.ancount, dummy );
65  SET_UINT16_TO_N( ptr, m->message.header.nscount, dummy );
66  SET_UINT16_TO_N( ptr, m->message.header.arcount, dummy );
67
68  return 0;
69}
70/*****************************************************************************/
71void dns_construct_reply( dns_request_t *m )
72{
73  int len;
74
75  /* point to end of orginal packet */
76  m->here = &m->original_buf[m->numread];
77
78  m->message.header.ancount = 1;
79  m->message.header.flags.f.question = 1;
80//-----JYWeng: 20030530* modified this bit for palm
81  m->message.header.flags.f.recursion_avail = 1;
82//-----
83  dns_construct_header( m );
84
85  if( m->message.question[0].type == A ){
86    /* standard lookup so return and IP */
87    struct in_addr in;
88
89    inet_aton( m->ip, &in );
90    SET_UINT16_TO_N( m->here, 0xc00c, m->numread ); /* pointer to name */
91    SET_UINT16_TO_N( m->here, A, m->numread );      /* type */
92    SET_UINT16_TO_N( m->here, IN, m->numread );     /* class */
93    SET_UINT32_TO_N( m->here, 10000, m->numread );  /* ttl */
94    SET_UINT16_TO_N( m->here, 4, m->numread );      /* datalen */
95    memcpy( m->here, &in.s_addr, sizeof(in.s_addr) ); /* data */
96    m->numread += sizeof( in.s_addr);
97  }else if ( m->message.question[0].type == PTR ){
98    /* reverse look up so we are returning a name */
99    SET_UINT16_TO_N( m->here, 0xc00c, m->numread ); /* pointer to name */
100    SET_UINT16_TO_N( m->here, PTR, m->numread );    /* type */
101    SET_UINT16_TO_N( m->here, IN, m->numread );     /* class */
102    SET_UINT32_TO_N( m->here, 10000, m->numread );  /* ttl */
103    len = dns_construct_name( m->cname, m->here + 2 );
104    SET_UINT16_TO_N( m->here, len, m->numread );      /* datalen */
105    m->numread += len;
106  }
107}
108/*****************************************************************************/
109void dns_construct_error_reply(dns_request_t *m)
110{
111  /* point to end of orginal packet */
112  m->here = m->original_buf;
113
114  m->message.header.flags.f.question = 1;
115  m->message.header.flags.f.rcode = 2;
116  dns_construct_header( m );
117}
118