3 * - Address Resolution Protocol
9 #define ARP_CACHE_SIZE 64
12 extern tInterface *IPv4_GetInterface(tAdapter *Adapter, tIPv4 Address, int Broadcast);
13 extern tInterface *IPv6_GetInterface(tAdapter *Adapter, tIPv6 Address, int Broadcast);
17 int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address);
18 void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer);
31 * \fn int ARP_Initialise()
32 * \brief Initalise the ARP section
36 gaARP_Cache = malloc( ARP_CACHE_SIZE * sizeof(*gaARP_Cache) );
37 memset( gaARP_Cache, 0, ARP_CACHE_SIZE * sizeof(*gaARP_Cache) );
38 giARP_CacheSpace = ARP_CACHE_SIZE;
40 Link_RegisterType(0x0806, ARP_int_GetPacket);
45 * \fn int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address)
46 * \brief Request the network to resolve an IPv4 Address
47 * \return Boolean Success
49 int ARP_int_Resolve4(tInterface *Interface, tIPv4 Address)
51 struct sArpRequest4 req;
53 req.HWType = htons(0x100); // Ethernet
54 req.Type = htons(0x0800);
57 req.Request = htons(1);
58 req.SourceMac = Interface->Adapter->MacAddr;
59 req.SourceIP = Interface->IP4.Address;
60 req.DestMac = cMAC_BROADCAST;
63 Link_SendPacket(Interface->Adapter, 0x0806, req.DestMac, sizeof(struct sArpRequest4), &req);
69 * \fn void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer)
70 * \brief Called when an ARP packet is recieved
72 void ARP_int_GetPacket(tAdapter *Adapter, tMacAddr From, int Length, void *Buffer)
76 tArpRequest4 *req4 = Buffer;
77 tArpRequest6 *req6 = Buffer;
80 // Sanity Check Packet
81 if( Length < sizeof(tArpRequest4) ) {
82 Log("[ARP ] Recieved undersized packet");
85 if( ntohs(req4->Type) != 0x0800 ) {
86 Log("[ARP ] Recieved a packet with a bad type 0x%x", ntohs(req4->Type));
89 if( req4->HWSize != 6 ) {
90 Log("[ARP ] Recieved a packet with HWSize != 6 (%i)", req4->HWSize);
93 if( !MAC_EQU(req4->SourceMac, From) ) {
94 Log("[ARP ] ARP spoofing detected", req4->HWSize);
98 switch( req4->Request )
100 case 1: // You want my IP?
101 // Check what type of IP it is
102 switch( req4->SWSize )
105 iface = IPv4_GetInterface(Adapter, req4->DestIP, 0);
108 IP4_SET(req4->DestIP, req4->SourceIP);
109 req4->DestMac = req4->SourceMac;
110 req4->SourceIP = iface->IP4.Address;
111 req4->SourceMac = Adapter->MacAddr;
112 req4->Request = htons(2);
113 Link_SendPacket(Adapter, 0x0806, req4->DestMac, sizeof(tArpRequest4), req4);
117 if( Length < sizeof(tArpRequest6) ) {
118 Log("[ARP ] Recieved undersized packet (IPv6)");
121 iface = IPv6_GetInterface(Adapter, req6->DestIP, 0);
124 req6->DestIP = req6->SourceIP;
125 req6->DestMac = req6->SourceMac;
126 req6->SourceIP = iface->IP6.Address;
127 req6->SourceMac = Adapter->MacAddr;
128 req6->Request = htons(2);
129 Link_SendPacket(Adapter, 0x0806, req6->DestMac, sizeof(tArpRequest6), req6);
133 Log("[ARP ] Unknown Protocol Address size (%i)", req4->SWSize);
139 case 2: // Ooh! A response!
140 // Find an entry for the MAC address in the cache
141 for( i = giARP_CacheSpace; i--; )
143 if(gaARP_Cache[oldest].LastUpdate > gaARP_Cache[i].LastUpdate) {
146 if( MAC_EQU(gaARP_Cache[i].MAC, From) ) break;
147 if( gaARP_Cache[i].LastUpdate == 0 && free==-1 ) free = i;
156 // Check what type of IP it is
157 switch( req4->SWSize )
160 gaARP_Cache[i].IP4 = req4->SourceIP;
163 if( Length < sizeof(tArpRequest6) ) {
164 Log("[ARP ] Recieved undersized packet (IPv6)");
167 gaARP_Cache[i].IP6 = req6->SourceIP;
170 Log("[ARP ] Unknown Protocol Address size (%i)", req4->SWSize);
174 gaARP_Cache[i].LastUpdate = now();