friendev EtherDune TCP/IP library
/home/jander/temp/etherdune/ARP.cpp
Go to the documentation of this file.
1 // EtherDune ARP Service
2 // Author: Javier Peletier <jm@friendev.com>
3 // Summary: Implements the ARP protocol as an EtherDune service
4 //
5 // Copyright (c) 2015 All Rights Reserved, http://friendev.com
6 //
7 // This source is subject to the GPLv2 license.
8 // Please see the License.txt file for more information.
9 // All other rights reserved.
10 //
11 // THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
12 // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
13 // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
14 // PARTICULAR PURPOSE.
15 
16 #include "ARP.h"
17 
18 #define AC_LOGLEVEL 2
19 #include <ACLog.h>
20 ACROSS_MODULE("ARP");
21 
22 static uint16_t minuteTimer = 60 * 1000 / NETWORK_TIMER_RESOLUTION;
23 
24 ARPEntry ARPService::arpTable[ARP_TABLE_LENGTH];
25 
26 
27 
29 {
30  memset(arpTable, -2, ARP_TABLE_LENGTH * sizeof(ARPEntry));
31 }
32 
33 bool ARPService::onPacketReceived()
34 {
35 
37  return false;
38 
39  ACTRACE("processHeader");
40 
41  switch (packet.arp.OPER.l)
42  {
43  case ARP_OPCODE_REPLY_L:
44  {
45 
46  ACTRACE("ARP Reply=%02x:%02x:%02x:%02x:%02x:%02x", packet.arp.senderMAC.b[0], packet.arp.senderMAC.b[1], packet.arp.senderMAC.b[2], packet.arp.senderMAC.b[3], packet.arp.senderMAC.b[4], packet.arp.senderMAC.b[5]);
47  processARPReply();
48 
49  return true;
50  }break;
51 
52  case ARP_OPCODE_REQ_L:
53  {
54  ACTRACE("ARP Request from=%02x:%02x:%02x:%02x:%02x:%02x", packet.arp.senderMAC.b[0], packet.arp.senderMAC.b[1], packet.arp.senderMAC.b[2], packet.arp.senderMAC.b[3], packet.arp.senderMAC.b[4], packet.arp.senderMAC.b[5]);
55 
56  if (packet.arp.targetIP.u == localIP.u)
57  makeARPReply();
58  return true;
59  }break;
60 
61  default:
62  {
63  return true;
64  }break;
65  }
66 }
67 
68 
69 void ARPService::tick()
70 {
71  minuteTimer--;
72 
73  if (minuteTimer == 0)
74  {
76 
77  for (ARPEntry* entry = arpTable + (ARP_TABLE_LENGTH - 1); entry >= arpTable; entry--)
78  {
79  if (entry->status_TTL > 0)
80  entry->status_TTL--;
81  }
82  }
83 }
84 
85 
96 {
97  for (ARPEntry* entry = arpTable + (ARP_TABLE_LENGTH - 1); entry >= arpTable; entry--)
98  {
99  if (ip.u == entry->ip.u && entry->status_TTL > 0)
100  {
101  entry->status_TTL = MAX_ARP_TTL;
102  return &entry->mac;
103  }
104  }
105 
106  makeWhoHasARPRequest(ip);
107 
108  return NULL;
109 
110 
111 }
112 
113 
114 
115 void ARPService::makeWhoHasARPRequest(IPAddress& ip)
116 {
117  memset(&packet.eth.dstMAC, 0xFF, sizeof(MACAddress));
120  packet.arp.HTYPE = 0x0001;
121  packet.arp.PTYPE = 0x0800;
122  packet.arp.HLEN = 0x06;
123  packet.arp.PLEN = 0x04;
124  packet.arp.OPER = 0x0001;
125  memset(&packet.arp.targetMAC, 0x00, sizeof(MACAddress));
126  packet.arp.targetIP = ip;
128 
129 
130 
131  packetSend(sizeof(EthernetHeader) + sizeof(ARPPacket), packet.raw);
132 
133 }
134 
135 void ARPService::makeARPReply()
136 {
142 
143  packetSend(sizeof(EthernetHeader) + sizeof(ARPPacket), packet.raw);
144 }
145 
146 void ARPService::processARPReply()
147 {
148  int16_t lowest = MAX_ARP_TTL;
149  ARPEntry * selectedEntry = NULL;
150  for (ARPEntry* entry = arpTable + (ARP_TABLE_LENGTH - 1); entry >= arpTable; entry--)
151  {
152  if (entry->ip.u == packet.arp.senderIP.u)
153  {
154  selectedEntry = entry;
155  break;
156  }
157 
158  if (entry->status_TTL <= lowest)
159  {
160  lowest = entry->status_TTL;
161  selectedEntry = entry;
162  }
163  }
164 
165  ACBREAK(selectedEntry!=NULL,"selectedEntry is NULL");
166 
167  selectedEntry->status_TTL = MAX_ARP_TTL;
168  selectedEntry->ip = packet.arp.senderIP;
169  selectedEntry->mac = packet.arp.senderMAC;
170 
171 }
172 
static const int16_t MAX_ARP_TTL
Time the ARP entry is considered fresh, in minutes.
Definition: config.h:178
Stores a MAC address in memory.
Definition: inet.h:252
nint16_t etherType
Protocol type, e.g.
Definition: inet.h:461
uint8_t HLEN
Hardware address length.
Definition: inet.h:284
MACAddress * whoHas(IPAddress &ip)
Attempts to return the MAC address associated with the provided IP address.
Definition: ARP.cpp:95
uint32_t u
access the IP as a uint32_t for convenience
Definition: inet.h:184
uint8_t raw[566]
Definition: inet.h:537
static EthBuffer packet
in-memory packet buffer currently being processed.
uint8_t PLEN
Protocol address length.
Definition: inet.h:285
static const uint8_t ARP_OPCODE_REPLY_L
ARP Opcode for reply.
Definition: inet.h:580
static const uint8_t ARP_OPCODE_REQ_L
ARP Opcode for request.
Definition: inet.h:581
IPAddress targetIP
Target protocol address.
Definition: inet.h:290
Represents the header of an Ethernet frame.
Definition: inet.h:457
MACAddress srcMAC
Source MAC address.
Definition: inet.h:460
Entry in the ARP table.
Definition: inet.h:542
MACAddress mac
MAC address.
Definition: inet.h:545
represents an IP address in memory
Definition: inet.h:181
ACROSS_MODULE("ARP")
MACAddress dstMAC
Destination MAC address.
Definition: inet.h:459
static void packetSend(uint16_t len)
Definition: ENC28J60.cpp:256
nint16_t OPER
Operation.
Definition: inet.h:286
uint8_t b[6]
byte-wise access to the MAC address
Definition: inet.h:254
static const uint8_t ARP_TABLE_LENGTH
Maximum number of entries in the ARP table.
Definition: config.h:177
MACAddress senderMAC
Sender hardware address.
Definition: inet.h:287
ARPService()
Definition: ARP.cpp:28
static const uint16_t ETHTYPE_ARP
Ethernet header protocol type for ARP.
Definition: inet.h:577
static MACAddress localMAC
Ethernet MAC address.
MACAddress targetMAC
Target hardware address.
Definition: inet.h:289
IPAddress ip
IP address.
Definition: inet.h:544
uint8_t l
least significant byte
Definition: inet.h:65
ARP packet layout.
Definition: inet.h:278
static IPAddress localIP
IP address of this application.
static uint16_t minuteTimer
Definition: ARP.cpp:22
nint16_t HTYPE
Hardware type.
Definition: inet.h:282
static const uint16_t NETWORK_TIMER_RESOLUTION
Resolution of the NetworkService timer.
Definition: config.h:30
IPAddress senderIP
Sender protocol address.
Definition: inet.h:288
ARPPacket arp
Definition: inet.h:503
EthernetHeader eth
Definition: inet.h:500
nint16_t PTYPE
Protocol type.
Definition: inet.h:283
int8_t status_TTL
TTL in minutes to consider the entry valid.
Definition: inet.h:546