source: mainline/uspace/srv/net/inetsrv/ndp.c@ 1f97352

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1f97352 was 08ed137, checked in by Martin Decky <martin@…>, 12 years ago

basic NDP implementation

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/*
2 * Copyright (c) 2013 Antonin Steinhauser
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup ethip
30 * @{
31 */
32/**
33 * @file
34 * @brief
35 */
36
37#include <errno.h>
38#include <mem.h>
39#include <malloc.h>
40#include <net/socket_codes.h>
41#include "ntrans.h"
42#include "addrobj.h"
43#include "pdu.h"
44#include "inet_link.h"
45#include "ndp.h"
46
47/** Time to wait for NDP reply in microseconds */
48#define NDP_REQUEST_TIMEOUT (3 * 1000 * 1000)
49
50static addr48_t solicited_node_mac =
51 {0x33, 0x33, 0xff, 0, 0, 0};
52
53static addr128_t solicited_node_ip =
54 {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, 0, 0, 0};
55
56static void ndp_solicited_node_mac(addr128_t ip_addr, addr48_t mac_addr)
57{
58 memcpy(mac_addr, solicited_node_mac, 3);
59 memcpy(mac_addr + 3, ip_addr + 13, 3);
60}
61
62static void ndp_solicited_node_ip(addr128_t ip_addr,
63 addr128_t ip_solicited)
64{
65 memcpy(ip_solicited, solicited_node_ip, 13);
66 memcpy(ip_solicited + 13, ip_addr + 13, 3);
67}
68
69static int ndp_send_packet(inet_link_t *link, ndp_packet_t *packet)
70{
71 inet_dgram_t dgram;
72 ndp_pdu_encode(packet, &dgram);
73
74 inet_link_send_dgram6(link, packet->target_hw_addr, &dgram,
75 IP_PROTO_ICMPV6, INET6_HOP_LIMIT_MAX, 0);
76
77 free(dgram.data);
78
79 return EOK;
80}
81
82static int ndp_router_advertisement(inet_dgram_t *dgram, inet_addr_t *router)
83{
84 // FIXME TODO
85 return ENOTSUP;
86}
87
88int ndp_received(inet_dgram_t *dgram)
89{
90 ndp_packet_t packet;
91 int rc = ndp_pdu_decode(dgram, &packet);
92 if (rc != EOK)
93 return rc;
94
95 inet_addr_t sender;
96 inet_addr_set6(packet.sender_proto_addr, &sender);
97
98 inet_addr_t target;
99 inet_addr_set6(packet.target_proto_addr, &target);
100
101 inet_addrobj_t *laddr;
102
103 switch (packet.opcode) {
104 case ICMPV6_NEIGHBOUR_SOLICITATION:
105 laddr = inet_addrobj_find(&target, iaf_addr);
106 if (laddr != NULL) {
107 rc = ntrans_add(packet.sender_proto_addr,
108 packet.sender_hw_addr);
109 if (rc != EOK)
110 return rc;
111
112 ndp_packet_t reply;
113
114 reply.opcode = ICMPV6_NEIGHBOUR_ADVERTISEMENT;
115 addr48(laddr->ilink->mac, reply.sender_hw_addr);
116 addr128(packet.target_proto_addr, reply.sender_proto_addr);
117 addr48(packet.sender_hw_addr, reply.target_hw_addr);
118 addr128(packet.sender_proto_addr, reply.target_proto_addr);
119
120 ndp_send_packet(laddr->ilink, &reply);
121 }
122
123 break;
124 case ICMPV6_NEIGHBOUR_ADVERTISEMENT:
125 laddr = inet_addrobj_find(&dgram->dest, iaf_addr);
126 if (laddr != NULL)
127 return ntrans_add(packet.sender_proto_addr,
128 packet.sender_hw_addr);
129
130 break;
131 case ICMPV6_ROUTER_ADVERTISEMENT:
132 return ndp_router_advertisement(dgram, &sender);
133 default:
134 return ENOTSUP;
135 }
136
137 return EOK;
138}
139
140int ndp_translate(addr128_t src_addr, addr128_t ip_addr, addr48_t mac_addr,
141 inet_link_t *ilink)
142{
143 if (!ilink->mac_valid) {
144 /* The link does not support NDP */
145 memset(mac_addr, 0, 6);
146 return EOK;
147 }
148
149 int rc = ntrans_lookup(ip_addr, mac_addr);
150 if (rc == EOK)
151 return EOK;
152
153 ndp_packet_t packet;
154
155 packet.opcode = ICMPV6_NEIGHBOUR_SOLICITATION;
156 addr48(ilink->mac, packet.sender_hw_addr);
157 addr128(src_addr, packet.sender_proto_addr);
158 addr128(ip_addr, packet.solicited_ip);
159 ndp_solicited_node_mac(ip_addr, packet.target_hw_addr);
160 ndp_solicited_node_ip(ip_addr, packet.target_proto_addr);
161
162 rc = ndp_send_packet(ilink, &packet);
163 if (rc != EOK)
164 return rc;
165
166 (void) ntrans_wait_timeout(NDP_REQUEST_TIMEOUT);
167
168 return ntrans_lookup(ip_addr, mac_addr);
169}
Note: See TracBrowser for help on using the repository browser.