sitara_depot/components/free_rtos/ethernet_ip/eth_ip.cpp

135 lines
3.4 KiB
C++
Raw Blame History

/*
* eth_ip.cpp
*
* Created on: 13 <20><><EFBFBD>. 2023 <20>.
* Author: sychev
*/
#include "ethernet_ip/eth_ip.hpp"
#include "ethernet_ip/eth_ip_types.h"
#include "ethernet_ip/eth_checksum.h"
#include "ethernet/eth_frame.h"
#include "base/swap.h"
#include <cstring>
#define IP_TIME_TO_LIVE 64
#define IP_VER 4
#define IP_HEADER_WORD_SIZE 5
static void ip_swap_ip ( uint8_t * const dest_ip, uint8_t * const source_ip )
{
uint8_t i = 0;
for (i = 0; i < ETH_IP_ADDR_LEN; i++)
{
uint8_t tmp = dest_ip[i];
dest_ip[i] = source_ip[i];
source_ip[i] = tmp;
}
}
free_rtos::EthIp::EthIp(EthStackIface& eth_stack, EthArpIface& arp) :
eth_stack_{eth_stack},
arp_{arp}
{
}
int32_t free_rtos::EthIp::Process(uint8_t * p_data, uint32_t len)
{
TIpHeader * ip_hdr = (TIpHeader *)p_data;
uint32_t ip_addr;
memcpy(&ip_addr, ip_hdr->ip_dst, ETH_IP_ADDR_LEN);
if (ip_addr != self_ip_) {
return 0;
}
int32_t reply = handlers_.Process(ip_hdr->ip_p, p_data + sizeof(TIpHeader), len - sizeof(TIpHeader));
if (reply > 0) {
uint16_t cksum;
uint16_t len;
/* Swap the IP destination address and the IP source address */
ip_swap_ip(ip_hdr->ip_dst, ip_hdr->ip_src);
reply += sizeof(TIpHeader);
ip_hdr->ip_len = BASE_SWAP16(reply);
ip_hdr->ip_id = BASE_SWAP16(ip_indet_);
//-------------------------------------------------------
ip_hdr->ip_sum = 0;
len = (ip_hdr->ip_hl_v & 0x0F) * 4;
cksum = eth_calcChksum(0,(uint8_t *)ip_hdr, len);
ip_hdr->ip_sum = BASE_SWAP16(cksum);
//-------------------------------------------------------
++ip_indet_;
}
return reply;
}
uint32_t free_rtos::EthIp::Sender(uint8_t * p_data, size_t scatter_segment)
{
return 0;
}
bool free_rtos::EthIp::send(TEthMacPorts port_id, uint32_t dest_ip, uint8_t prot_id, TEthPkt& pkt)
{
uint64_t mac_dst;
/// <20><><EFBFBD><EFBFBD><EFBFBD> mac-<2D><><EFBFBD><EFBFBD><EFBFBD> <20><> arp <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (!arp_.getMacAddr(dest_ip, mac_dst)) {
/*
* <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> arp-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>, <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> arp-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* (<28><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> getMacAddr)
*/
return false;
}
uint16_t cksum = 0;
uint16_t len = 0;
TIpHeader * ip_header = (TIpHeader *)(pkt.data + sizeof(TEthFrameHeader));
memcpy(ip_header->ip_src, &self_ip_, ETH_IP_ADDR_LEN);
memcpy(ip_header->ip_dst, &dest_ip, ETH_IP_ADDR_LEN);
ip_header->ip_hl_v = (IP_VER << 4) | IP_HEADER_WORD_SIZE;
ip_header->ip_tos = 0;
ip_header->ip_id = BASE_SWAP16(ip_indet_);
++ip_indet_;
ip_header->ip_off = 0;
ip_header->ip_ttl = IP_TIME_TO_LIVE;
ip_header->ip_p = prot_id;
len = (ip_header->ip_hl_v & 0x0F) * 4;
pkt.length += len;
ip_header->ip_len = BASE_SWAP16(pkt.length);
ip_header->ip_sum = 0;
cksum = eth_calcChksum(0,(uint8_t *)ip_header, len);
ip_header->ip_sum = BASE_SWAP16(cksum);
/// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return eth_stack_.send_pkt(port_id, mac_dst, ETH_PROT_IP_BE, pkt);
}
bool free_rtos::EthIp::Register(uint8_t prot_id, Handler * p_handler)
{
return handlers_.Register(prot_id, p_handler);
}