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 Log("[ARP ] Request ID %i", ntohs(req4->Request));
100 switch( ntohs(req4->Request) )
102 case 1: // You want my IP?
103 Log("[ARP ] ARP Request Address class %i", req4->SWSize);
104 // Check what type of IP it is
105 switch( req4->SWSize )
108 Log("[ARP ] From MAC %02x:%02x:%02x:%02x:%02x:%02x",
109 req4->SourceMac.B[0], req4->SourceMac.B[1],
110 req4->SourceMac.B[2], req4->SourceMac.B[3],
111 req4->SourceMac.B[4], req4->SourceMac.B[5]);
112 Log("[ARP ] to MAC %02x:%02x:%02x:%02x:%02x:%02x",
113 req4->DestMac.B[0], req4->DestMac.B[1],
114 req4->DestMac.B[2], req4->DestMac.B[3],
115 req4->DestMac.B[4], req4->DestMac.B[5]);
116 Log("[ARP ] ARP Request IPv4 Address %i.%i.%i.%i",
117 req4->DestIP.B[0], req4->DestIP.B[1], req4->DestIP.B[2],
119 Log("[ARP ] from %i.%i.%i.%i",
120 req4->SourceIP.B[0], req4->SourceIP.B[1],
121 req4->SourceIP.B[2], req4->SourceIP.B[3]);
122 iface = IPv4_GetInterface(Adapter, req4->DestIP, 0);
125 req4->DestIP = req4->SourceIP;
126 req4->DestMac = req4->SourceMac;
127 req4->SourceIP = iface->IP4.Address;
128 req4->SourceMac = Adapter->MacAddr;
129 req4->Request = htons(2);
130 Log("[ARP ] Hey, That's us!");
131 Log("[ARP ] Sending back %02x:%02x:%02x:%02x:%02x:%02x",
132 req4->SourceMac.B[0], req4->SourceMac.B[1],
133 req4->SourceMac.B[2], req4->SourceMac.B[3],
134 req4->SourceMac.B[4], req4->SourceMac.B[5]);
135 Link_SendPacket(Adapter, 0x0806, req4->DestMac, sizeof(tArpRequest4), req4);
139 if( Length < sizeof(tArpRequest6) ) {
140 Log("[ARP ] Recieved undersized packet (IPv6)");
143 iface = IPv6_GetInterface(Adapter, req6->DestIP, 0);
146 req6->DestIP = req6->SourceIP;
147 req6->DestMac = req6->SourceMac;
148 req6->SourceIP = iface->IP6.Address;
149 req6->SourceMac = Adapter->MacAddr;
150 req6->Request = htons(2);
151 Link_SendPacket(Adapter, 0x0806, req6->DestMac, sizeof(tArpRequest6), req6);
155 Log("[ARP ] Unknown Protocol Address size (%i)", req4->SWSize);
161 case 2: // Ooh! A response!
162 // Find an entry for the MAC address in the cache
163 for( i = giARP_CacheSpace; i--; )
165 if(gaARP_Cache[oldest].LastUpdate > gaARP_Cache[i].LastUpdate) {
168 if( MAC_EQU(gaARP_Cache[i].MAC, From) ) break;
169 if( gaARP_Cache[i].LastUpdate == 0 && free==-1 ) free = i;
178 // Check what type of IP it is
179 switch( req4->SWSize )
182 gaARP_Cache[i].IP4 = req4->SourceIP;
185 if( Length < sizeof(tArpRequest6) ) {
186 Log("[ARP ] Recieved undersized packet (IPv6)");
189 gaARP_Cache[i].IP6 = req6->SourceIP;
192 Log("[ARP ] Unknown Protocol Address size (%i)", req4->SWSize);
196 gaARP_Cache[i].LastUpdate = now();