sitara_depot/components/free_rtos/ethernet_ip/eth_arp.cpp

212 lines
5.6 KiB
C++
Raw Blame History

/*
* eth_arp.cpp
*
* Created on: 13 <20><><EFBFBD>. 2023 <20>.
* Author: sychev
*/
#include "ethernet_ip/eth_arp.hpp"
#include "ethernet/eth_frame.h"
#include "ethernet_ip/eth_prots_id.h"
#include "ethernet_ip/eth_ip_types.h"
#include <cstring>
#define ARP_ETH_TYPE_BE 0x1000
void free_rtos::clock_timeout(ClockP_Object * obj, void * arg)
{
EthArp * p_arp = ( EthArp *)arg;
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip
if (p_arp->tmrGratuitous_.tick(100))
{
if (p_arp->table_mac_.empty()) {
p_arp->request(p_arp->self_ip_);
}
}
for (auto& item : p_arp->table_ip_)
{
auto& ip_data = item.second;
if (ip_data.tmr.tick(100))
{
if (++ip_data.attemps >= p_arp->max_attemps_)
{
ip_data.tmr.stop();
ip_data.attemps = 0;
}
else
{
p_arp->request(item.first); /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mac <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> ip
}
}
}
}
free_rtos::EthArp::EthArp(EthStackIface& eth_stack) :
eth_stack_{eth_stack}
{
}
bool free_rtos::EthArp::init(TEthMacPorts eth_port_id, uint64_t self_mac, uint32_t self_ip)
{
self_mac_ = self_mac;
self_ip_ = self_ip;
eth_port_id_ = eth_port_id;
init_request_pkt(self_mac_, self_ip_);
clock_.init(100, free_rtos::clock_timeout, this); /// 100<30><30>
tmrGratuitous_.start(1000); /// 1 <20><><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
clock_.start();
return true;
}
void free_rtos::EthArp::init_request_pkt(uint64_t self_mac, uint32_t self_ip)
{
TArpHeader * arp_hdr = (TArpHeader *)(request_pkt_.data + sizeof(TEthFrameHeader));
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ARP
memcpy(arp_hdr->ar_sha, &self_mac_, ETH_FRAME_MAC_ADDR_LEN_BYTES);
memset(arp_hdr->ar_tha, 0, ETH_FRAME_MAC_ADDR_LEN_BYTES);
memcpy(arp_hdr->ar_spa, &self_ip_, ETH_IP_ADDR_LEN);
arp_hdr->ar_op = arp_opr_be_[e_oprRequest];
arp_hdr->ar_hrd = ARP_ETH_TYPE_BE;
arp_hdr->ar_pro = ETH_PROT_IP_BE;
arp_hdr->ar_hln = ETH_FRAME_MAC_ADDR_LEN_BYTES;
arp_hdr->ar_pln = ETH_IP_ADDR_LEN;
}
bool free_rtos::EthArp::request(uint32_t ip)
{
TArpHeader * arp_hdr = (TArpHeader *)(request_pkt_.data + sizeof(TEthFrameHeader));
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip-<2D><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
memcpy(arp_hdr->ar_tpa, &ip, ETH_IP_ADDR_LEN);
request_pkt_.length = sizeof(TArpHeader);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return eth_stack_.send_pkt(eth_port_id_, ETH_FRAME_MAC_ADDR_BROADCAST, ETH_PROT_ARP_BE, request_pkt_);
}
bool free_rtos::EthArp::try_request(uint32_t ip)
{
ArpIpReqData * p_ip_req_data = nullptr;
auto item = table_ip_.find(ip);
if (item == table_ip_.end())
{
p_ip_req_data = &table_ip_[ip]; ///
}
else
{
p_ip_req_data = &item->second;
if (p_ip_req_data->mac != 0) {
return true; /// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
else if (p_ip_req_data->tmr.is_started()) {
return true; /// <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD>
}
}
p_ip_req_data->attemps = 0;
p_ip_req_data->tmr.start(1000); /// <20><><EFBFBD><EFBFBD><EFBFBD> 1 <20><><EFBFBD><EFBFBD> <20> <20><><EFBFBD>
return request(ip);
}
void free_rtos::EthArp::add(uint64_t mac, uint32_t ip) {
table_mac_[mac] = ip;
auto& item = table_ip_[ip];
item.mac = mac;
item.attemps = 0;
item.tmr.stop();
}
bool free_rtos::EthArp::getIpAddr(uint64_t mac, uint32_t& ip) {
auto item = table_mac_.find(mac);
if (item == table_mac_.end()) {
return false;
}
ip = item->second;
return true;
}
bool free_rtos::EthArp::getMacAddr(uint32_t ip, uint64_t& mac) {
auto item = table_ip_.find(ip);
if (item == table_ip_.end()) {
try_request(ip);
return false;
}
mac = item->second.mac;
return true;
}
int32_t free_rtos::EthArp::Process(uint8_t * p_data, uint32_t len)
{
TArpHeader * arp_hdr = (TArpHeader *)(p_data);
uint16_t type = arp_hdr->ar_op;
uint64_t mac_sender = 0;
uint32_t ip_sender = 0;
memcpy(&mac_sender, arp_hdr->ar_sha, ETH_FRAME_MAC_ADDR_LEN_BYTES);
memcpy(&ip_sender, arp_hdr->ar_spa, ETH_IP_ADDR_LEN);
/**
* <20><><EFBFBD><EFBFBD> ip == 0, <20><> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> "Who has....".
* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD>.
*/
if (ip_sender == 0) {
return 0;
}
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> arp-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
add(mac_sender, ip_sender);
if ( type == arp_opr_be_[e_oprRequest])
{
uint32_t ip_target;
memcpy(&ip_target, arp_hdr->ar_tpa, ETH_IP_ADDR_LEN);
if (ip_target == self_ip_)
{
/// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD>
arp_hdr->ar_op = arp_opr_be_[e_oprReply];
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> mac <20><><EFBFBD><EFBFBD><EFBFBD>
memcpy(arp_hdr->ar_tha, arp_hdr->ar_sha, ETH_FRAME_MAC_ADDR_LEN_BYTES);
memcpy(arp_hdr->ar_sha, &self_mac_, ETH_FRAME_MAC_ADDR_LEN_BYTES);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ip <20><><EFBFBD><EFBFBD><EFBFBD>
memcpy(arp_hdr->ar_tpa, arp_hdr->ar_spa, ETH_IP_ADDR_LEN);
memcpy(arp_hdr->ar_spa, &self_ip_, ETH_IP_ADDR_LEN);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return len;
}
}
return 0;
}
uint32_t free_rtos::EthArp::Sender(uint8_t * p_data, size_t scatter_segment)
{
return 0;
}