3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
27 #include <net/packet.h>
29 #include <net/socket.h>
31 dns_cache_t dns_cache_list
;
35 unsigned short dns_trans
= NULL
;
37 #define DEFAULT_DNS_ADDRESS NET_IPV4_TO_ADDR (192,168,0,1)
40 unsigned dns_cache_add (char *hostname
, unsigned short len
, net_ipv4 ip
);
43 unsigned dns_addr (net_ipv4 dns
)
50 net_ipv4
dns_addr_get ()
55 net_ipv4
dns_send_request (char *hostname
)
60 if ((sock
= socket (AF_INET
, SOCK_DGRAM
, IPPROTO_UDP
)) == -1)
62 puts ("Cant create socket\n");
66 sockaddr_in serverSock
;
68 serverSock
.sin_family
= AF_INET
;
69 serverSock
.sin_port
= htons (DEFAULT_DNS_PORT
);
70 memcpy (&(serverSock
.sin_addr
), &dns_ip
, sizeof (net_ipv4
));
72 // Lets connect to dns server
73 if (connect (sock
, (sockaddr
*) &serverSock
, sizeof (serverSock
)) == -1)
75 puts ("ERROR -> Connection cant be estabilished\n");
79 unsigned short len
= strlen (hostname
);
81 proto_dns_t
*dns
= (proto_dns_t
*) kmalloc (sizeof (proto_dns_t
)+len
+7);
87 dns
->trans
= swap16 (dns_trans
++);
88 dns
->flags
= swap16 (0x0100);
89 dns
->question
= swap16 (1);
94 char *dns_
= (char *) dns
;
97 // correct - dsl.cz : 03 64 73 6c 02 63 7a 00
98 // incorrect - dsl.cz : 06 64 73 6c 2e 63 7a 00 ..
100 unsigned short type
= swap16 (1);
101 unsigned short class = swap16 (1);
103 char *name_coded
= (char *) kmalloc (sizeof (char) * (len
+ 2));
108 memcpy (name_coded
+1, hostname
, len
);
109 name_coded
[len
+1] = '\0';
116 if (name_coded
[i
] == '.' || name_coded
[i
] == '\0') {
130 memcpy (dns_
+12, name_coded
, len
+2);
131 memcpy (dns_
+14+len
, (char *) &type
, 2);
132 memcpy (dns_
+16+len
, (char *) &class, 2);
134 int ret
= send (sock
, (char *) dns
, sizeof (proto_dns_t
)+len
+6, 0);
137 char *buf
= (char *) kmalloc (192 * sizeof (char));
142 ret
= recv (sock
, buf
, 192, 0);
146 /* dns server send respond */
148 proto_dns_t
*dns_res
= (proto_dns_t
*) buf
;
150 /* all is ok, no error */
151 if (dns_res
->flags
== 0x8081) {
152 memcpy (&target
, buf
+sizeof (proto_dns_t
)+len
+6+12, 4);
154 dns_cache_add (hostname
, len
, target
);
168 unsigned dns_cache_add (char *hostname
, unsigned short len
, net_ipv4 ip
)
171 for (cache
= dns_cache_list
.next
; cache
!= &dns_cache_list
; cache
= cache
->next
) {
172 if (!strcmp (cache
->hostname
, hostname
))
176 /* alloc and init context */
177 cache
= (dns_cache_t
*) kmalloc (sizeof (dns_cache_t
));
185 cache
->hostname
= (char *) kmalloc (sizeof (char) * (cache
->len
+ 1));
187 if (!cache
->hostname
)
190 memcpy (cache
->hostname
, hostname
, cache
->len
);
191 cache
->hostname
[len
] = '\0';
194 cache
->next
= &dns_cache_list
;
195 cache
->prev
= dns_cache_list
.prev
;
196 cache
->prev
->next
= cache
;
197 cache
->next
->prev
= cache
;
202 net_ipv4
dns_cache_get (char *hostname
)
206 for (cache
= dns_cache_list
.next
; cache
!= &dns_cache_list
; cache
= cache
->next
) {
207 if (!strcmp (cache
->hostname
, hostname
))
215 unsigned init_net_proto_dns ()
217 dns_cache_list
.next
= &dns_cache_list
;
218 dns_cache_list
.prev
= &dns_cache_list
;
222 dns_addr (DEFAULT_DNS_ADDRESS
);
224 /* any preset address for irc :) */
225 dns_cache_add ("irc.freenode.net", 16, NET_IPV4_TO_ADDR (207,158,1,150));
226 dns_cache_add ("kornbluth.freenode.net", 22, NET_IPV4_TO_ADDR (82,96,64,4));