feat: dns header decoding
This commit is contained in:
commit
01ed0bd7dd
4 changed files with 111 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
dns
|
||||
6
.vscode/settings.json
vendored
Normal file
6
.vscode/settings.json
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"stdio.h": "c",
|
||||
"netdb.h": "c"
|
||||
}
|
||||
}
|
||||
89
dns.c
Normal file
89
dns.c
Normal 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
15
dnshdr.h
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue