UDP
- El Protocolo de Datagramas de Usuario (UDP) es un protocolo de transporte ligero, parte del conjunto TCP/IP.
- A diferencia de TCP, no proporciona mecanismos de comprobaci贸n de errores ni garantiza la entrega.
DNS
El Sistema de Nombres de Dominio (DNS) traduce nombres de dominio legibles
para humanos (como example.com) en direcciones IP entendibles
por los sistemas de red.
Para qu茅 sirve: Facilita la navegaci贸n en Internet al permitir que los usuarios usen nombres amigables en lugar de memorizar direcciones IP num茅ricas.
Ejemplo en lenguaje C
Ejemplo en lenguaje C, que implementa parte de los est谩ndares relacionados con UDP y DNS. Para los dem谩s protocolos (como IMAP), necesitar铆as bibliotecas espec铆ficas que cumplan con los est谩ndares de la IETF:
C贸digo: Cliente DNS usando UDP
Este programa consulta un servidor DNS para resolver un nombre de dominio en su direcci贸n IP.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define DNS_SERVER "8.8.8.8" // Servidor DNS p煤blico de Google
#define DNS_PORT 53 // Puerto est谩ndar de DNS
#define BUFFER_SIZE 512 // Tama帽o del buffer para mensajes DNS
void build_dns_query(unsigned char *buffer, const char *hostname);
void parse_dns_response(unsigned char *buffer);
int main() {
int sockfd;
struct sockaddr_in server_addr;
unsigned char buffer[BUFFER_SIZE];
// Crear socket UDP
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("Error al crear socket");
exit(EXIT_FAILURE);
}
// Configurar direcci贸n del servidor DNS
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(DNS_PORT);
server_addr.sin_addr.s_addr = inet_addr(DNS_SERVER);
// Construir consulta DNS
const char *hostname = "example.com"; // Dominio a resolver
memset(buffer, 0, BUFFER_SIZE);
build_dns_query(buffer, hostname);
// Enviar consulta al servidor DNS
if (sendto(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("Error al enviar consulta DNS");
close(sockfd);
exit(EXIT_FAILURE);
}
// Recibir respuesta del servidor DNS
socklen_t addr_len = sizeof(server_addr);
if (recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&server_addr, &addr_len) < 0) {
perror("Error al recibir respuesta DNS");
close(sockfd);
exit(EXIT_FAILURE);
}
// Parsear respuesta DNS
parse_dns_response(buffer);
// Cerrar socket
close(sockfd);
return 0;
}
void build_dns_query(unsigned char *buffer, const char *hostname) {
// Cabecera DNS
buffer[0] = 0xAB; // ID de la consulta
buffer[1] = 0xCD;
buffer[2] = 0x01; // Flags: consulta est谩ndar
buffer[3] = 0x00;
buffer[4] = 0x00; // N煤mero de preguntas
buffer[5] = 0x01;
buffer[6] = 0x00; // Respuestas, autoritativas, adicionales
buffer[7] = 0x00;
buffer[8] = 0x00;
buffer[9] = 0x00;
// Pregunta DNS
unsigned char *qname = &buffer[12];
const char *token = strtok((char *)hostname, ".");
while (token) {
size_t len = strlen(token);
*qname++ = len;
memcpy(qname, token, len);
qname += len;
token = strtok(NULL, ".");
}
*qname++ = 0x00; // Fin del nombre de dominio
buffer[qname - buffer] = 0x00; // Tipo de consulta A (direcci贸n IPv4)
buffer[qname - buffer + 1] = 0x01;
buffer[qname - buffer + 2] = 0x00; // Clase IN (Internet)
buffer[qname - buffer + 3] = 0x01;
}
void parse_dns_response(unsigned char *buffer) {
printf("Respuesta DNS recibida.\n");
// Aqu铆 puedes implementar l贸gica para analizar la respuesta DNS
// y extraer direcciones IP, CNAME, etc.
}
Explicaci贸n del c贸digo
- Construcci贸n de una consulta DNS: El programa construye un paquete DNS, que incluye la cabecera y el nombre de dominio a resolver.
- Comunicaci贸n UDP: Utiliza sockets UDP para enviar y recibir paquetes DNS hacia/desde el servidor.
- Parseo de respuesta DNS: Despu茅s de recibir la respuesta, el programa puede analizarla para extraer la direcci贸n IP asociada al dominio.
