source: mainline/uspace/srv/net/ethip/arp.c

Last change on this file was b4edc96, checked in by Jiri Svoboda <jiri@…>, 4 years ago

Rename and move addr48_t to eth_addr_t

  • Property mode set to 100644
File size: 4.2 KB
RevLine 
[87e5658c]1/*
[f05edcb]2 * Copyright (c) 2021 Jiri Svoboda
[87e5658c]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 inet
30 * @{
31 */
32/**
33 * @file
34 * @brief
35 */
36
37#include <errno.h>
38#include <inet/iplink_srv.h>
[02a09ed]39#include <inet/addr.h>
[b4edc96]40#include <inet/eth_addr.h>
41#include <io/log.h>
[87e5658c]42#include <stdlib.h>
43#include "arp.h"
[f9d3dd4]44#include "atrans.h"
[87e5658c]45#include "ethip.h"
46#include "ethip_nic.h"
47#include "pdu.h"
48#include "std.h"
49
[3d016ac]50/** Time to wait for ARP reply in microseconds */
51#define ARP_REQUEST_TIMEOUT (3 * 1000 * 1000)
52
[b7fd2a0]53static errno_t arp_send_packet(ethip_nic_t *nic, arp_eth_packet_t *packet);
[87e5658c]54
55void arp_received(ethip_nic_t *nic, eth_frame_t *frame)
56{
[a1a101d]57 log_msg(LOG_DEFAULT, LVL_DEBUG, "arp_received()");
[a35b458]58
[02a09ed]59 arp_eth_packet_t packet;
[b7fd2a0]60 errno_t rc = arp_pdu_decode(frame->data, frame->size, &packet);
[87e5658c]61 if (rc != EOK)
62 return;
[a35b458]63
[a1a101d]64 log_msg(LOG_DEFAULT, LVL_DEBUG, "ARP PDU decoded, opcode=%d, tpa=%x",
[a2e3ee6]65 packet.opcode, packet.target_proto_addr);
[a35b458]66
[02a09ed]67 inet_addr_t addr;
68 inet_addr_set(packet.target_proto_addr, &addr);
[a35b458]69
[02a09ed]70 ethip_link_addr_t *laddr = ethip_nic_addr_find(nic, &addr);
71 if (laddr == NULL)
72 return;
[a35b458]73
[02a09ed]74 addr32_t laddr_v4;
[f023251]75 ip_ver_t laddr_ver = inet_addr_get(&laddr->addr, &laddr_v4, NULL);
76 if (laddr_ver != ip_v4)
[02a09ed]77 return;
[a35b458]78
[02a09ed]79 log_msg(LOG_DEFAULT, LVL_DEBUG, "Request/reply to my address");
[a35b458]80
[02a09ed]81 (void) atrans_add(packet.sender_proto_addr,
[f05edcb]82 &packet.sender_hw_addr);
[a35b458]83
[02a09ed]84 if (packet.opcode == aop_request) {
85 arp_eth_packet_t reply;
[a35b458]86
[02a09ed]87 reply.opcode = aop_reply;
[d5ed54b]88 reply.sender_hw_addr = nic->mac_addr;
[02a09ed]89 reply.sender_proto_addr = laddr_v4;
[d5ed54b]90 reply.target_hw_addr = packet.sender_hw_addr;
[02a09ed]91 reply.target_proto_addr = packet.sender_proto_addr;
[a35b458]92
[02a09ed]93 arp_send_packet(nic, &reply);
[87e5658c]94 }
95}
96
[b7fd2a0]97errno_t arp_translate(ethip_nic_t *nic, addr32_t src_addr, addr32_t ip_addr,
[b4edc96]98 eth_addr_t *mac_addr)
[3d016ac]99{
[695b6ff]100 /* Broadcast address */
101 if (ip_addr == addr32_broadcast_all_hosts) {
[b4edc96]102 *mac_addr = eth_addr_broadcast;
[695b6ff]103 return EOK;
104 }
105
[b7fd2a0]106 errno_t rc = atrans_lookup(ip_addr, mac_addr);
[3d016ac]107 if (rc == EOK)
108 return EOK;
[a35b458]109
[02a09ed]110 arp_eth_packet_t packet;
[a35b458]111
[3d016ac]112 packet.opcode = aop_request;
[d5ed54b]113 packet.sender_hw_addr = nic->mac_addr;
[a2e3ee6]114 packet.sender_proto_addr = src_addr;
[b4edc96]115 packet.target_hw_addr = eth_addr_broadcast;
[a2e3ee6]116 packet.target_proto_addr = ip_addr;
[a35b458]117
[3d016ac]118 rc = arp_send_packet(nic, &packet);
119 if (rc != EOK)
120 return rc;
[a35b458]121
[f303f2cf]122 return atrans_lookup_timeout(ip_addr, ARP_REQUEST_TIMEOUT, mac_addr);
[3d016ac]123}
124
[b7fd2a0]125static errno_t arp_send_packet(ethip_nic_t *nic, arp_eth_packet_t *packet)
[87e5658c]126{
[b7fd2a0]127 errno_t rc;
[87e5658c]128 void *pdata;
129 size_t psize;
130
131 eth_frame_t frame;
132 void *fdata;
133 size_t fsize;
134
[a1a101d]135 log_msg(LOG_DEFAULT, LVL_DEBUG, "arp_send_packet()");
[87e5658c]136
137 rc = arp_pdu_encode(packet, &pdata, &psize);
138 if (rc != EOK)
139 return rc;
140
[d5ed54b]141 frame.dest = packet->target_hw_addr;
142 frame.src = packet->sender_hw_addr;
[87e5658c]143 frame.etype_len = ETYPE_ARP;
144 frame.data = pdata;
145 frame.size = psize;
146
147 rc = eth_pdu_encode(&frame, &fdata, &fsize);
148 if (rc != EOK) {
149 free(pdata);
150 return rc;
151 }
152
153 rc = ethip_nic_send(nic, fdata, fsize);
154 free(fdata);
155 free(pdata);
156
157 return rc;
158
159}
160
161/** @}
162 */
Note: See TracBrowser for help on using the repository browser.