Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / kernel / core / net / ndp.c
blob5cf143c1a046ee0588253c051d21d40477568f29
1 /*
2 * ZeX/OS
3 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2009 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <system.h>
22 #include <string.h>
23 #include <dev.h>
24 #include <net/eth.h>
25 #include <net/net.h>
26 #include <net/if.h>
27 #include <net/packet.h>
28 #include <net/ip.h>
29 #include <net/icmp.h>
30 #include <net/ndp.h>
31 #include <net/tun.h>
32 #include <net/checksum.h>
34 ndp_cache_t ndp_cache_list;
35 mac_addr_t ndp_macgw;
37 extern unsigned long timer_ticks;
39 /* prototype */
42 unsigned ndp_send_nbrequest (netif_t *netif, net_ipv6 dest)
44 /* packet header */
45 packet_t *packet = (packet_t *) kmalloc (sizeof (packet_t));
47 if (!packet)
48 return 0;
50 char id[2];
51 memcpy (&id, (void *) &dest[7], sizeof (unsigned short));
53 mac_addr_t mac_dest;
54 mac_dest[0] = 0x33;
55 mac_dest[1] = 0x33;
56 mac_dest[2] = 0xff;
57 mac_dest[3] = 0x0;
58 mac_dest[4] = 0x0;
59 mac_dest[5] = id[1];
61 memcpy (&packet->mac_source, netif->dev->dev_addr, 6);
62 memcpy (&packet->mac_dest, mac_dest, 6);
63 packet->type = NET_PACKET_TYPE_IPV6;
65 /* ip layer */
66 proto_ipv6_t *ip = (proto_ipv6_t *) kmalloc (sizeof (proto_ipv6_t));
68 if (!ip)
69 return 0;
71 /* there are some fixed values - yeah it is horrible */
72 ip->ver = 0x60;
73 ip->tclass = 0x0;
74 ip->flabel = 0x0;
75 ip->pl_len = swap16 (32);
76 ip->nhead = NET_PROTO_IP_TYPE_ICMP6;
77 ip->hop = 0xff;
79 memcpy (ip->ip_source, (void *) netif->ipv6, sizeof (net_ipv6));
81 // if (dest[0] == swap16 (0xff02))
83 NET_IPV6_TO_ADDR (ip->ip_dest, 0xff02, 0x0, 0x0, 0x0, 0x0, 0x0001, 0xff00, swap16 (dest[7]));
84 //memcpy (ip->ip_dest, (void *) dest, sizeof (net_ipv6));
86 /* icmp layer */
87 proto_ndp_sol_t *ndp = (proto_ndp_sol_t *) kmalloc (sizeof (proto_ndp_sol_t));
89 if (!ndp)
90 return 0;
92 memset ((char *) ndp, 0, sizeof (proto_ndp_sol_t));
94 ndp->type = NET_NDP_TYPE_NBSOL;
95 ndp->code = 0;
96 memcpy (ndp->target, (void *) dest, sizeof (net_ipv6));
98 ndp->ll_type = 1;
99 ndp->ll_length = 1;
100 memcpy (&ndp->ll_mac, netif->dev->dev_addr, 6);
102 ndp->checksum = checksum16_ipv6 (ip->ip_source, ip->ip_dest, ndp, sizeof (proto_ndp_sol_t), NET_PROTO_IP_TYPE_ICMP6);
104 unsigned ret = net_proto_ipv6_send (netif, packet, ip, (char *) ndp, sizeof (proto_ndp_sol_t));
106 kfree (ndp);
107 kfree (ip);
108 kfree (packet);
110 return 1;
114 int ndp_send_nbreply (netif_t *i, mac_addr_t target_mac, net_ipv6 target_ipaddr)
116 /* packet header */
117 packet_t *packet = (packet_t *) kmalloc (sizeof (packet_t));
119 if (!packet)
120 return 0;
122 memcpy (&packet->mac_source, i->dev->dev_addr, 6);
123 memcpy (&packet->mac_dest, target_mac, 6);
124 packet->type = NET_PACKET_TYPE_IPV6;
126 /* ip layer */
127 proto_ipv6_t *ip = (proto_ipv6_t *) kmalloc (sizeof (proto_ipv6_t));
129 if (!ip)
130 return 0;
132 /* there are some fixed values - yeah it is horrible */
133 ip->ver = 0x60;
134 ip->tclass = 0x0;
135 ip->flabel = 0x0;
136 ip->pl_len = swap16 (32);
137 ip->nhead = NET_PROTO_IP_TYPE_ICMP6;
138 ip->hop = 0xff;
140 memcpy (ip->ip_source, (void *) i->ipv6, sizeof (net_ipv6));
142 // if (dest[0] == swap16 (0xff02))
144 memcpy (ip->ip_dest, (void *) target_ipaddr, sizeof (net_ipv6));
146 /* icmp layer */
147 proto_ndp_adv_t *ndp = (proto_ndp_adv_t *) kmalloc (sizeof (proto_ndp_adv_t));
149 if (!ndp)
150 return 0;
152 memset ((char *) ndp, 0, sizeof (proto_ndp_sol_t));
154 ndp->type = NET_NDP_TYPE_NBADVERT;
155 ndp->code = 0;
156 ndp->flags = swap32 (0x60000000);
157 memcpy (ndp->target, (void *) i->ipv6, sizeof (net_ipv6));
159 ndp->ll_type = 2;
160 ndp->ll_length = 1;
161 memcpy (&ndp->ll_mac, i->dev->dev_addr, 6);
163 ndp->checksum = checksum16_ipv6 (ip->ip_source, ip->ip_dest, ndp, sizeof (proto_ndp_adv_t), NET_PROTO_IP_TYPE_ICMP6);
165 unsigned ret = net_proto_ipv6_send (i, packet, ip, (char *) ndp, sizeof (proto_ndp_sol_t));
167 kfree (ndp);
168 kfree (ip);
169 kfree (packet);
171 return 1;
174 int ndp_send_rreply (netif_t *i, proto_icmp_ndp2_t *ndp, net_ipv6 source, net_ipv6 dest)
176 /*printf ("IP adresa je: ");
177 net_proto_ipv6_print (source);
178 printf ("\n");*/
180 net_ipv6 bcast_ip;
182 NET_IPV6_TO_ADDR (bcast_ip, 0xfe80, 0, 0, 0, 0, 0, 0, 0);
184 if (!net_proto_ipv6_cmp_prefix (source, bcast_ip, 64)) {
185 return 0;
188 /* local IPv6 address - we can change it to public IPv6 */
189 if (!net_proto_ipv6_network (i->ipv6)) {
190 if (ndp->prefix_len != 64)
191 return 0;
193 net_ipv6 ipv6;
196 eth3 Zapouzdření:Ethernet HWadr 00:E0:4D:7A:D3:48
197 inet6-adr: 2001:15c0:661d:0:2e0:4dff:fe7a:d348/64 Rozsah:Globál
198 inet6-adr: fe80::2e0:4dff:fe7a:d348/64 Rozsah:Linka
201 unsigned l = ndp->prefix_len/8;
203 memcpy (&ipv6, (void *) ndp->prefix, l);
205 //memcpy ((char *) &ipv6+ndp->prefix_len/8, ndp->prefix, ndp->prefix_len);
206 /*unsigned i;
207 for (i = l/8; i < 8; i ++) {
208 ipv6[i] =
210 ipv6[4] = 0x2 | i->dev->dev_addr[1] << 8;
211 ipv6[5] = 0xff << 8 | i->dev->dev_addr[2];
212 ipv6[6] = 0xfe | i->dev->dev_addr[3] << 8;
213 ipv6[7] = i->dev->dev_addr[4] | i->dev->dev_addr[5] << 8;
215 netif_ipv6_addr (i, ipv6, IF_CFG_TYPE_RADVERT);
217 //NET_IPV6_TO_ADDR (ipv6, 0xfc00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1);
220 netif_gwv6_addr (i, ndp->prefix);
221 memcpy (&ndp_macgw, &ndp->ll_mac, sizeof (mac_addr_t));
224 return 1;
225 #ifdef TEST
226 /* packet header */
227 packet_t *packet = (packet_t *) kmalloc (sizeof (packet_t));
229 if (!packet)
230 return 0;
232 memcpy (&packet->mac_source, i->dev->dev_addr, 6);
233 memcpy (&packet->mac_dest, target_mac, 6);
234 packet->type = NET_PACKET_TYPE_IPV6;
236 /* ip layer */
237 proto_ipv6_t *ip = (proto_ipv6_t *) kmalloc (sizeof (proto_ipv6_t));
239 if (!ip)
240 return 0;
242 /* there are some fixed values - yeah it is horrible */
243 ip->ver = 0x60;
244 ip->tclass = 0x0;
245 ip->flabel = 0x0;
246 ip->pl_len = swap16 (32);
247 ip->nhead = NET_PROTO_IP_TYPE_ICMP6;
248 ip->hop = 0xff;
250 memcpy (ip->ip_source, (void *) i->ipv6, sizeof (net_ipv6));
252 // if (dest[0] == swap16 (0xff02))
254 memcpy (ip->ip_dest, (void *) source, sizeof (net_ipv6));
256 /* icmp layer */
257 proto_ndp_adv_t *ndp = (proto_ndp_adv_t *) kmalloc (sizeof (proto_ndp_adv_t));
259 if (!ndp)
260 return 0;
262 memset ((char *) ndp, 0, sizeof (proto_ndp_sol_t));
264 ndp->type = NET_NDP_TYPE_RSOL;
265 ndp->code = 0;
266 ndp->flags = swap32 (0x60000000);
267 memcpy (ndp->target, (void *) i->ipv6, sizeof (net_ipv6));
269 ndp->ll_type = 2;
270 ndp->ll_length = 1;
271 memcpy (&ndp->ll_mac, i->dev->dev_addr, 6);
273 ndp->checksum = checksum16_ipv6 (ip->ip_source, ip->ip_dest, ndp, sizeof (proto_ndp_adv_t), NET_PROTO_IP_TYPE_ICMP6);
275 unsigned ret = net_proto_ipv6_send (i, packet, ip, (char *) ndp, sizeof (proto_ndp_sol_t));
277 kfree (ndp);
278 kfree (ip);
279 kfree (packet);
280 #endif
281 return 1;
284 /* NDP Cache */
285 unsigned ndp_cache_add (mac_addr_t mac, net_ipv6 ip)
287 ndp_cache_t *cache;
288 for (cache = ndp_cache_list.next; cache != &ndp_cache_list; cache = cache->next) {
289 if (net_proto_ipv6_cmp (cache->ip, ip)) {
290 //printf ("PRDPRD\n");
291 return 0;
295 //printf ("hmm: pridavam novou mac %x:%x:%x:%x:%x:%x a ip: ", (unsigned char) mac[0], (unsigned char) mac[1], (unsigned char) mac[2], (unsigned char) mac[3], (unsigned char) mac[4], (unsigned char) mac[5]);
296 //net_proto_ipv6_print (ip);
298 /* alloc and init context */
299 cache = (ndp_cache_t *) kmalloc (sizeof (ndp_cache_t));
301 if (!cache)
302 return 0;
304 memcpy (&cache->mac, mac, 6);
306 memcpy (cache->ip, (void *) ip, sizeof (net_ipv6));
308 /* add into list */
309 cache->next = &ndp_cache_list;
310 cache->prev = ndp_cache_list.prev;
311 cache->prev->next = cache;
312 cache->next->prev = cache;
314 return 1;
317 unsigned ndp_cache_get (net_ipv6 ip, mac_addr_t *mac)
319 ndp_cache_t *cache;
321 if (net_proto_ipv6_network (ip)) {
322 /*netif_t *eth = netif_findbyname ("eth0");
324 if (!eth)
325 return 0;
327 for (cache = ndp_cache_list.next; cache != &ndp_cache_list; cache = cache->next) {
328 if (net_proto_ipv6_cmp (cache->ip, eth->gwv6)) {
329 memcpy (mac, cache->mac, 6);
330 return 1;
334 memcpy (mac, &ndp_macgw, 6);
336 return 1;
337 } else {
338 for (cache = ndp_cache_list.next; cache != &ndp_cache_list; cache = cache->next) {
339 if (net_proto_ipv6_cmp (cache->ip, ip)) {
340 memcpy (mac, cache->mac, 6);
341 return 1;
346 return 0;
349 unsigned init_proto_ndp ()
351 ndp_cache_list.next = &ndp_cache_list;
352 ndp_cache_list.prev = &ndp_cache_list;
354 return 1;