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/>.
27 #include <net/packet.h>
32 #include <net/checksum.h>
34 ndp_cache_t ndp_cache_list
;
37 extern unsigned long timer_ticks
;
42 unsigned ndp_send_nbrequest (netif_t
*netif
, net_ipv6 dest
)
45 packet_t
*packet
= (packet_t
*) kmalloc (sizeof (packet_t
));
51 memcpy (&id
, (void *) &dest
[7], sizeof (unsigned short));
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
;
66 proto_ipv6_t
*ip
= (proto_ipv6_t
*) kmalloc (sizeof (proto_ipv6_t
));
71 /* there are some fixed values - yeah it is horrible */
75 ip
->pl_len
= swap16 (32);
76 ip
->nhead
= NET_PROTO_IP_TYPE_ICMP6
;
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));
87 proto_ndp_sol_t
*ndp
= (proto_ndp_sol_t
*) kmalloc (sizeof (proto_ndp_sol_t
));
92 memset ((char *) ndp
, 0, sizeof (proto_ndp_sol_t
));
94 ndp
->type
= NET_NDP_TYPE_NBSOL
;
96 memcpy (ndp
->target
, (void *) dest
, sizeof (net_ipv6
));
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
));
114 int ndp_send_nbreply (netif_t
*i
, mac_addr_t target_mac
, net_ipv6 target_ipaddr
)
117 packet_t
*packet
= (packet_t
*) kmalloc (sizeof (packet_t
));
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
;
127 proto_ipv6_t
*ip
= (proto_ipv6_t
*) kmalloc (sizeof (proto_ipv6_t
));
132 /* there are some fixed values - yeah it is horrible */
136 ip
->pl_len
= swap16 (32);
137 ip
->nhead
= NET_PROTO_IP_TYPE_ICMP6
;
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
));
147 proto_ndp_adv_t
*ndp
= (proto_ndp_adv_t
*) kmalloc (sizeof (proto_ndp_adv_t
));
152 memset ((char *) ndp
, 0, sizeof (proto_ndp_sol_t
));
154 ndp
->type
= NET_NDP_TYPE_NBADVERT
;
156 ndp
->flags
= swap32 (0x60000000);
157 memcpy (ndp
->target
, (void *) i
->ipv6
, sizeof (net_ipv6
));
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
));
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);
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)) {
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)
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);
207 for (i = l/8; i < 8; 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
));
227 packet_t
*packet
= (packet_t
*) kmalloc (sizeof (packet_t
));
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
;
237 proto_ipv6_t
*ip
= (proto_ipv6_t
*) kmalloc (sizeof (proto_ipv6_t
));
242 /* there are some fixed values - yeah it is horrible */
246 ip
->pl_len
= swap16 (32);
247 ip
->nhead
= NET_PROTO_IP_TYPE_ICMP6
;
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
));
257 proto_ndp_adv_t
*ndp
= (proto_ndp_adv_t
*) kmalloc (sizeof (proto_ndp_adv_t
));
262 memset ((char *) ndp
, 0, sizeof (proto_ndp_sol_t
));
264 ndp
->type
= NET_NDP_TYPE_RSOL
;
266 ndp
->flags
= swap32 (0x60000000);
267 memcpy (ndp
->target
, (void *) i
->ipv6
, sizeof (net_ipv6
));
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
));
285 unsigned ndp_cache_add (mac_addr_t mac
, net_ipv6 ip
)
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");
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
));
304 memcpy (&cache
->mac
, mac
, 6);
306 memcpy (cache
->ip
, (void *) ip
, sizeof (net_ipv6
));
309 cache
->next
= &ndp_cache_list
;
310 cache
->prev
= ndp_cache_list
.prev
;
311 cache
->prev
->next
= cache
;
312 cache
->next
->prev
= cache
;
317 unsigned ndp_cache_get (net_ipv6 ip
, mac_addr_t
*mac
)
321 if (net_proto_ipv6_network (ip
)) {
322 /*netif_t *eth = netif_findbyname ("eth0");
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);
334 memcpy (mac
, &ndp_macgw
, 6);
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);
349 unsigned init_proto_ndp ()
351 ndp_cache_list
.next
= &ndp_cache_list
;
352 ndp_cache_list
.prev
= &ndp_cache_list
;