📄 arp.lst
字号:
154 // See "TCP/IP Illustrated, Volume 1" Sect 4.5
155 // arp解析
156 //------------------------------------------------------------------------
157 UCHAR xdata * arp_resolve(ULONG dest_ipaddr)
158 {
159 1 UCHAR i;
160 1
161 1 // If destination IP is not on my subnet then we really want eth addr
162 1 // of gateway, not destination IP
163 1 if ((dest_ipaddr ^ my_ipaddr) & my_subnet)
164 1 {
165 2 if (gateway_ipaddr == 0)
166 2 {
167 3 if (debug) SendCommString("ARP: Error, gateway addr not set\r");
168 3 return (NULL);
169 3 }
170 2 else dest_ipaddr = gateway_ipaddr;
171 2 }
172 1
173 1
174 1 // See if IP addr of interest is in ARP cache
175 1 for (i=0; i < CACHESIZE; i++)
176 1 {
177 2 if (arp_cache[i].ipaddr == dest_ipaddr)
178 2 return (&arp_cache[i].hwaddr[0]);
179 2 }
C51 COMPILER V7.20 ARP 03/07/2006 14:49:08 PAGE 4
180 1
181 1 if (debug) SendCommString("ARP: IP addr not found in cache\r");
182 1 if (debug) SendCommString("ARP: Sending an ARP broadcast\r");
183 1 // Not in cache so broadcast ARP request
184 1 arp_send(NULL, dest_ipaddr, ARP_REQUEST);
185 1
186 1 // Set a flag to indicate that an IP datagram is waiting
187 1 // to be sent
188 1 waiting_for_arp = TRUE;
189 1
190 1 // Null means that we have sent an ARP request
191 1 return (NULL);
192 1 }
193
194
195 //------------------------------------------------------------------------
196 // This handles incoming ARP messages
197 // See "TCP/IP Illustrated, Volume 1" Sect 4.4
198 // Todo: Resolve problem of trying to add to a full cache
199 //------------------------------------------------------------------------
200 void arp_rcve(UCHAR xdata * inbuf)
201 {
202 1 UCHAR idata i, cached, oldest;
203 1 UINT idata minimum;
204 1 ARP_HEADER xdata * arp;
205 1
206 1 arp = (ARP_HEADER xdata *)(inbuf + 14);
207 1 cached = FALSE;
208 1
209 1 // Print message
210 1 if (debug)
211 1 {
212 2 if (arp->message_type == ARP_REQUEST)SendCommString("ARP: Request rcvd\r");
213 2 else SendCommString("ARP: Response rcvd\r");
214 2 }
215 1
216 1 // Validate incoming frame
217 1 if ((arp->hardware_type != DIX_ETHERNET) ||
218 1 (arp->protocol_type != IP_PACKET)) return;
219 1
220 1 // Search ARP cache for senders IP address
221 1 // If found, update entry and restart timer
222 1 for (i=0; i < CACHESIZE; i++)
223 1 {
224 2 if (arp_cache[i].ipaddr == arp->source_ipaddr)
225 2 {
226 3 memcpy(&arp_cache[i].hwaddr[0], &arp->source_hwaddr[0], 6);
227 3 arp_cache[i].timer = CACHETIME;
228 3 cached = TRUE;
229 3 if (debug) SendCommString("ARP: Cache entry updated\r");
230 3 break;
231 3 }
232 2 }
233 1
234 1 if (arp->dest_ipaddr != my_ipaddr) return;
235 1
236 1 // At this point we know the the frame is addressed to me
237 1 // If not already in cache then add entry and start timer
238 1 if (cached == FALSE)
239 1 {
240 2 // Find first blank space and add entry
241 2 // Blank entries are indicated by ip addr = 0
C51 COMPILER V7.20 ARP 03/07/2006 14:49:08 PAGE 5
242 2 for (i=0; i < CACHESIZE; i++)
243 2 {
244 3 if (arp_cache[i].ipaddr == 0)
245 3 {
246 4 arp_cache[i].ipaddr = arp->source_ipaddr;
247 4 memcpy(&arp_cache[i].hwaddr[0], &arp->source_hwaddr[0], 6);
248 4 arp_cache[i].timer = CACHETIME;
249 4 if (debug) SendCommString("ARP: New cache entry added\r");
250 4 break;
251 4 }
252 3 }
253 2
254 2 // If no blank entries in arp cache then sort cache
255 2 // to find oldest entry and replace it
256 2 if (i == CACHESIZE)
257 2 {
258 3 // Oldest entry is the one with lowest timer value
259 3 minimum = 0xFFFF;
260 3 for (i=0; i < CACHESIZE; i++)
261 3 {
262 4 if (arp_cache[i].timer < minimum)
263 4 {
264 5 minimum = arp_cache[i].timer;
265 5 oldest = i;
266 5 }
267 4 }
268 3
269 3 // "oldest" is now index of oldest entry, so replace it
270 3 arp_cache[oldest].ipaddr = arp->source_ipaddr;
271 3 memcpy(&arp_cache[oldest].hwaddr[0], &arp->source_hwaddr[0], 6);
272 3 arp_cache[oldest].timer = CACHETIME;
273 3 if (debug) SendCommString("ARP: Cache full, so replaced oldest\r");
274 3 }
275 2 }
276 1
277 1
278 1 // If we are waiting for an arp response and the arp response
279 1 // that just came in is addressed to me and is from the host
280 1 // we are waiting for, then send the message-in-waiting
281 1 if (arp->message_type == ARP_RESPONSE)
282 1 {
283 2 if ((waiting_for_arp) && (wait.ipaddr == arp->source_ipaddr))
284 2 {
285 3 waiting_for_arp = FALSE;
286 3 ip_send(wait.buf, wait.ipaddr, wait.proto_id, wait.len);
287 3 }
288 2 }
289 1 else if (arp->message_type == ARP_REQUEST)
290 1 {
291 2 // Send ARP response
292 2 if (debug) SendCommString("ARP: Sending response\r");
293 2 arp_send(arp->source_hwaddr, arp->source_ipaddr, ARP_RESPONSE);
294 2 }
295 1 }
296
297
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1303 ----
CONSTANT SIZE = 372 ----
XDATA SIZE = 110 ----
C51 COMPILER V7.20 ARP 03/07/2006 14:49:08 PAGE 6
PDATA SIZE = ---- ----
DATA SIZE = 1 20
IDATA SIZE = 1 5
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -