2023-05-03 14:01:32 +03:00
/*
* eth_arp . cpp
*
2023-06-08 12:27:49 +03:00
* Created on : 13 <EFBFBD> <EFBFBD> <EFBFBD> . 2023 <EFBFBD> .
2023-05-03 14:01:32 +03:00
* Author : sychev
*/
2023-06-26 18:22:30 +03:00
# include "free_rtos/ethernet_ip/eth_arp.hpp"
# include "free_rtos/ethernet/eth_frame.h"
# include "free_rtos/ethernet_ip/eth_prots_id.h"
# include "free_rtos/ethernet_ip/eth_ip_types.h"
2023-05-03 14:01:32 +03:00
# include <cstring>
# define ARP_ETH_TYPE_BE 0x1000
void free_rtos : : clock_timeout ( ClockP_Object * obj , void * arg )
{
EthArp * p_arp = ( EthArp * ) arg ;
2023-06-08 12:27:49 +03:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ip
2023-05-03 14:01:32 +03:00
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
{
2023-06-08 12:27:49 +03:00
p_arp - > request ( item . first ) ; /// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> mac <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> ip
2023-05-03 14:01:32 +03:00
}
}
}
}
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_ ) ;
2023-06-08 12:27:49 +03:00
clock_ . init ( 100 , free_rtos : : clock_timeout , this ) ; /// 100<30> <30>
2023-05-03 14:01:32 +03:00
2023-06-08 12:27:49 +03:00
tmrGratuitous_ . start ( 1000 ) ; /// 1 <20> <> <EFBFBD> <20> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2023-05-03 14:01:32 +03:00
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 ) ) ;
2023-06-08 12:27:49 +03:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ARP
2023-05-03 14:01:32 +03:00
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 ) ) ;
2023-06-08 12:27:49 +03:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ip-<2D> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2023-05-03 14:01:32 +03:00
memcpy ( arp_hdr - > ar_tpa , & ip , ETH_IP_ADDR_LEN ) ;
request_pkt_ . length = sizeof ( TArpHeader ) ;
2023-06-08 12:27:49 +03:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2023-05-03 14:01:32 +03:00
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 ) {
2023-06-08 12:27:49 +03:00
return true ; /// <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2023-05-03 14:01:32 +03:00
}
else if ( p_ip_req_data - > tmr . is_started ( ) ) {
2023-06-08 12:27:49 +03:00
return true ; /// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD>
2023-05-03 14:01:32 +03:00
}
}
p_ip_req_data - > attemps = 0 ;
2023-06-08 12:27:49 +03:00
p_ip_req_data - > tmr . start ( 1000 ) ; /// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> 1 <20> <> <EFBFBD> <EFBFBD> <20> <20> <> <EFBFBD>
2023-05-03 14:01:32 +03:00
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 ) ;
/**
2023-06-08 12:27:49 +03:00
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ip = = 0 , <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> " Who has.... " .
* <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> .
2023-05-03 14:01:32 +03:00
*/
if ( ip_sender = = 0 ) {
return 0 ;
}
2023-06-08 12:27:49 +03:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> arp-<2D> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
2023-05-03 14:01:32 +03:00
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_ )
{
2023-06-08 12:27:49 +03:00
/// <20> <> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> - <20> <> <EFBFBD> <EFBFBD> <EFBFBD>
2023-05-03 14:01:32 +03:00
arp_hdr - > ar_op = arp_opr_be_ [ e_oprReply ] ;
2023-06-08 12:27:49 +03:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> mac <20> <> <EFBFBD> <EFBFBD> <EFBFBD>
2023-05-03 14:01:32 +03:00
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 ) ;
2023-06-08 12:27:49 +03:00
/// <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> ip <20> <> <EFBFBD> <EFBFBD> <EFBFBD>
2023-05-03 14:01:32 +03:00
memcpy ( arp_hdr - > ar_tpa , arp_hdr - > ar_spa , ETH_IP_ADDR_LEN ) ;
memcpy ( arp_hdr - > ar_spa , & self_ip_ , ETH_IP_ADDR_LEN ) ;
2023-06-08 12:27:49 +03:00
/// <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>
2023-05-03 14:01:32 +03:00
return len ;
}
}
return 0 ;
}
2023-06-08 12:27:49 +03:00
2023-10-26 10:21:41 +03:00
uint16_t free_rtos : : EthArp : : Sender ( HandlerArgs & handlerArgs , size_t scatter_segment )
2023-06-08 12:27:49 +03:00
{
2023-06-08 14:46:25 +03:00
return 0 ;
2023-06-08 12:27:49 +03:00
}