Envoi de données via le protocole DNS
Bonjour,
Je suis actuellement en train de créer un mini-resolver, client DNS, qui permet la résolution d'adresse uniquement dans un sens : L'utilisateur entre un nom de site et le client DNS va se charger de lui donner l'adresse IP correspondante (client qui va dialoguer avec un serveur DNS, mais ca je ne m'en occupe pas).
Ayant lu le RFC 1035 correspondant, j'ai commencé par faire simplement un envoi de requêtes (suivant le rfc donc).
Cependant, j'ai un problème de sendto(), celui ci me retourne -1. Je ne vois pas pourquoi, il me semble avoir bien appliquer le rfc 1035 pourtant.
Voici mon code source :
le .h
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
|
#include "base.h"
#ifndef __CLIENTDNS_H_
#define __CLIENTDNS_H_
/*
RFC 1035 shows the structure of DNS message as follows
+---------------------+
| Header |
+---------------------+
| Question | the question for the name server
+---------------------+
| Answer | RRs answering the question
+---------------------+
| Authority | RRs pointing toward an authority
+---------------------+
| Additional | RRs holding additional information
+---------------------+
*/
/*
This is the structure of a DNS header :
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| Opcode |AA|TC|RD|RA| Z | RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QDCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| NSCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ARCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
ID :the identifier
QDCOUNT : how many question are there in the packet.
ANCOUNT : how many answers in the RR queue.
NSCOUNT : Authority RR count
ARCOUNT : Additional Count
*/
typedef struct
{
unsigned short id; // identification number
unsigned char rd :1; // recursion desired
unsigned char tc :1; // truncated message
unsigned char aa :1; // authoritive answer
unsigned char opcode :4; // purpose of message
unsigned char qr :1; // query/response flag
unsigned char rcode :4; // response code
unsigned char cd :1; // checking disabled
unsigned char ad :1; // authenticated data
unsigned char z :1; // its z! reserved
unsigned char ra :1; // recursion available
unsigned short q_count; // number of question entries
unsigned short ans_count; // number of answer entries
unsigned short auth_count; // number of authority entries
unsigned short add_count; // number of resource entries
}DNS_HEADER;
/*
A Query structure looks like this
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
| QNAME |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QTYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| QCLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Note : QNAME is a variable length field to fit the hostname
QCLASS should be 1 since we are on internet
QTYPE determines what you want to know ; ipv4 address , mx etc.
*/
typedef struct
{
unsigned char* qname;
unsigned short qtype;
unsigned short qclass;
}QUESTION;
/*
Resource Record(RR) field looks like this
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
| |
| NAME |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TYPE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| CLASS |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| TTL |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
| RDATA |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Note again : NAME and RDATA are variable length field
Type field tells how RDATA relates to NAME. e.g. if TYPE is 1 then RDATA
contains the ipv4 address of the NAME.
Thats all about the structures we need.
*/
typedef struct
{
unsigned short type;
unsigned short _class;
unsigned int ttl;
unsigned short data_len;
} R_DATA;
typedef struct
{
unsigned char *name;
R_DATA *resource;
unsigned char *rdata;
} RES_RECORD;
typedef struct
{
unsigned char *name;
struct QUESTION *ques;
} QUERY;
//Function Prototypes
void ngethostbyname(void);
#endif |
Et mon .c (je ne mets pas le main, c'est juste un appel a ngethostbyname, le site www.google.fr étant déjà en dur.) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
void ngethostbyname(void)
{
int i,s; unsigned char buf[65536];
i=0;
struct sockaddr_in dest;
DNS_HEADER *dns = NULL;
QUESTION *qinfo = NULL;
s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries
dest.sin_family = AF_INET;
dest.sin_port = htons(53);
dest.sin_addr.s_addr = inet_addr("dns1.proxad.net"); //dns servers
//Set the DNS structure to standard queries
dns = (DNS_HEADER *)&buf;
dns->id = (unsigned short) htons(getpid());
dns->qr = 0; //This is a query
dns->opcode = 0; //This is a standard query
dns->aa = 1; //Not Authoritative
dns->tc = 0; //This message is not truncated
dns->rd = 1; //Recursion Desired
dns->ra = 0;
dns->z = 0;
dns->ad = 0;
dns->cd = 0;
dns->rcode = 0;
dns->q_count = htons(1); //we have only 1 question
dns->ans_count = 0;
dns->auth_count = 0;
dns->add_count = 0;
// Query = ?
//qname =(unsigned char*)&buf[sizeof(DNS_HEADER)];
//qname = (unsigned char*)"3www6google3com0";
qinfo = (QUESTION*)&buf[sizeof(DNS_HEADER)];// + (strlen((const char*)qname) + 1)]; //fill it
qinfo->qname = (unsigned char*) "3www6google3com0";
qinfo->qtype = htons(1); //we are requesting the ipv4 address
qinfo->qclass = htons(1); // internet
printf("Envoie du Packet...\n");
if(sendto(s,(char*) buf,sizeof(DNS_HEADER) + sizeof(QUESTION),0,(struct sockaddr*)&dest,sizeof(dest)) == -1)
{
printf("Error sending socket\n");
}
} |
Pourriez vous m'aiguiller à ce sujet ? J'avoue être bien embêté :?
Merci d'avance,
Bonne journée.