/*
* Cliente DNS que resuelve servidores MAIL EXCHANGE
* (Servidores de correo), con peticiones recursivas.
* Adrián Ruiz Bermudo 2005-06.
*/
#include
#include
#include
#define size 1024
/*
* Prototipos
*/
//Prepara la estructura para conectar con el servidor
int conexion_dns_mx(char*, int);
//Extrae el dominio para realizar la consulta
char *extract_dom_mx(char*);
//Envía y recibe el paquete de la consulta
int sendrecv_packet_mx(int,char*);
//Devuelve el número de carácteres que hay en una variable
//establecidas por dos posiciones.
int tam_mail(char*,int,char,char);
//Extrae los servidores de correo del paquete recibido
int format_recv_packet(char*);
//Extrae cadenas de carácteres de los mensajes comprimidos
int compress_msg(char*);
//Copia los carácteres del paquete mientras éstos no estén comprimidos
int copy_c(char*);
/*
* Estructura de la consulta DNS a realizar
* (A modo informativo)
struct query_mx{
WORD transaction; 2 bytes, indica el número de transacción [0x0001]
WORD flags; 2 bytes, Banderas, [0x0100] indica consulta recursiva.
WORD questions; 2 bytes, número de consultas [0x0001]
WORD answer_rrs; 2 bytes, [0x0000] vacío.
WORD authority_rrs; 2 bytes, [0x0000] vacío.
WORD additional_rrs; 2 bytes, [0x0000] vacío.
char host[size]; n bytes, dominio a consultar.
WORD type; 2 bytes, tipo de servidor [0x0f00] servidor MX (correo).
WORD Class; 2 bytes, Clase del servidor [0x0001] clase IN, internet.
};
*/
struct sockaddr_in conexion; //Estructura para realizar la conexión
struct hostent *dns; //Estructura para resolver el nombre de dominio
char result[size]; //Almacena el nombre de dominio formateado para la consulta(aux)
char packet[size]; //Paquete que almacena el envío y recibo.
char dominio[size]; //Almacena el nombre de dominio formateado para la consulta
char servers_mx[size]; //Almacena los servidores resueltos
int pos_servers_mx; //Contiene la posición actual del paquete de servidores resueltos
int pos_act_packet; //Contiene la posición actual del paquete recibido
/*
* Función que conecta con el servidor DNS remoto
* y devuelve el descriptor de socket si la conexión
* se realizó con éxito, en otro caso devuelve -1
* si ocurrieron errores durante la operación.
*/
int conexion_dns_mx(char *host,int port){
int sd;
memset(&conexion,0,sizeof(conexion));
if((sd=socket(PF_INET,SOCK_DGRAM,0))<0){
perror("[SOCKET]");
return -1;
}
if((dns=gethostbyname(host))==NULL){
perror("[DNS]");
return -1;
}
conexion.sin_family = AF_INET;
conexion.sin_port = htons(port);
conexion.sin_addr = *((struct in_addr *)dns -> h_addr);
return sd;
}
/*
* Prepara el paquete para ser transferido al servidor DNS
* y por consiguiente obtiene respuesta del servidor.
*/
int sendrecv_packet_mx(int sd, char *domain){
int x,y;
/*
* Incluyendo todos los flags, hay una constante de 16 bytes +
* el dominio a consultar
*/
/*
* Banderas que indican como se va a realizar la consulta.
* Van al principio de cabecera
*/
char flags_x[] = {
"\\x00" "\\x01" //transaction
"\\x01" "\\x00" //flags
"\\x00" "\\x01" //questions
"\\x00" "\\x00" //answer_rrs
"\\x00" "\\x00" //authority_rrs
"\\x00" "\\x00" //additional_rrs
};
/*
* Banderas que indican que tipo de consulta a realizar.
* Van al final de cabecera
*/
char flags_q[] = {
"\\x00" "\\x0f" //type
"\\x00" "\\x01" //Class IN (INternet)
};
// flags_x + consulta + flag_q
memset(packet,0,size);
memcpy(packet,flags_x,11); //Copiamos la cabecera
y = 12;
for(x=0;x=tam) return NULL;
memset(result,0,size);
y = 0;
result[y] = tam_mail(mail,x+1,0x2E,0x00); // @ o NULL
y++;
z=0;
for(x=pos;x \\n\\n ",argv[0]);
else{
if(WSAStartup(MAKEWORD(2,0), &win_sock)<0){
printf("Error al crear sockets windows\\n");
return 1;
}
printf("[+] Sockets inicializados.\\n");
printf("[!] Extrayendo dominio...\\n");
if((dom = extract_dom_mx(argv[1]))==NULL){
printf("[x] Email no valido\\n");
return 1;
}
printf("[!] Conectando con el servidor DNS...\\n");
if((sock = conexion_dns_mx(argv[2],atoi(argv[3])))==-1){
printf("[x] Error durante la conexion\\n");
return 1;
}
printf("[+] Conectado correctamente\\n");
printf("[!] Transfiriendo paquete...\\n");
if(sendrecv_packet_mx(sock,dom)==-1){
printf("[x] Error al transferir paquete\\n");
return 1;
}
printf("[!] Obteniendo resultados...\\n");
if(format_recv_packet(packet)==-1){
printf("[x] Errores durante la operacion\\n");
return 1;
}
printf("%s",servers_mx);
printf("\\n** Hecho **\\n\\n\\a");
}
return 0;
}