ZDE button.c - source code cleanup; ZDE cursor.c - improvement of mouse flags; ZDE...
[ZeXOS.git] / kernel / core / net / dns.c
blobc07ae2e4be2adf79446e837563ad1492ce1a25d7
1 /*
2 * ZeX/OS
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/>.
20 #include <system.h>
21 #include <string.h>
22 #include <dev.h>
23 #include <net/eth.h>
24 #include <net/net.h>
25 #include <net/if.h>
26 #include <net/ip.h>
27 #include <net/packet.h>
28 #include <net/dns.h>
29 #include <net/socket.h>
31 dns_cache_t dns_cache_list;
33 net_ipv4 dns_ip;
35 unsigned short dns_trans = NULL;
37 #define DEFAULT_DNS_ADDRESS NET_IPV4_TO_ADDR (192,168,0,1)
39 /* prototype */
40 unsigned dns_cache_add (char *hostname, unsigned short len, net_ipv4 ip);
43 unsigned dns_addr (net_ipv4 dns)
45 dns_ip = dns;
47 return 1;
50 net_ipv4 dns_addr_get ()
52 return dns_ip;
55 net_ipv4 dns_send_request (char *hostname)
57 int sock = 0;
59 // Create a socket
60 if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
62 puts ("Cant create socket\n");
63 return 0;
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");
76 return 0;
79 unsigned short len = strlen (hostname);
81 proto_dns_t *dns = (proto_dns_t *) kmalloc (sizeof (proto_dns_t)+len+7);
83 if (!dns)
84 return 0;
86 /* dns header */
87 dns->trans = swap16 (dns_trans ++);
88 dns->flags = swap16 (0x0100);
89 dns->question = swap16 (1);
90 dns->answer = 0;
91 dns->auth = 0;
92 dns->add = 0;
94 char *dns_ = (char *) dns;
96 /* dns queries */
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));
105 if (!name_coded)
106 return 0;
108 memcpy (name_coded+1, hostname, len);
109 name_coded[len+1] = '\0';
111 unsigned i = 1;
112 unsigned y = 0;
113 unsigned z = 0;
115 while (i < len+2) {
116 if (name_coded[i] == '.' || name_coded[i] == '\0') {
117 if (y == 0)
118 name_coded[0] = i-1;
119 else
120 name_coded[y] = z-1;
122 y = i;
123 z = 0;
126 i ++;
127 z ++;
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);
136 /* it is not done */
137 char *buf = (char *) kmalloc (192 * sizeof (char));
139 if (!buf)
140 return 0;
142 ret = recv (sock, buf, 192, 0);
144 net_ipv4 target = 0;
146 /* dns server send respond */
147 if (ret) {
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);
158 sclose (sock);
160 kfree (buf);
161 kfree (dns);
163 return target;
167 /* DNS Cache */
168 unsigned dns_cache_add (char *hostname, unsigned short len, net_ipv4 ip)
170 dns_cache_t *cache;
171 for (cache = dns_cache_list.next; cache != &dns_cache_list; cache = cache->next) {
172 if (!strcmp (cache->hostname, hostname))
173 return 0;
176 /* alloc and init context */
177 cache = (dns_cache_t *) kmalloc (sizeof (dns_cache_t));
179 if (!cache)
180 return 0;
182 cache->ip = ip;
183 cache->len = len;
185 cache->hostname = (char *) kmalloc (sizeof (char) * (cache->len + 1));
187 if (!cache->hostname)
188 return 0;
190 memcpy (cache->hostname, hostname, cache->len);
191 cache->hostname[len] = '\0';
193 /* add into list */
194 cache->next = &dns_cache_list;
195 cache->prev = dns_cache_list.prev;
196 cache->prev->next = cache;
197 cache->next->prev = cache;
199 return 1;
202 net_ipv4 dns_cache_get (char *hostname)
204 dns_cache_t *cache;
206 for (cache = dns_cache_list.next; cache != &dns_cache_list; cache = cache->next) {
207 if (!strcmp (cache->hostname, hostname))
208 return cache->ip;
212 return 0;
215 unsigned init_net_proto_dns ()
217 dns_cache_list.next = &dns_cache_list;
218 dns_cache_list.prev = &dns_cache_list;
220 dns_trans = 1024;
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));
228 return 1;