/* * eth_ip.cpp * * Created on: 13 ���. 2023 �. * Author: sychev */ #include "free_rtos/ethernet_ip/eth_ip.hpp" #include "free_rtos/ethernet_ip/eth_ip_types.h" #include "free_rtos/ethernet_ip/eth_checksum.h" #include "free_rtos/ethernet/eth_frame.h" #include "free_rtos/base/swap.h" #include #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; /// ����� mac-����� �� arp ������� if (!arp_.getMacAddr(dest_ip, mac_dst)) { /* * ���� ������ � arp-������� ���, �� ��������� ����������� arp-������ * (���� ������ ������ ������� 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); /// �������� ������ 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); }