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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers arp.c Source File

arp.c

00001 
00002 #include <stdint.h>
00003 #include <stdbool.h>
00004 
00005 #include "log.h"
00006 #include "action.h"
00007 #include "net.h"
00008 #include "eth.h"
00009 #include "mac.h"
00010 #include "dhcp.h"
00011 #include "ar4.h"
00012 #include "nr.h"
00013 #include "ip4addr.h"
00014 #include "arphdr.h"
00015 
00016 #define REQUEST   1
00017 #define REPLY     2
00018 
00019 bool ArpTrace = false;
00020 
00021 uint32_t ArpAddressToResolve;
00022 bool     ArpResolveRequestFlag = false;
00023 
00024 static void logHeader(char* pPacket)
00025 {    
00026     if (NetTraceVerbose)
00027     {
00028         LogTime("ARP header\r\n");
00029         if (ArpHdrGetHardwareType(pPacket) == ETHERNET) Log ("  hardwareType          = ETHERNET\r\n");
00030         else                                         LogF("  hardwareType          = %d\r\n", ArpHdrGetHardwareType(pPacket));
00031         Log ("  protocolType          = ");      EthProtocolLog(ArpHdrGetProtocolType  (pPacket));        Log("\r\n");
00032         LogF("  hardwareLength        = %d\r\n",                ArpHdrGetHardwareLength(pPacket));
00033         LogF("  protocolLength        = %d\r\n",                ArpHdrGetProtocolLength(pPacket));
00034         if      (ArpHdrGetOpCode(pPacket) == REQUEST)   Log ("  opCode                = REQUEST\r\n");
00035         else if (ArpHdrGetOpCode(pPacket) == REPLY  )   Log ("  opCode                = REPLY\r\n");
00036         else                                         LogF("  opCode                = %d\r\n", ArpHdrGetOpCode(pPacket));
00037         Log("  senderHardwareAddress = ");          MacLog(ArpHdrPtrSenderHardwareAddr(pPacket)); Log("\r\n");
00038         Log("  senderProtocolAddress = ");      Ip4AddrLog(ArpHdrGetSenderProtocolAddr(pPacket)); Log("\r\n");
00039         Log("  targetHardwareAddress = ");          MacLog(ArpHdrPtrTargetHardwareAddr(pPacket)); Log("\r\n");
00040         Log("  targetProtocolAddress = ");      Ip4AddrLog(ArpHdrGetTargetProtocolAddr(pPacket)); Log("\r\n");
00041     }
00042     else
00043     {
00044         Log("ARP header ");
00045             MacLog(ArpHdrPtrSenderHardwareAddr(pPacket)); Log("==");
00046         Ip4AddrLog(ArpHdrGetSenderProtocolAddr(pPacket)); Log(" >>> ");
00047             MacLog(ArpHdrPtrTargetHardwareAddr(pPacket)); Log("==");
00048         Ip4AddrLog(ArpHdrGetTargetProtocolAddr(pPacket)); Log("\r\n");
00049         
00050     }
00051 }
00052 static char* pHeaderTrace;
00053 static void (*pTraceBack)(void);
00054 static void trace()
00055 {
00056     pTraceBack();
00057     logHeader(pHeaderTrace);
00058 }
00059 
00060 int ArpHandleReceivedPacket(void (*traceback)(void), char* pPacketRx, int sizeRx, char* pPacketTx, int* pSizeTx)
00061 {
00062     pTraceBack = traceback;
00063     pHeaderTrace = pPacketRx;
00064     
00065     int16_t           hardwareType = ArpHdrGetHardwareType      (pPacketRx);
00066     int16_t           protocolType = ArpHdrGetProtocolType      (pPacketRx);
00067     int8_t          hardwareLength = ArpHdrGetHardwareLength    (pPacketRx);
00068     int8_t          protocolLength = ArpHdrGetProtocolLength    (pPacketRx);
00069     int16_t                 opCode = ArpHdrGetOpCode            (pPacketRx);
00070     uint32_t targetProtocolAddress = ArpHdrGetTargetProtocolAddr(pPacketRx);
00071 
00072     if (hardwareType          != ETHERNET     ) return DO_NOTHING; //This is not ethernet
00073     if (protocolType          != ETH_IPV4     ) return DO_NOTHING; //This is not IPv4
00074     if (hardwareLength        != 6            ) return DO_NOTHING; //This is not a MAC hardware address
00075     if (protocolLength        != 4            ) return DO_NOTHING; //This is not an IPv4 IP address
00076     if (targetProtocolAddress != DhcpLocalIp  ) return DO_NOTHING; //This packet was not addressed to us
00077     
00078     switch (opCode)
00079     {
00080         case REQUEST:
00081             if (ArpTrace)
00082             {
00083                 if (NetTraceNewLine) Log("\r\n");
00084                 LogTime("ARP received request\r\n");
00085                 if (NetTraceStack) traceback();
00086                 logHeader(pPacketRx);
00087             }   
00088                     ArpHdrSetHardwareType      (pPacketTx,  ETHERNET                              );
00089                     ArpHdrSetProtocolType      (pPacketTx,  ETH_IPV4                              );
00090                     ArpHdrSetHardwareLength    (pPacketTx,  6                                     );
00091                     ArpHdrSetProtocolLength    (pPacketTx,  4                                     );
00092                     ArpHdrSetOpCode            (pPacketTx,  REPLY                                 );
00093             MacCopy(ArpHdrPtrTargetHardwareAddr(pPacketTx), ArpHdrPtrSenderHardwareAddr(pPacketRx));
00094                     ArpHdrSetTargetProtocolAddr(pPacketTx,  ArpHdrGetSenderProtocolAddr(pPacketRx));
00095             MacCopy(ArpHdrPtrSenderHardwareAddr(pPacketTx), MacLocal                              );
00096                     ArpHdrSetSenderProtocolAddr(pPacketTx,  DhcpLocalIp                           );
00097             *pSizeTx = ARP_HEADER_LENGTH;
00098             if (ArpTrace) logHeader(pPacketTx);
00099             return ActionMakeFromDestAndTrace(UNICAST, ArpTrace && NetTraceStack);
00100             
00101         case REPLY:
00102             if (ArpTrace)
00103             {
00104                 if (NetTraceNewLine) Log("\r\n");
00105                 LogTime("ARP received reply\r\n");
00106                 if (NetTraceStack) traceback();
00107                 logHeader(pPacketRx);
00108             }   
00109             Ar4AddIpRecord(trace, ArpHdrPtrSenderHardwareAddr(pPacketRx), ArpHdrGetSenderProtocolAddr(pPacketRx));
00110             NrMakeRequestForNameFromAddress4(ArpHdrGetSenderProtocolAddr(pPacketRx));
00111             return DO_NOTHING;
00112             
00113         default:
00114             return DO_NOTHING;
00115     }
00116 }
00117 int ArpPollForPacketToSend(char* pPacketTx, int* pSizeTx)
00118 {
00119     if (!ArpResolveRequestFlag) return DO_NOTHING;
00120     ArpResolveRequestFlag = false;
00121 
00122              ArpHdrSetHardwareType      (pPacketTx,  ETHERNET           );
00123              ArpHdrSetProtocolType      (pPacketTx,  ETH_IPV4           );
00124              ArpHdrSetHardwareLength    (pPacketTx,  6                  );
00125              ArpHdrSetProtocolLength    (pPacketTx,  4                  );
00126              ArpHdrSetOpCode            (pPacketTx,  REQUEST            );
00127     MacClear(ArpHdrPtrTargetHardwareAddr(pPacketTx)                     );
00128              ArpHdrSetTargetProtocolAddr(pPacketTx,  ArpAddressToResolve);
00129     MacCopy (ArpHdrPtrSenderHardwareAddr(pPacketTx), MacLocal           );
00130              ArpHdrSetSenderProtocolAddr(pPacketTx,  DhcpLocalIp        );
00131     *pSizeTx = ARP_HEADER_LENGTH;
00132     
00133     if (ArpTrace)
00134     {
00135         if (NetTraceNewLine) Log("\r\n");
00136         LogTime("ARP send request\r\n");
00137         logHeader(pPacketTx);
00138     }
00139     return ActionMakeFromDestAndTrace(BROADCAST, ArpTrace && NetTraceStack);
00140 }