From 01ed0bd7ddfda6b3eecaeca5804e4e6862b603b0 Mon Sep 17 00:00:00 2001 From: Ako Date: Sat, 23 Aug 2025 18:51:10 +0200 Subject: [PATCH] feat: dns header decoding --- .gitignore | 1 + .vscode/settings.json | 6 +++ dns.c | 89 +++++++++++++++++++++++++++++++++++++++++++ dnshdr.h | 15 ++++++++ 4 files changed, 111 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 dns.c create mode 100644 dnshdr.h diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..01d7a5d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +dns \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cd32f93 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "files.associations": { + "stdio.h": "c", + "netdb.h": "c" + } +} \ No newline at end of file diff --git a/dns.c b/dns.c new file mode 100644 index 0000000..6f3d4eb --- /dev/null +++ b/dns.c @@ -0,0 +1,89 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#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; iflags); + + 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; + +} \ No newline at end of file diff --git a/dnshdr.h b/dnshdr.h new file mode 100644 index 0000000..6ad8422 --- /dev/null +++ b/dnshdr.h @@ -0,0 +1,15 @@ +#ifndef DNSHDR_H +#define DNSHDR_H + +#include + +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