1
0
This repository has been archived on 2024-07-22. You can view files and clone it, but cannot push or open issues or pull requests.
TP-Link_Archer-XR500v/EN7526G_3.18Kernel_SDK/apps/public/dproxy-nexgen/dns_construct.c
2024-07-22 01:58:46 -03:00

106 lines
3.6 KiB
C
Executable File

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
//#include <asm/unaligned.h>
#include <string.h>
#include "dns_construct.h"
#define get_unaligned(ptr) \
({ __typeof__(*(ptr)) __tmp; memmove(&__tmp, (ptr), sizeof(*(ptr))); __tmp; })
#define put_unaligned(val, ptr) \
({ __typeof__(*(ptr)) __tmp = (val); \
memmove((ptr), &__tmp, sizeof(*(ptr))); \
(void)0; })
#define SET_UINT16_TO_N(buf, val, count) put_unaligned(htons(val), (uint16*)buf);count += 2; buf += 2
#define SET_UINT32_TO_N(buf, val, count) put_unaligned(htonl(val), (uint32*)buf);count += 4; buf += 4
/*****************************************************************************/
/* this function encode the plain string in name to the domain name encoding
* see decode_domain_name for more details on what this function does. */
int dns_construct_name(char *name, char *encoded_name)
{
int i,j,k,n;
k = 0; /* k is the index to temp */
i = 0; /* i is the index to name */
while( name[i] ){
/* find the dist to the next '.' or the end of the string and add it*/
for( j = 0; name[i+j] && name[i+j] != '.'; j++);
encoded_name[k++] = j;
/* now copy the text till the next dot */
for( n = 0; n < j; n++)
encoded_name[k++] = name[i+n];
/* now move to the next dot */
i += j + 1;
/* check to see if last dot was not the end of the string */
if(!name[i-1])break;
}
encoded_name[k++] = 0;
return k;
}
/*****************************************************************************/
int dns_construct_header(dns_request_t *m)
{
char *ptr = m->original_buf;
int dummy;
SET_UINT16_TO_N( ptr, m->message.header.id, dummy );
SET_UINT16_TO_N( ptr, m->message.header.flags.flags, dummy );
SET_UINT16_TO_N( ptr, m->message.header.qdcount, dummy );
SET_UINT16_TO_N( ptr, m->message.header.ancount, dummy );
SET_UINT16_TO_N( ptr, m->message.header.nscount, dummy );
SET_UINT16_TO_N( ptr, m->message.header.arcount, dummy );
return 0;
}
/*****************************************************************************/
void dns_construct_reply( dns_request_t *m )
{
int len;
/* point to end of orginal packet */
m->here = &m->original_buf[m->numread];
m->message.header.ancount = 1;
m->message.header.flags.f.question = 1;
dns_construct_header( m );
if( m->message.question[0].type == A ){
/* standard lookup so return and IP */
struct in_addr in;
inet_aton( m->ip, &in );
SET_UINT16_TO_N( m->here, 0xc00c, m->numread ); /* pointer to name */
SET_UINT16_TO_N( m->here, A, m->numread ); /* type */
SET_UINT16_TO_N( m->here, IN, m->numread ); /* class */
SET_UINT32_TO_N( m->here, 10000, m->numread ); /* ttl */
SET_UINT16_TO_N( m->here, 4, m->numread ); /* datalen */
memcpy( m->here, &in.s_addr, sizeof(in.s_addr) ); /* data */
m->numread += sizeof( in.s_addr);
}else if ( m->message.question[0].type == PTR ){
/* reverse look up so we are returning a name */
SET_UINT16_TO_N( m->here, 0xc00c, m->numread ); /* pointer to name */
SET_UINT16_TO_N( m->here, PTR, m->numread ); /* type */
SET_UINT16_TO_N( m->here, IN, m->numread ); /* class */
SET_UINT32_TO_N( m->here, 10000, m->numread ); /* ttl */
len = dns_construct_name( m->cname, m->here + 2 );
SET_UINT16_TO_N( m->here, len, m->numread ); /* datalen */
m->numread += len;
}
}
/*****************************************************************************/
void dns_construct_error_reply(dns_request_t *m)
{
/* point to end of orginal packet */
m->here = m->original_buf;
m->message.header.flags.f.question = 1;
m->message.header.flags.f.rcode = 2;
dns_construct_header( m );
}