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. 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.) :
Pourriez vous m'aiguiller à ce sujet ? J'avoue être bien embêté
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"); } }
Merci d'avance,
Bonne journée.
Partager