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 : Sélectionner tout - Visualiser dans une fenêtre à part
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.
 
That’s 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 : Sélectionner tout - Visualiser dans une fenêtre à part
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.