7 #include "LibEndian.hpp"
10 NetArp::SLOT NetArp::sSlots[NET_CFG_MAX_ARP_ENTRIES];
12 void NetArp::processFrame(NetDefs::FRAME& frame, NetDefs::ARP_HEADER& header) {
15 switch (header.operation) {
16 case NetDefs::ARP_OPERATION_REQ:
17 if (header.dstIpAddr == Net::sConfig.ipAddr) {
18 send(frame, header.srcMacAddr, header.srcIpAddr, NetDefs::ARP_OPERATION_RESP);
21 Net::freeFrame(frame);
24 case NetDefs::ARP_OPERATION_RESP: {
25 SLOT* slot = getWaitingSlot(header.srcIpAddr);
27 slot->macAddr = header.srcMacAddr;
28 slot->status = SLOT_RESOLVED;
31 Net::freeFrame(frame);
35 Net::freeFrame(frame);
41 bool NetArp::resolve(NetDefs::IP_ADDR ipAddr, NetDefs::MAC_ADDR& macAddr) {
44 if (ipAddr == NetDefs::IP_BROADCAST) {
45 macAddr = NetDefs::MAC_BROADCAST;
49 if ((Net::getConfig().ipAddr.val ^ ipAddr.val) & Net::getConfig().mask.val) {
50 ipAddr = Net::getConfig().gatewayIpAddr;
53 if (checkCache(ipAddr, macAddr)) {
57 SLOT* slot = getFreeSlot();
63 NetDefs::FRAME* frame = Net::allocFrame(
sizeof(NetDefs::MAC_HEADER) +
sizeof(NetDefs::ARP_HEADER));
65 slot->status = SLOT_EMPTY;
69 slot->ipAddr = ipAddr;
70 slot->timer = TIMEOUT_SLOT_RESOLVING;
71 slot->status = SLOT_RESOLVING;
75 send(*frame, NetDefs::MAC_BROADCAST, ipAddr, NetDefs::ARP_OPERATION_REQ);
78 slot->task->suspend();
79 if (slot->status != SLOT_RESOLVING) {
80 if (slot->status == SLOT_RESOLVED) {
81 macAddr = slot->macAddr;
82 slot->timer = TIMEOUT_SLOT_VALID;
83 slot->status = SLOT_VALID;
90 slot->status = SLOT_EMPTY;
95 NetArp::SLOT* NetArp::getFreeSlot() {
96 uint16_t smalestTimer = 0xFFFF;
99 for (
int i = 0; i < NET_CFG_MAX_ARP_ENTRIES; i++) {
101 if (sSlots[i].status == SLOT_EMPTY) {
102 sSlots[i].status = SLOT_RESERVED;
106 if (sSlots[i].status == SLOT_VALID) {
107 if (sSlots[i].timer < smalestTimer) {
113 sSlots[oldest].status = SLOT_RESERVED;
115 return &sSlots[oldest];
121 NetArp::SLOT* NetArp::getWaitingSlot(
const NetDefs::IP_ADDR ipAddr) {
122 for (
int i = 0; i < NET_CFG_MAX_ARP_ENTRIES; i++) {
123 if ((sSlots[i].status == SLOT_RESOLVING) && (sSlots[i].ipAddr == ipAddr)) {
130 bool NetArp::checkCache(
const NetDefs::IP_ADDR& ipAddr, NetDefs::MAC_ADDR& macAddr) {
131 for (
int i = 0; i < NET_CFG_MAX_ARP_ENTRIES; i++) {
133 if ((sSlots[i].status == SLOT_VALID) && (sSlots[i].ipAddr == ipAddr)) {
134 macAddr = sSlots[i].macAddr;
144 void NetArp::tick() {
145 for (
int i = 0; i < NET_CFG_MAX_ARP_ENTRIES; i++) {
146 if (--sSlots[i].timer == 0) {
148 if ((sSlots[i].status == SLOT_VALID)) {
149 sSlots[i].status = SLOT_EMPTY;
153 if ((sSlots[i].status == SLOT_RESOLVING)) {
154 sSlots[i].status = SLOT_TIMEOUT;
155 sSlots[i].task->resume();
161 void NetArp::send(NetDefs::FRAME& frame,
const NetDefs::MAC_ADDR& macDst,
const NetDefs::IP_ADDR& ipDst,
const NetDefs::ARP_OPERATION op) {
162 frame.types.arp.arpHeader.hardwareType = NetDefs::ARP_HW_TYPE_ETHERNET;
163 frame.types.arp.arpHeader.protocol = NetDefs::ARP_PROTOCOL_IP;
164 frame.types.arp.arpHeader.macAddrLen =
sizeof(NetDefs::MAC_ADDR);
165 frame.types.arp.arpHeader.protocolLen =
sizeof(NetDefs::IP_ADDR);
167 frame.types.arp.arpHeader.operation = op;
169 if (op == NetDefs::ARP_OPERATION_RESP) {
170 frame.types.arp.arpHeader.dstMacAddr = macDst;
173 frame.types.arp.arpHeader.dstMacAddr = NetDefs::MAC_BROADCAST;
176 frame.types.arp.arpHeader.srcIpAddr = Net::sConfig.ipAddr;
177 frame.types.arp.arpHeader.srcMacAddr = Net::sMacAddr;
178 frame.types.arp.arpHeader.dstIpAddr = ipDst;
180 swapHeader(frame.types.arp.arpHeader);
182 Net::putHeader(frame, frame.types.arp.arpHeader.dstMacAddr, NetDefs::MAC_TYPE_ARP);
183 Net::flush(frame,
sizeof(NetDefs::MAC_HEADER) +
sizeof(NetDefs::ARP_HEADER),
true);
186 void NetArp::swapHeader(NetDefs::ARP_HEADER& header) {
187 header.hardwareType = (NetDefs::ARP_HW_TYPE) LibEndian::hwToBe((uint16_t) header.hardwareType);
188 header.protocol = (NetDefs::ARP_PROTOCOL) LibEndian::hwToBe((uint16_t) header.protocol);
189 header.operation = (NetDefs::ARP_OPERATION) LibEndian::hwToBe((uint16_t) header.operation);