source: mainline/uspace/srv/net/ethip/arp.c@ 071a2c60

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

Make sure we wait the specified time before giving up on ARP translation.

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