source: mainline/uspace/srv/net/inetsrv/ndp.c@ 1433ecda

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 1433ecda was 1433ecda, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Fix cstyle: make ccheck-fix and commit only files where all the changes are good.

  • Property mode set to 100644
File size: 5.0 KB
RevLine 
[08ed137]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>
[38d150e]39#include <stdlib.h>
[1d94e21]40#include <io/log.h>
[08ed137]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 addr128_t solicited_node_ip =
[1433ecda]51 { 0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, 0, 0, 0 };
[08ed137]52
[1d94e21]53/** Compute solicited node IPv6 multicast address from target IPv6 address
54 *
55 * @param ip_addr Target IPv6 address
56 * @param ip_solicited Solicited IPv6 address to be assigned
57 *
58 */
[08ed137]59static void ndp_solicited_node_ip(addr128_t ip_addr,
60 addr128_t ip_solicited)
61{
62 memcpy(ip_solicited, solicited_node_ip, 13);
63 memcpy(ip_solicited + 13, ip_addr + 13, 3);
64}
65
[b7fd2a0]66static errno_t ndp_send_packet(inet_link_t *link, ndp_packet_t *packet)
[08ed137]67{
68 inet_dgram_t dgram;
69 ndp_pdu_encode(packet, &dgram);
[a35b458]70
[08ed137]71 inet_link_send_dgram6(link, packet->target_hw_addr, &dgram,
72 IP_PROTO_ICMPV6, INET6_HOP_LIMIT_MAX, 0);
[a35b458]73
[08ed137]74 free(dgram.data);
[a35b458]75
[08ed137]76 return EOK;
77}
78
[b7fd2a0]79static errno_t ndp_router_advertisement(inet_dgram_t *dgram, inet_addr_t *router)
[08ed137]80{
81 // FIXME TODO
82 return ENOTSUP;
83}
84
[b7fd2a0]85errno_t ndp_received(inet_dgram_t *dgram)
[08ed137]86{
[1d94e21]87 log_msg(LOG_DEFAULT, LVL_DEBUG, "ndp_received()");
[a35b458]88
[08ed137]89 ndp_packet_t packet;
[b7fd2a0]90 errno_t rc = ndp_pdu_decode(dgram, &packet);
[08ed137]91 if (rc != EOK)
92 return rc;
[a35b458]93
[08ed137]94 inet_addr_t sender;
95 inet_addr_set6(packet.sender_proto_addr, &sender);
[a35b458]96
[08ed137]97 inet_addr_t target;
98 inet_addr_set6(packet.target_proto_addr, &target);
[a35b458]99
[08ed137]100 inet_addrobj_t *laddr;
[a35b458]101
[1d94e21]102 log_msg(LOG_DEFAULT, LVL_DEBUG, "NDP PDU decoded; opcode: %d",
103 packet.opcode);
[a35b458]104
[08ed137]105 switch (packet.opcode) {
106 case ICMPV6_NEIGHBOUR_SOLICITATION:
107 laddr = inet_addrobj_find(&target, iaf_addr);
108 if (laddr != NULL) {
109 rc = ntrans_add(packet.sender_proto_addr,
110 packet.sender_hw_addr);
111 if (rc != EOK)
112 return rc;
[a35b458]113
[08ed137]114 ndp_packet_t reply;
[a35b458]115
[08ed137]116 reply.opcode = ICMPV6_NEIGHBOUR_ADVERTISEMENT;
117 addr48(laddr->ilink->mac, reply.sender_hw_addr);
118 addr128(packet.target_proto_addr, reply.sender_proto_addr);
119 addr48(packet.sender_hw_addr, reply.target_hw_addr);
120 addr128(packet.sender_proto_addr, reply.target_proto_addr);
[a35b458]121
[08ed137]122 ndp_send_packet(laddr->ilink, &reply);
123 }
[a35b458]124
[08ed137]125 break;
126 case ICMPV6_NEIGHBOUR_ADVERTISEMENT:
127 laddr = inet_addrobj_find(&dgram->dest, iaf_addr);
128 if (laddr != NULL)
129 return ntrans_add(packet.sender_proto_addr,
130 packet.sender_hw_addr);
[a35b458]131
[08ed137]132 break;
133 case ICMPV6_ROUTER_ADVERTISEMENT:
134 return ndp_router_advertisement(dgram, &sender);
135 default:
136 return ENOTSUP;
137 }
[a35b458]138
[08ed137]139 return EOK;
140}
141
[1d94e21]142/** Translate IPv6 to MAC address
143 *
144 * @param src Source IPv6 address
145 * @param dest Destination IPv6 address
146 * @param mac Target MAC address to be assigned
147 * @param link Network interface
148 *
149 * @return EOK on success
150 * @return ENOENT when NDP translation failed
151 *
152 */
[b7fd2a0]153errno_t ndp_translate(addr128_t src_addr, addr128_t ip_addr, addr48_t mac_addr,
[08ed137]154 inet_link_t *ilink)
155{
156 if (!ilink->mac_valid) {
157 /* The link does not support NDP */
158 memset(mac_addr, 0, 6);
159 return EOK;
160 }
[a35b458]161
[b7fd2a0]162 errno_t rc = ntrans_lookup(ip_addr, mac_addr);
[08ed137]163 if (rc == EOK)
164 return EOK;
[a35b458]165
[08ed137]166 ndp_packet_t packet;
[a35b458]167
[08ed137]168 packet.opcode = ICMPV6_NEIGHBOUR_SOLICITATION;
169 addr48(ilink->mac, packet.sender_hw_addr);
170 addr128(src_addr, packet.sender_proto_addr);
171 addr128(ip_addr, packet.solicited_ip);
[83781a22]172 addr48_solicited_node(ip_addr, packet.target_hw_addr);
[08ed137]173 ndp_solicited_node_ip(ip_addr, packet.target_proto_addr);
[a35b458]174
[08ed137]175 rc = ndp_send_packet(ilink, &packet);
176 if (rc != EOK)
177 return rc;
[a35b458]178
[08ed137]179 (void) ntrans_wait_timeout(NDP_REQUEST_TIMEOUT);
[a35b458]180
[08ed137]181 return ntrans_lookup(ip_addr, mac_addr);
182}
Note: See TracBrowser for help on using the repository browser.