feat: dns header decoding

This commit is contained in:
Emi Aline Boucly 2025-08-23 18:51:10 +02:00
commit 01ed0bd7dd
4 changed files with 111 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
dns

6
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,6 @@
{
"files.associations": {
"stdio.h": "c",
"netdb.h": "c"
}
}

89
dns.c Normal file
View file

@ -0,0 +1,89 @@
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/socket.h>
#include <unistd.h>
#include "dnshdr.h"
int main()
{
int sockfd;
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd < 0) {
perror("Couldn't open socket. Is port available ?");
}
struct sockaddr_in server_addr;
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = INADDR_ANY;
server_addr.sin_port = htons(5353);
if (bind(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {
perror("Couldn't bind socket to ip/port.");
close(sockfd);
return 1;
}
unsigned char* buffer = calloc(512, sizeof(char*));
struct sockaddr_in client_addr;
socklen_t client_len = sizeof(client_addr);
while (1) {
int buflen;
buflen = recvfrom(sockfd, buffer, 512, 0, (struct sockaddr*)&client_addr, &client_len);
if (buflen < 0) {
perror("Unable to receive data");
continue;
}
printf("===== New request! %d bytes. =====\n", buflen);
printf("Hexdump: \n");
for(int i = 0; i<buflen; i++)
{
printf("%02x ", buffer[i]);
if ((i + 1) % 8 == 0) printf(" ");
if ((i + 1) % 32 == 0) printf("\n");
}
printf("\n");
struct dnshdr *hdr = (struct dnshdr*) buffer;
uint16_t flags = ntohs(hdr->flags);
printf("Id : %d\n", ntohs(hdr->id));
printf("Flags : QR=%d OPCODE=%d AA=%d TC=%d RD=%d RA=%d Z=%d AD=%d CD=%d RCODE=%d\n",
(flags & 0x8000) >> 15,
(flags & 0x7800) >> 11,
(flags & 0x0400) >> 10,
(flags & 0x0200) >> 9,
(flags & 0x0100) >> 8,
(flags & 0x0080) >> 7,
(flags & 0x0040) >> 6,
(flags & 0x0020) >> 5,
(flags & 0x0010) >> 4,
(flags & 0X000F)
);
printf("Qdcount : %d\n", ntohs(hdr->qdcount));
printf("Ancount : %d\n", ntohs(hdr->ancount));
printf("Nscount : %d\n", ntohs(hdr->nscount));
printf("Arcount : %d\n", ntohs(hdr->arcount));
}
free(buffer);
close(sockfd);
return 1;
}

15
dnshdr.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef DNSHDR_H
#define DNSHDR_H
#include <stdint.h>
struct dnshdr {
uint16_t id; /* Identifiant sur 16 bit à faire correspondre pour la réponse */
uint16_t flags; /* Liste des flags => QR, Opcode, AA, TC, RD, RA, Z, RCODE */
uint16_t qdcount; /* Quantité d'entrées dans la section de questions */
uint16_t ancount; /* Quantité d'entrées dans la section de réponses */
uint16_t nscount; /* Quantité d'entrées de serveur de noms dans la section d'autorité */
uint16_t arcount; /* Quantité d'entrées dans la section de ressources additionnelles */
} __attribute__((packed));
#endif