A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.
Dependents: oldheating gps motorhome heating
arp/arp.c
- Committer:
- andrewboyson
- Date:
- 2021-05-20
- Revision:
- 200:5acbc41bf469
- Parent:
- 187:122fc1996c86
File content as of revision 200:5acbc41bf469:
#include <stdint.h> #include <stdbool.h> #include "log.h" #include "action.h" #include "net.h" #include "eth.h" #include "mac.h" #include "dhcp.h" #include "ar4.h" #include "nr.h" #include "ip4addr.h" #include "arphdr.h" #define REQUEST 1 #define REPLY 2 bool ArpTrace = false; uint32_t ArpAddressToResolve; bool ArpResolveRequestFlag = false; static void logHeader(char* pPacket) { if (NetTraceVerbose) { LogTime("ARP header\r\n"); if (ArpHdrGetHardwareType(pPacket) == ETHERNET) Log (" hardwareType = ETHERNET\r\n"); else LogF(" hardwareType = %d\r\n", ArpHdrGetHardwareType(pPacket)); Log (" protocolType = "); EthProtocolLog(ArpHdrGetProtocolType (pPacket)); Log("\r\n"); LogF(" hardwareLength = %d\r\n", ArpHdrGetHardwareLength(pPacket)); LogF(" protocolLength = %d\r\n", ArpHdrGetProtocolLength(pPacket)); if (ArpHdrGetOpCode(pPacket) == REQUEST) Log (" opCode = REQUEST\r\n"); else if (ArpHdrGetOpCode(pPacket) == REPLY ) Log (" opCode = REPLY\r\n"); else LogF(" opCode = %d\r\n", ArpHdrGetOpCode(pPacket)); Log(" senderHardwareAddress = "); MacLog(ArpHdrPtrSenderHardwareAddr(pPacket)); Log("\r\n"); Log(" senderProtocolAddress = "); Ip4AddrLog(ArpHdrGetSenderProtocolAddr(pPacket)); Log("\r\n"); Log(" targetHardwareAddress = "); MacLog(ArpHdrPtrTargetHardwareAddr(pPacket)); Log("\r\n"); Log(" targetProtocolAddress = "); Ip4AddrLog(ArpHdrGetTargetProtocolAddr(pPacket)); Log("\r\n"); } else { Log("ARP header "); MacLog(ArpHdrPtrSenderHardwareAddr(pPacket)); Log("=="); Ip4AddrLog(ArpHdrGetSenderProtocolAddr(pPacket)); Log(" >>> "); MacLog(ArpHdrPtrTargetHardwareAddr(pPacket)); Log("=="); Ip4AddrLog(ArpHdrGetTargetProtocolAddr(pPacket)); Log("\r\n"); } } static char* pHeaderTrace; static void (*pTraceBack)(void); static void trace() { pTraceBack(); logHeader(pHeaderTrace); } int ArpHandleReceivedPacket(void (*traceback)(void), char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx) { pTraceBack = traceback; pHeaderTrace = pPacketRx; int16_t hardwareType = ArpHdrGetHardwareType (pPacketRx); int16_t protocolType = ArpHdrGetProtocolType (pPacketRx); int8_t hardwareLength = ArpHdrGetHardwareLength (pPacketRx); int8_t protocolLength = ArpHdrGetProtocolLength (pPacketRx); int16_t opCode = ArpHdrGetOpCode (pPacketRx); uint32_t targetProtocolAddress = ArpHdrGetTargetProtocolAddr(pPacketRx); if (hardwareType != ETHERNET ) return DO_NOTHING; //This is not ethernet if (protocolType != ETH_IPV4 ) return DO_NOTHING; //This is not IPv4 if (hardwareLength != 6 ) return DO_NOTHING; //This is not a MAC hardware address if (protocolLength != 4 ) return DO_NOTHING; //This is not an IPv4 IP address if (targetProtocolAddress != DhcpLocalIp ) return DO_NOTHING; //This packet was not addressed to us switch (opCode) { case REQUEST: if (ArpTrace) { if (NetTraceNewLine) Log("\r\n"); LogTime("ARP received request\r\n"); if (NetTraceStack) traceback(); logHeader(pPacketRx); } ArpHdrSetHardwareType (pPacketTx, ETHERNET ); ArpHdrSetProtocolType (pPacketTx, ETH_IPV4 ); ArpHdrSetHardwareLength (pPacketTx, 6 ); ArpHdrSetProtocolLength (pPacketTx, 4 ); ArpHdrSetOpCode (pPacketTx, REPLY ); MacCopy(ArpHdrPtrTargetHardwareAddr(pPacketTx), ArpHdrPtrSenderHardwareAddr(pPacketRx)); ArpHdrSetTargetProtocolAddr(pPacketTx, ArpHdrGetSenderProtocolAddr(pPacketRx)); MacCopy(ArpHdrPtrSenderHardwareAddr(pPacketTx), MacLocal ); ArpHdrSetSenderProtocolAddr(pPacketTx, DhcpLocalIp ); *pSizeTx = ARP_HEADER_LENGTH; if (ArpTrace) logHeader(pPacketTx); return ActionMakeFromDestAndTrace(UNICAST, ArpTrace && NetTraceStack); case REPLY: if (ArpTrace) { if (NetTraceNewLine) Log("\r\n"); LogTime("ARP received reply\r\n"); if (NetTraceStack) traceback(); logHeader(pPacketRx); } Ar4AddIpRecord(trace, ArpHdrPtrSenderHardwareAddr(pPacketRx), ArpHdrGetSenderProtocolAddr(pPacketRx)); NrMakeRequestForNameFromAddress4(ArpHdrGetSenderProtocolAddr(pPacketRx)); return DO_NOTHING; default: return DO_NOTHING; } } int ArpPollForPacketToSend(char* pPacketTx, int* pSizeTx) { if (!ArpResolveRequestFlag) return DO_NOTHING; ArpResolveRequestFlag = false; ArpHdrSetHardwareType (pPacketTx, ETHERNET ); ArpHdrSetProtocolType (pPacketTx, ETH_IPV4 ); ArpHdrSetHardwareLength (pPacketTx, 6 ); ArpHdrSetProtocolLength (pPacketTx, 4 ); ArpHdrSetOpCode (pPacketTx, REQUEST ); MacClear(ArpHdrPtrTargetHardwareAddr(pPacketTx) ); ArpHdrSetTargetProtocolAddr(pPacketTx, ArpAddressToResolve); MacCopy (ArpHdrPtrSenderHardwareAddr(pPacketTx), MacLocal ); ArpHdrSetSenderProtocolAddr(pPacketTx, DhcpLocalIp ); *pSizeTx = ARP_HEADER_LENGTH; if (ArpTrace) { if (NetTraceNewLine) Log("\r\n"); LogTime("ARP send request\r\n"); logHeader(pPacketTx); } return ActionMakeFromDestAndTrace(BROADCAST, ArpTrace && NetTraceStack); }