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

Committer:
andrewboyson
Date:
Thu Dec 14 20:55:40 2017 +0000
Revision:
59:e0e556c8bd46
Parent:
58:d48c899e482f
Added buffer length to help avoid over runs

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 37:793b39683406 1 #include "mbed.h"
andrewboyson 37:793b39683406 2 #include "log.h"
andrewboyson 37:793b39683406 3 #include "action.h"
andrewboyson 37:793b39683406 4 #include "net.h"
andrewboyson 37:793b39683406 5 #include "eth.h"
andrewboyson 37:793b39683406 6 #include "mac.h"
andrewboyson 37:793b39683406 7 #include "dhcp.h"
andrewboyson 48:952dddb74b8b 8 #include "ar4.h"
andrewboyson 50:492f2d2954e4 9 #include "nr4.h"
andrewboyson 37:793b39683406 10 #include "io.h"
andrewboyson 49:1a6336f2b3f9 11 #include "ip4addr.h"
andrewboyson 10:f0854784e960 12
andrewboyson 10:f0854784e960 13 #define REQUEST 1
andrewboyson 10:f0854784e960 14 #define REPLY 2
andrewboyson 10:f0854784e960 15
andrewboyson 43:bc028d5a6424 16 bool ArpTrace = false;
andrewboyson 43:bc028d5a6424 17
andrewboyson 22:914b970356f0 18 uint32_t ArpAddressToResolve;
andrewboyson 22:914b970356f0 19 bool ArpResolveRequestFlag = false;
andrewboyson 22:914b970356f0 20
andrewboyson 10:f0854784e960 21 __packed struct header
andrewboyson 10:f0854784e960 22 {
andrewboyson 10:f0854784e960 23 int16_t hardwareType; //16.bit: (ar$hrd) Hardware address space (e.g., Ethernet, Packet Radio Net). Always 1.
andrewboyson 10:f0854784e960 24 int16_t protocolType; //16.bit: (ar$pro) Protocol address space. For Ethernet hardware, this is from the set of type fields ether_typ$<protocol>. As held in eth.h, eg IPv4 = 0x8000.
andrewboyson 10:f0854784e960 25 int8_t hardwareLength; // 8.bit: (ar$hln) byte length of each hardware address. Always 6 bytes.
andrewboyson 10:f0854784e960 26 int8_t protocolLength; // 8.bit: (ar$pln) byte length of each protocol address. Always 4 bytes.
andrewboyson 10:f0854784e960 27 int16_t opCode; //16.bit: (ar$op) opcode (ares_op$REQUEST = 1 | ares_op$REPLY = 2), high byte transmitted first.
andrewboyson 10:f0854784e960 28 char senderHardwareAddress[6]; //nbytes: (ar$sha) Hardware address of sender of this packet, n from the ar$hln field.
andrewboyson 10:f0854784e960 29 uint32_t senderProtocolAddress; //mbytes: (ar$spa) Protocol address of sender of this packet, m from the ar$pln field.
andrewboyson 10:f0854784e960 30 char targetHardwareAddress[6]; //nbytes: (ar$tha) Hardware address of target of this packet (if known).
andrewboyson 10:f0854784e960 31 uint32_t targetProtocolAddress; //mbytes: (ar$tpa) Protocol address of target.
andrewboyson 10:f0854784e960 32 };
andrewboyson 43:bc028d5a6424 33
andrewboyson 59:e0e556c8bd46 34 static void logHeader(struct header* pHeader)
andrewboyson 48:952dddb74b8b 35 {
andrewboyson 43:bc028d5a6424 36 if (NetTraceVerbose)
andrewboyson 43:bc028d5a6424 37 {
andrewboyson 43:bc028d5a6424 38 LogTime("ARP header\r\n");
andrewboyson 43:bc028d5a6424 39 if (NetToHost16(pHeader->hardwareType) == ETHERNET) Log (" hardwareType = ETHERNET\r\n");
andrewboyson 43:bc028d5a6424 40 else LogF(" hardwareType = %d\r\n", NetToHost16(pHeader->hardwareType));
andrewboyson 48:952dddb74b8b 41 Log (" protocolType = "); EthProtocolLog(pHeader->protocolType); Log("\r\n");
andrewboyson 48:952dddb74b8b 42 LogF(" hardwareLength = %d\r\n", pHeader->hardwareLength);
andrewboyson 48:952dddb74b8b 43 LogF(" protocolLength = %d\r\n", pHeader->protocolLength);
andrewboyson 48:952dddb74b8b 44 if (NetToHost16(pHeader->opCode) == REQUEST) Log (" opCode = REQUEST\r\n");
andrewboyson 48:952dddb74b8b 45 else if (NetToHost16(pHeader->opCode) == REPLY ) Log (" opCode = REPLY\r\n");
andrewboyson 48:952dddb74b8b 46 else LogF(" opCode = %d\r\n", NetToHost16(pHeader->opCode));
andrewboyson 48:952dddb74b8b 47 Log(" senderHardwareAddress = "); MacLog(pHeader->senderHardwareAddress); Log("\r\n");
andrewboyson 48:952dddb74b8b 48 Log(" senderProtocolAddress = "); Ip4AddressLog(pHeader->senderProtocolAddress); Log("\r\n");
andrewboyson 48:952dddb74b8b 49 Log(" targetHardwareAddress = "); MacLog(pHeader->targetHardwareAddress); Log("\r\n");
andrewboyson 48:952dddb74b8b 50 Log(" targetProtocolAddress = "); Ip4AddressLog(pHeader->targetProtocolAddress); Log("\r\n");
andrewboyson 43:bc028d5a6424 51 }
andrewboyson 43:bc028d5a6424 52 else
andrewboyson 43:bc028d5a6424 53 {
andrewboyson 43:bc028d5a6424 54 Log("ARP header ");
andrewboyson 47:73af5c0b0dc2 55 MacLog(pHeader->senderHardwareAddress); Log("==");
andrewboyson 47:73af5c0b0dc2 56 Ip4AddressLog(pHeader->senderProtocolAddress); Log(" >>> ");
andrewboyson 47:73af5c0b0dc2 57 MacLog(pHeader->targetHardwareAddress); Log("==");
andrewboyson 47:73af5c0b0dc2 58 Ip4AddressLog(pHeader->targetProtocolAddress); Log("\r\n");
andrewboyson 43:bc028d5a6424 59
andrewboyson 43:bc028d5a6424 60 }
andrewboyson 43:bc028d5a6424 61 }
andrewboyson 59:e0e556c8bd46 62 static struct header* pHeaderTrace;
andrewboyson 48:952dddb74b8b 63 static void (*pTraceBack)(void);
andrewboyson 48:952dddb74b8b 64 static void trace()
andrewboyson 48:952dddb74b8b 65 {
andrewboyson 48:952dddb74b8b 66 pTraceBack();
andrewboyson 59:e0e556c8bd46 67 logHeader(pHeaderTrace);
andrewboyson 48:952dddb74b8b 68 }
andrewboyson 43:bc028d5a6424 69
andrewboyson 59:e0e556c8bd46 70 int ArpHandleReceivedPacket(void (*traceback)(void), void* pPacketRx, int sizeRx, void* pPacketTx, int* pSizeTx)
andrewboyson 10:f0854784e960 71 {
andrewboyson 48:952dddb74b8b 72 pTraceBack = traceback;
andrewboyson 59:e0e556c8bd46 73 struct header* pHeaderRx = (header*)pPacketRx;
andrewboyson 59:e0e556c8bd46 74 struct header* pHeaderTx = (header*)pPacketTx;
andrewboyson 59:e0e556c8bd46 75 pHeaderTrace = pHeaderRx;
andrewboyson 59:e0e556c8bd46 76
andrewboyson 59:e0e556c8bd46 77 int16_t hardwareType = NetToHost16(pHeaderRx->hardwareType);
andrewboyson 59:e0e556c8bd46 78 int16_t protocolType = NetToHost16(pHeaderRx->protocolType);
andrewboyson 59:e0e556c8bd46 79 int8_t hardwareLength = pHeaderRx->hardwareLength;
andrewboyson 59:e0e556c8bd46 80 int8_t protocolLength = pHeaderRx->protocolLength;
andrewboyson 59:e0e556c8bd46 81 int16_t opCode = NetToHost16(pHeaderRx->opCode);
andrewboyson 59:e0e556c8bd46 82 uint32_t targetProtocolAddress = pHeaderRx->targetProtocolAddress;
andrewboyson 48:952dddb74b8b 83
andrewboyson 10:f0854784e960 84 if (hardwareType != ETHERNET ) return DO_NOTHING; //This is not ethernet
andrewboyson 10:f0854784e960 85 if (protocolType != IPV4 ) return DO_NOTHING; //This is not IPv4
andrewboyson 10:f0854784e960 86 if (hardwareLength != 6 ) return DO_NOTHING; //This is not a MAC hardware address
andrewboyson 10:f0854784e960 87 if (protocolLength != 4 ) return DO_NOTHING; //This is not an IPv4 IP address
andrewboyson 10:f0854784e960 88 if (targetProtocolAddress != DhcpLocalIp ) return DO_NOTHING; //This packet was not addressed to us
andrewboyson 10:f0854784e960 89
andrewboyson 22:914b970356f0 90 switch (opCode)
andrewboyson 22:914b970356f0 91 {
andrewboyson 22:914b970356f0 92 case REQUEST:
andrewboyson 43:bc028d5a6424 93 if (ArpTrace)
andrewboyson 43:bc028d5a6424 94 {
andrewboyson 43:bc028d5a6424 95 if (NetTraceNewLine) Log("\r\n");
andrewboyson 43:bc028d5a6424 96 LogTime("ARP received request\r\n");
andrewboyson 44:83ce5ace337b 97 if (NetTraceStack) traceback();
andrewboyson 59:e0e556c8bd46 98 logHeader(pHeaderRx);
andrewboyson 43:bc028d5a6424 99 }
andrewboyson 59:e0e556c8bd46 100 pHeaderTx->hardwareType = NetToHost16(ETHERNET);
andrewboyson 59:e0e556c8bd46 101 pHeaderTx->protocolType = NetToHost16(IPV4);
andrewboyson 59:e0e556c8bd46 102 pHeaderTx->hardwareLength = 6;
andrewboyson 59:e0e556c8bd46 103 pHeaderTx->protocolLength = 4;
andrewboyson 59:e0e556c8bd46 104 pHeaderTx->opCode = NetToHost16(REPLY);
andrewboyson 59:e0e556c8bd46 105 MacCopy(pHeaderTx->targetHardwareAddress, pHeaderRx->senderHardwareAddress);
andrewboyson 59:e0e556c8bd46 106 pHeaderTx->targetProtocolAddress = pHeaderRx->senderProtocolAddress;
andrewboyson 59:e0e556c8bd46 107 MacCopy(pHeaderTx->senderHardwareAddress, MacLocal);
andrewboyson 59:e0e556c8bd46 108 pHeaderTx->senderProtocolAddress = DhcpLocalIp;
andrewboyson 59:e0e556c8bd46 109 *pSizeTx = sizeof(header);
andrewboyson 59:e0e556c8bd46 110 if (ArpTrace) logHeader(pHeaderTx);
andrewboyson 43:bc028d5a6424 111 return ActionMakeFromDestAndTrace(UNICAST, ArpTrace && NetTraceStack);
andrewboyson 43:bc028d5a6424 112
andrewboyson 22:914b970356f0 113 case REPLY:
andrewboyson 43:bc028d5a6424 114 if (ArpTrace)
andrewboyson 43:bc028d5a6424 115 {
andrewboyson 43:bc028d5a6424 116 if (NetTraceNewLine) Log("\r\n");
andrewboyson 43:bc028d5a6424 117 LogTime("ARP received reply\r\n");
andrewboyson 44:83ce5ace337b 118 if (NetTraceStack) traceback();
andrewboyson 59:e0e556c8bd46 119 logHeader(pHeaderRx);
andrewboyson 43:bc028d5a6424 120 }
andrewboyson 59:e0e556c8bd46 121 Ar4AddIpRecord(trace, pHeaderRx->senderHardwareAddress, pHeaderRx->senderProtocolAddress);
andrewboyson 59:e0e556c8bd46 122 Nr4MakeRequestForNameFromIp(pHeaderRx->senderProtocolAddress);
andrewboyson 22:914b970356f0 123 return DO_NOTHING;
andrewboyson 43:bc028d5a6424 124
andrewboyson 22:914b970356f0 125 default:
andrewboyson 22:914b970356f0 126 return DO_NOTHING;
andrewboyson 22:914b970356f0 127 }
andrewboyson 22:914b970356f0 128 }
andrewboyson 59:e0e556c8bd46 129 int ArpPollForPacketToSend(void* pPacketTx, int* pSizeTx)
andrewboyson 22:914b970356f0 130 {
andrewboyson 22:914b970356f0 131 if (!ArpResolveRequestFlag) return DO_NOTHING;
andrewboyson 22:914b970356f0 132 ArpResolveRequestFlag = false;
andrewboyson 48:952dddb74b8b 133
andrewboyson 59:e0e556c8bd46 134 struct header* pHeaderTx = (header*)pPacketTx;
andrewboyson 48:952dddb74b8b 135
andrewboyson 59:e0e556c8bd46 136 pHeaderTx->hardwareType = NetToHost16(ETHERNET);
andrewboyson 59:e0e556c8bd46 137 pHeaderTx->protocolType = NetToHost16(IPV4);
andrewboyson 59:e0e556c8bd46 138 pHeaderTx->hardwareLength = 6;
andrewboyson 59:e0e556c8bd46 139 pHeaderTx->protocolLength = 4;
andrewboyson 59:e0e556c8bd46 140 pHeaderTx->opCode = NetToHost16(REQUEST);
andrewboyson 48:952dddb74b8b 141
andrewboyson 59:e0e556c8bd46 142 MacClear(pHeaderTx->targetHardwareAddress);
andrewboyson 59:e0e556c8bd46 143 pHeaderTx->targetProtocolAddress = ArpAddressToResolve;
andrewboyson 59:e0e556c8bd46 144 MacCopy (pHeaderTx->senderHardwareAddress, MacLocal);
andrewboyson 59:e0e556c8bd46 145 pHeaderTx->senderProtocolAddress = DhcpLocalIp;
andrewboyson 48:952dddb74b8b 146
andrewboyson 59:e0e556c8bd46 147 *pSizeTx = sizeof(header);
andrewboyson 10:f0854784e960 148
andrewboyson 43:bc028d5a6424 149 if (ArpTrace)
andrewboyson 43:bc028d5a6424 150 {
andrewboyson 43:bc028d5a6424 151 if (NetTraceNewLine) Log("\r\n");
andrewboyson 43:bc028d5a6424 152 LogTime("ARP send request\r\n");
andrewboyson 59:e0e556c8bd46 153 logHeader(pHeaderTx);
andrewboyson 43:bc028d5a6424 154 }
andrewboyson 43:bc028d5a6424 155 return ActionMakeFromDestAndTrace(BROADCAST, ArpTrace && NetTraceStack);
andrewboyson 35:93c39d260a83 156 }