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