BOOTLOADER
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
ethernetarp.c
Go to the documentation of this file.
1 /******************************************************
2 * Function: etherent arp protocol handler
3 *
4 * File: etherentarp.c
5 * Author: Book Chen
6 * Date: 2008.07.18
7 *******************************************************
8 */
9 #include "includes.h"
10 #if(DEBUG_ETHERNET_ARP==1)
11 #define DEBUG_ETHERNET_INFO 1
12 #define DEBUG_ETHERNET_ADDRESS_GET 1
13 #else
14 #define DEBUG_ETHERNET_INFO 0
15 #define DEBUG_ETHERNET_ADDRESS_GET 0
16 #endif
17 
18 #define EthernetArpIdleState 0
19 
23 
24 void F_EthernetArpInit(void){
25  memset(&ArpEntry,0,sizeof(ARP_ENTRY)); // clear memory of ArpEntry
26  memset(ArpCache,0,(sizeof(ARP_ENTRY))*ARP_CACHE_SIZE); // clear memory of ArpCache
27  ArpCtrl.CacheIndex=0;
28  ArpCtrl.InUse=FALSE;
29  ArpCtrl.Id=ID_ETHERNET_ARP;
31 }
33  if(ArpCtrl.InUse==TRUE) return TRUE;
34  else return FALSE;
35 }
37  if(ArpCtrl.InUse==FALSE){
38  ArpCtrl.InUse=TRUE;
39  ArpCtrl.UserId=UserId;
40  return TRUE;
41  }
42  else return FALSE;
43 }
45  if((ArpCtrl.InUse==TRUE)&&(ArpCtrl.UserId==UserId)){
46  ArpCtrl.InUse=FALSE;
47  return TRUE;
48  }
49  else return FALSE;
50 }
51 INT8U F_EthernetArpEntrySet(INT16U UserId,INT8U *pMacAddress,INT8U *pIpAddress){
52  if((ArpCtrl.InUse==TRUE)&&(ArpCtrl.UserId==UserId)){
53  memcpy(ArpEntry.MacAddress,pMacAddress,ETHERNET_MAC_LENGTH);
54  memcpy(ArpEntry.IpAddress,pIpAddress,ETHERNET_IP_LENGTH);
55  return TRUE;
56  }
57  else return FALSE;
58 }
59 INT8U F_EthernetArpCacheAdd(INT8U *pMacAddress,INT8U *pIpAddress){
60  INT32U i;
61 
62  for(i=0;i<ARP_CACHE_SIZE;i++){
63  if((pIpAddress[0]==ArpCache[i].IpAddress[0])&&
64  (pIpAddress[1]==ArpCache[i].IpAddress[1])&&
65  (pIpAddress[2]==ArpCache[i].IpAddress[2])&&
66  (pIpAddress[3]==ArpCache[i].IpAddress[3]))
67  break;
68  }
69  if(i==ARP_CACHE_SIZE){ // means this ip is a new one...add into arp cache
70  i=ArpCtrl.CacheIndex;
71  ArpCtrl.CacheIndex++;
72  if(ArpCtrl.CacheIndex>=ARP_CACHE_SIZE) ArpCtrl.CacheIndex=0;
73  }
74  memcpy(ArpCache[i].MacAddress,pMacAddress,ETHERNET_MAC_LENGTH);
75  memcpy(ArpCache[i].IpAddress,pIpAddress,ETHERNET_IP_LENGTH);
76  #if(DEBUG_ETHERNET_ADDRESS_GET==1)
77  printf("\n arp address add");
78  printf("\n ARP index %x ",i);
79  printf("\n MAC Addr %2x %2x %2x %2x %2x %2x",pMacAddress[0]
80  ,pMacAddress[1]
81  ,pMacAddress[2]
82  ,pMacAddress[3]
83  ,pMacAddress[4]
84  ,pMacAddress[5]);
85  printf("\n IP Addr %2x %2x %2x %2x ",pIpAddress[0]
86  ,pIpAddress[1]
87  ,pIpAddress[2]
88  ,pIpAddress[3]);
89  #endif
90  return TRUE;
91 }
92 INT8U F_EthernetArpAddressGet(INT8U *pIpAddress,INT8U *pMacAddress){
93  INT32U i;
94 
95  for(i=0;i<ARP_CACHE_SIZE;i++){
96  if((pIpAddress[0]==ArpCache[i].IpAddress[0])&&
97  (pIpAddress[1]==ArpCache[i].IpAddress[1])&&
98  (pIpAddress[2]==ArpCache[i].IpAddress[2])&&
99  (pIpAddress[3]==ArpCache[i].IpAddress[3]))
100  {
101  memcpy(pMacAddress,ArpCache[i].MacAddress,ETHERNET_MAC_LENGTH);
102  break;
103  }
104  }
105  if(i==ARP_CACHE_SIZE){ // not found in arp entry cache
106  F_EthernetArpRequestSend(pIpAddress); // send a request to recogenize
107  return FALSE;
108  }
109  else{
110  #if(DEBUG_ETHERNET_ADDRESS_GET==1)
111  printf("\n arp address get");
112  printf("\n MAC Addr %2x %2x %2x %2x %2x %2x",pMacAddress[0]
113  ,pMacAddress[1]
114  ,pMacAddress[2]
115  ,pMacAddress[3]
116  ,pMacAddress[4]
117  ,pMacAddress[5]);
118  printf("\n IP Addr %2x %2x %2x %2x ",pIpAddress[0]
119  ,pIpAddress[1]
120  ,pIpAddress[2]
121  ,pIpAddress[3]);
122  #endif
123  return TRUE;
124  }
125 }
127  ETHBUFFER *pBuffer;
128  ARP_HEAD *pArpRequest;
129  INT8U Boardcast[ETHERNET_MAC_LENGTH]={0xff,0xff,0xff,0xff,0xff,0xff};
130 
131  pBuffer=F_EthernetBufferAllocate();
132  F_EthernetBufferReserve(pBuffer,sizeof(ETHERNET_HEAD)); // 6+6+2=14bytes
133  pArpRequest=(ARP_HEAD *)F_EthernetBufferPut(pBuffer,sizeof(ARP_HEAD)); // 2+2+1+1+2+1+4+1+4=18bytes
134  pArpRequest->HardwareType=F_EthernetUnsignedShortH2N(ARP_HW_ETHER_10M); // put hardware type in buffer
135  pArpRequest->ProtocolType=F_EthernetUnsignedShortH2N(ETHERNET_P_IP); // put protocol type in buffer
136  pArpRequest->HardwareAddrLength=ETHERNET_MAC_LENGTH; // MAC[6] // put MAC address length in buffer
137  pArpRequest->IpAddrLength=ETHERNET_IP_LENGTH; // xx.xx.xx.xx // put IP address length in buffer
138  pArpRequest->Opcode=F_EthernetUnsignedShortH2N(ARP_OP_REQUEST); // put ARP opcode in buffer
139  memcpy(pArpRequest->SenderHardwareAddr,ArpEntry.MacAddress,ETHERNET_MAC_LENGTH); // put my MAC address in buffer
140  memcpy(pArpRequest->SenderIpAddr,ArpEntry.IpAddress,ETHERNET_IP_LENGTH); // put my MAC address in buffer
141  memset(pArpRequest->TargetHardwareAddr,0x00,ETHERNET_MAC_LENGTH); // put 0x000000000000 in destination MAC address
142  memcpy(pArpRequest->TargetIpAddr,pIpAddress,ETHERNET_IP_LENGTH); // put my MAC address in buffer
143  #if(DEBUG_ETHERNET_INFO)
144  printf("\n HardwareType %4x",F_EthernetUnsignedShortH2N(pArpRequest->HardwareType));
145  printf("\n ProtocolType %4x",F_EthernetUnsignedShortH2N(pArpRequest->ProtocolType));
146  printf("\n HardwareAddrLength %4x",pArpRequest->HardwareAddrLength);
147  printf("\n IpAddrLength %4x",pArpRequest->IpAddrLength);
148  printf("\n Opcode %4x",F_EthernetUnsignedShortH2N(pArpRequest->Opcode));
149  printf("\n SenderHardwareAddr %2x %2x %2x %2x %2x %2x",pArpRequest->SenderHardwareAddr[0]
150  ,pArpRequest->SenderHardwareAddr[1]
151  ,pArpRequest->SenderHardwareAddr[2]
152  ,pArpRequest->SenderHardwareAddr[3]
153  ,pArpRequest->SenderHardwareAddr[4]
154  ,pArpRequest->SenderHardwareAddr[5]);
155  printf("\n SenderIpAddr %2x %2x %2x %2x ",pArpRequest->SenderIpAddr[0]
156  ,pArpRequest->SenderIpAddr[1]
157  ,pArpRequest->SenderIpAddr[2]
158  ,pArpRequest->SenderIpAddr[3]);
159  printf("\n TargetHardwareAddr %2x %2x %2x %2x %2x %2x",pArpRequest->TargetHardwareAddr[0]
160  ,pArpRequest->TargetHardwareAddr[1]
161  ,pArpRequest->TargetHardwareAddr[2]
162  ,pArpRequest->TargetHardwareAddr[3]
163  ,pArpRequest->TargetHardwareAddr[4]
164  ,pArpRequest->TargetHardwareAddr[5]);
165  printf("\n TargetIpAddr %2x %2x %2x %2x ",pArpRequest->TargetIpAddr[0]
166  ,pArpRequest->TargetIpAddr[1]
167  ,pArpRequest->TargetIpAddr[2]
168  ,pArpRequest->TargetIpAddr[3]);
169  #endif
170  // put destination IP address in buffer
171  F_EthernetSend(pBuffer,Boardcast,ETHERNET_P_ARP);
172  return TRUE;
173 }
175  ETHBUFFER *pBuffer;
176  ARP_HEAD *pArpResponse;
177 
178  pBuffer=F_EthernetBufferAllocate();
180  pArpResponse=(ARP_HEAD *)F_EthernetBufferPut(pBuffer,sizeof(ARP_HEAD));
183  pArpResponse->HardwareAddrLength=0x06;
184  pArpResponse->IpAddrLength=0x04;
187  memcpy((INT8U*)pArpResponse->SenderIpAddr,pArpHead->TargetIpAddr,ETHERNET_IP_LENGTH); //?? ans...this TargetIpAddr is in previous buffer...no overlap
189  memcpy((INT8U*)pArpResponse->TargetIpAddr,pArpHead->SenderIpAddr,ETHERNET_IP_LENGTH); //?? ans...this TargetIpAddr is in previous buffer...no overlap
190  #if(DEBUG_ETHERNET_INFO)
191  printf("\n HardwareType %4x",F_EthernetUnsignedShortH2N(pArpResponse->HardwareType));
192  printf("\n ProtocolType %4x",F_EthernetUnsignedShortH2N(pArpResponse->ProtocolType));
193  printf("\n HardwareAddrLength %4x",pArpResponse->HardwareAddrLength);
194  printf("\n IpAddrLength %4x",pArpResponse->IpAddrLength);
195  printf("\n Opcode %4x",F_EthernetUnsignedShortH2N(pArpResponse->Opcode));
196  printf("\n SenderHardwareAddr %2x %2x %2x %2x %2x %2x",pArpResponse->SenderHardwareAddr[0]
197  ,pArpResponse->SenderHardwareAddr[1]
198  ,pArpResponse->SenderHardwareAddr[2]
199  ,pArpResponse->SenderHardwareAddr[3]
200  ,pArpResponse->SenderHardwareAddr[4]
201  ,pArpResponse->SenderHardwareAddr[5]);
202  printf("\n SenderIpAddr %2x %2x %2x %2x ",pArpResponse->SenderIpAddr[0]
203  ,pArpResponse->SenderIpAddr[1]
204  ,pArpResponse->SenderIpAddr[2]
205  ,pArpResponse->SenderIpAddr[3]);
206  printf("\n TargetHardwareAddr %2x %2x %2x %2x %2x %2x",pArpResponse->TargetHardwareAddr[0]
207  ,pArpResponse->TargetHardwareAddr[1]
208  ,pArpResponse->TargetHardwareAddr[2]
209  ,pArpResponse->TargetHardwareAddr[3]
210  ,pArpResponse->TargetHardwareAddr[4]
211  ,pArpResponse->TargetHardwareAddr[5]);
212  printf("\n TargetIpAddr %2x %2x %2x %2x ",pArpResponse->TargetIpAddr[0]
213  ,pArpResponse->TargetIpAddr[1]
214  ,pArpResponse->TargetIpAddr[2]
215  ,pArpResponse->TargetIpAddr[3]);
216 
217  #endif
219  return TRUE;
220 }
222  ETHBUFFER *pBuffer;
223  ARP_HEAD *pArpResponse;
224 
225  pBuffer=F_EthernetBufferAllocate();
227  pArpResponse=(ARP_HEAD *)F_EthernetBufferPut(pBuffer,sizeof(ARP_HEAD));
230  pArpResponse->HardwareAddrLength=0x06;
231  pArpResponse->IpAddrLength=0x04;
234  memcpy((INT8U*)pArpResponse->SenderIpAddr,ArpEntry.IpAddress,ETHERNET_IP_LENGTH); //?? ans...this TargetIpAddr is in previous buffer...no overlap
236  memcpy((INT8U*)pArpResponse->TargetIpAddr,pArpHead->SenderIpAddr,ETHERNET_IP_LENGTH); //?? ans...this TargetIpAddr is in previous buffer...no overlap
237  #if(DEBUG_ETHERNET_INFO)
238  printf("\n ******** arp response send 2********");
239  printf("\n HardwareType %4x",F_EthernetUnsignedShortH2N(pArpResponse->HardwareType));
240  printf("\n ProtocolType %4x",F_EthernetUnsignedShortH2N(pArpResponse->ProtocolType));
241  printf("\n HardwareAddrLength %4x",pArpResponse->HardwareAddrLength);
242  printf("\n IpAddrLength %4x",pArpResponse->IpAddrLength);
243  printf("\n Opcode %4x",F_EthernetUnsignedShortH2N(pArpResponse->Opcode));
244  printf("\n SenderHardwareAddr %2x %2x %2x %2x %2x %2x",pArpResponse->SenderHardwareAddr[0]
245  ,pArpResponse->SenderHardwareAddr[1]
246  ,pArpResponse->SenderHardwareAddr[2]
247  ,pArpResponse->SenderHardwareAddr[3]
248  ,pArpResponse->SenderHardwareAddr[4]
249  ,pArpResponse->SenderHardwareAddr[5]);
250  printf("\n SenderIpAddr %2x %2x %2x %2x ",pArpResponse->SenderIpAddr[0]
251  ,pArpResponse->SenderIpAddr[1]
252  ,pArpResponse->SenderIpAddr[2]
253  ,pArpResponse->SenderIpAddr[3]);
254  printf("\n TargetHardwareAddr %2x %2x %2x %2x %2x %2x",pArpResponse->TargetHardwareAddr[0]
255  ,pArpResponse->TargetHardwareAddr[1]
256  ,pArpResponse->TargetHardwareAddr[2]
257  ,pArpResponse->TargetHardwareAddr[3]
258  ,pArpResponse->TargetHardwareAddr[4]
259  ,pArpResponse->TargetHardwareAddr[5]);
260  printf("\n TargetIpAddr %2x %2x %2x %2x ",pArpResponse->TargetIpAddr[0]
261  ,pArpResponse->TargetIpAddr[1]
262  ,pArpResponse->TargetIpAddr[2]
263  ,pArpResponse->TargetIpAddr[3]);
264  printf("\n arp transmition done \n");
265 
266  #endif
268  return TRUE;
269 }
271  ARP_HEAD *pArpHead=(ARP_HEAD *)pBuffer->pData;
272 
273  if((pArpHead->TargetIpAddr[0]==ArpEntry.IpAddress[0])&&
274  (pArpHead->TargetIpAddr[1]==ArpEntry.IpAddress[1])&&
275  (pArpHead->TargetIpAddr[2]==ArpEntry.IpAddress[2])&&
276  (pArpHead->TargetIpAddr[3]==ArpEntry.IpAddress[3])){
278  F_EthernetArpResponseSend(pArpHead);
279  F_EthernetArpCacheAdd(pArpHead->SenderHardwareAddr,pArpHead->SenderIpAddr); // keep this host ip in cache
280  return TRUE;
281  }
282  else return FALSE; // IP not match
283 }
285  ARP_HEAD *pArpHead=(ARP_HEAD *)pBuffer->pData;
286 
287  #if(DEBUG_ETHERNET_INFO==1)
288  printf("\n ******** arp receive********");
289  printf("\n HardwareType %4x",F_EthernetUnsignedShortH2N(pArpHead->HardwareType));
290  printf("\n ProtocolType %4x",F_EthernetUnsignedShortH2N(pArpHead->ProtocolType));
291  printf("\n HardwareAddrLength %4x",pArpHead->HardwareAddrLength);
292  printf("\n IpAddrLength %4x",pArpHead->IpAddrLength);
293  printf("\n Opcode %4x",F_EthernetUnsignedShortH2N(pArpHead->Opcode));
294  printf("\n SenderHardwareAddr %2x %2x %2x %2x %2x %2x",pArpHead->SenderHardwareAddr[0]
295  ,pArpHead->SenderHardwareAddr[1]
296  ,pArpHead->SenderHardwareAddr[2]
297  ,pArpHead->SenderHardwareAddr[3]
298  ,pArpHead->SenderHardwareAddr[4]
299  ,pArpHead->SenderHardwareAddr[5]);
300  printf("\n SenderIpAddr %2x %2x %2x %2x ",pArpHead->SenderIpAddr[0]
301  ,pArpHead->SenderIpAddr[1]
302  ,pArpHead->SenderIpAddr[2]
303  ,pArpHead->SenderIpAddr[3]);
304  printf("\n TargetHardwareAddr %2x %2x %2x %2x %2x %2x",pArpHead->TargetHardwareAddr[0]
305  ,pArpHead->TargetHardwareAddr[1]
306  ,pArpHead->TargetHardwareAddr[2]
307  ,pArpHead->TargetHardwareAddr[3]
308  ,pArpHead->TargetHardwareAddr[4]
309  ,pArpHead->TargetHardwareAddr[5]);
310  printf("\n TargetIpAddr %2x %2x %2x %2x ",pArpHead->TargetIpAddr[0]
311  ,pArpHead->TargetIpAddr[1]
312  ,pArpHead->TargetIpAddr[2]
313  ,pArpHead->TargetIpAddr[3]);
314  printf("\n arp receive done \n");
315  #endif
318  (pArpHead->HardwareAddrLength==0x06)&&
319  (pArpHead->IpAddrLength==0x04)&&
321  F_EthernetArpCacheAdd(pArpHead->SenderHardwareAddr,pArpHead->SenderIpAddr); // keep this host ip in cache
322  F_EthernetArpResponseSend2(pArpHead); // this line must be after...F_EthernetArpCacheAdd(...)
323  }
324  return TRUE;
325 }