00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "global.h"
00016 #include "net.h"
00017 #include "nic.h"
00018 #include "arp.h"
00019
00020 #include "rprintf.h"
00021
00022
00023
00024 struct ArpEntry
00025 {
00026 uint32_t ipaddr;
00027 struct netEthAddr ethaddr;
00028 uint8_t time;
00029 };
00030
00031 struct ArpEntry ArpMyAddr;
00032 struct ArpEntry ArpTable[ARP_TABLE_SIZE];
00033
00034
00035 void arpInit(void)
00036 {
00037 u08 i;
00038
00039 for(i=0; i<ARP_TABLE_SIZE; i++)
00040 {
00041 ArpTable[i].ipaddr = 0;
00042 ArpTable[i].time = 0;
00043 }
00044 }
00045
00046 void arpSetAddress(struct netEthAddr* myeth, uint32_t myip)
00047 {
00048
00049 ArpMyAddr.ethaddr = *myeth;
00050 ArpMyAddr.ipaddr = myip;
00051 }
00052
00053 void arpArpIn(unsigned int len, struct netEthArpHeader* packet)
00054 {
00055
00056
00057 if( (packet->arp.dipaddr == HTONL(ArpMyAddr.ipaddr)) &&
00058 (packet->arp.opcode == htons(ARP_OPCODE_REQUEST)) )
00059 {
00060
00061
00062 packet->arp.dhwaddr = packet->arp.shwaddr;
00063 packet->arp.dipaddr = packet->arp.sipaddr;
00064
00065 packet->arp.shwaddr = ArpMyAddr.ethaddr;
00066 packet->arp.sipaddr = HTONL(ArpMyAddr.ipaddr);
00067
00068 packet->arp.opcode = htons(ARP_OPCODE_REPLY);
00069
00070
00071 packet->eth.dest = packet->eth.src;
00072 packet->eth.src = ArpMyAddr.ethaddr;
00073
00074
00075
00076
00077
00078 nicSend(len, (unsigned char*)packet);
00079 }
00080 }
00081
00082 void arpIpIn(struct netEthIpHeader* packet)
00083 {
00084 int8_t index;
00085
00086
00087 index = arpMatchIp(HTONL(packet->ip.srcipaddr));
00088 if(index != -1)
00089 {
00090
00091 ArpTable[index].ethaddr = packet->eth.src;
00092
00093 return;
00094 }
00095
00096
00097
00098 for(index=0; index<ARP_TABLE_SIZE; index++)
00099 {
00100 if(!ArpTable[index].time)
00101 {
00102
00103 ArpTable[index].ethaddr = packet->eth.src;
00104 ArpTable[index].ipaddr = HTONL(packet->ip.srcipaddr);
00105 ArpTable[index].time = ARP_CACHE_TIME_TO_LIVE;
00106
00107 return;
00108 }
00109 }
00110
00111
00112 }
00113
00114 void arpIpOut(struct netEthIpHeader* packet, uint32_t phyDstIp)
00115 {
00116 int index;
00117
00118
00119 if(phyDstIp)
00120 index = arpMatchIp(phyDstIp);
00121 else
00122 index = arpMatchIp(HTONL(packet->ip.destipaddr));
00123
00124 if(index != -1)
00125 {
00126
00127 packet->eth.src = ArpMyAddr.ethaddr;
00128 packet->eth.dest = ArpTable[index].ethaddr;
00129 packet->eth.type = HTONS(ETHTYPE_IP);
00130 }
00131 else
00132 {
00133
00134 packet->eth.src = ArpMyAddr.ethaddr;
00135
00136 packet->eth.dest.addr[0] = 0xFF;
00137 packet->eth.dest.addr[1] = 0xFF;
00138 packet->eth.dest.addr[2] = 0xFF;
00139 packet->eth.dest.addr[3] = 0xFF;
00140 packet->eth.dest.addr[4] = 0xFF;
00141 packet->eth.dest.addr[5] = 0xFF;
00142 packet->eth.type = HTONS(ETHTYPE_IP);
00143 }
00144 }
00145
00146 void arpTimer(void)
00147 {
00148 int index;
00149
00150
00151
00152 for(index=0; index<ARP_TABLE_SIZE; index++)
00153 {
00154 if(ArpTable[index].time)
00155 ArpTable[index].time--;
00156 }
00157 }
00158
00159 int arpMatchIp(uint32_t ipaddr)
00160 {
00161 uint8_t i;
00162
00163
00164 for(i=0; i<ARP_TABLE_SIZE; i++)
00165 {
00166 if(ArpTable[i].ipaddr == ipaddr)
00167 {
00168
00169 return i;
00170 }
00171 }
00172
00173
00174 return -1;
00175 }
00176
00177 #ifdef ARP_DEBUG_PRINT
00178 void arpPrintHeader(struct netArpHeader* packet)
00179 {
00180 rprintfProgStrM("ARP Packet:\r\n");
00181
00182
00183 rprintfProgStrM("Operation : ");
00184 if(packet->opcode == htons(ARP_OPCODE_REQUEST))
00185 rprintfProgStrM("REQUEST");
00186 else if(packet->opcode == htons(ARP_OPCODE_REPLY))
00187 rprintfProgStrM("REPLY");
00188 else
00189 rprintfProgStrM("UNKNOWN");
00190 rprintfCRLF();
00191
00192 rprintfProgStrM("SrcHwAddr : "); netPrintEthAddr(&packet->shwaddr); rprintfCRLF();
00193
00194 rprintfProgStrM("SrcProtoAddr: "); netPrintIPAddr(HTONL(packet->sipaddr)); rprintfCRLF();
00195
00196 rprintfProgStrM("DstHwAddr : "); netPrintEthAddr(&packet->dhwaddr); rprintfCRLF();
00197
00198 rprintfProgStrM("DstProtoAddr: "); netPrintIPAddr(HTONL(packet->dipaddr)); rprintfCRLF();
00199 }
00200
00201
00202 void arpPrintTable(void)
00203 {
00204 uint8_t i;
00205
00206
00207 rprintfProgStrM("Time Eth Address IP Address\r\n");
00208 rprintfProgStrM("---------------------------------------\r\n");
00209 for(i=0; i<ARP_TABLE_SIZE; i++)
00210 {
00211 rprintfu08(ArpTable[i].time);
00212 rprintfProgStrM(" ");
00213 netPrintEthAddr(&ArpTable[i].ethaddr);
00214 rprintfProgStrM(" ");
00215 netPrintIPAddr(ArpTable[i].ipaddr);
00216 rprintfCRLF();
00217 }
00218 }
00219 #endif