📄 uip_arp.lst
字号:
216 1 memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
217 1 tabptr->time = arptime;
218 1 }
219 /*-----------------------------------------------------------------------------------*/
220 /**
221 * ARP processing for incoming IP packets
222 *
223 * This function should be called by the device driver when an IP
224 * packet has been received. The function will check if the address is
225 * in the ARP cache, and if so the ARP cache entry will be
226 * refreshed. If no ARP cache entry was found, a new one is created.
227 *
228 * This function expects an IP packet with a prepended Ethernet header
229 * in the uip_buf[] buffer, and the length of the packet in the global
230 * variable uip_len.
231 */
232 /*-----------------------------------------------------------------------------------*/
233 #if 0
void
uip_arp_ipin(void)
{
uip_len -= sizeof(struct uip_eth_hdr);
/* Only insert/update an entry if the source IP address of the
C51 COMPILER V9.00 UIP_ARP 02/08/2010 20:58:32 PAGE 5
incoming IP packet comes from a host on the local network. */
if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
(uip_hostaddr[0] & uip_netmask[0])) {
return;
}
if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
(uip_hostaddr[1] & uip_netmask[1])) {
return;
}
uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
return;
}
#endif /* 0 */
254 /*-----------------------------------------------------------------------------------*/
255 /**
256 * ARP processing for incoming ARP packets.
257 *
258 * This function should be called by the device driver when an ARP
259 * packet has been received. The function will act differently
260 * depending on the ARP packet type: if it is a reply for a request
261 * that we previously sent out, the ARP cache will be filled in with
262 * the values from the ARP reply. If the incoming ARP packet is an ARP
263 * request for our IP address, an ARP reply packet is created and put
264 * into the uip_buf[] buffer.
265 *
266 * When the function returns, the value of the global variable uip_len
267 * indicates whether the device driver should send out a packet or
268 * not. If uip_len is zero, no packet should be sent. If uip_len is
269 * non-zero, it contains the length of the outbound packet that is
270 * present in the uip_buf[] buffer.
271 *
272 * This function expects an ARP packet with a prepended Ethernet
273 * header in the uip_buf[] buffer, and the length of the packet in the
274 * global variable uip_len.
275 */
276 /*-----------------------------------------------------------------------------------*/
277 void
278 uip_arp_arpin(void)
279 {
280 1
281 1 if(uip_len < sizeof(struct arp_hdr)) {
282 2 uip_len = 0;
283 2 return;
284 2 }
285 1 uip_len = 0;
286 1
287 1 switch(BUF->opcode) {
288 2 case HTONS(ARP_REQUEST):
289 2 /* ARP request. If it asked for our address, we send out a
290 2 reply. */
291 2 if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
292 3 /* First, we register the one who made the request in our ARP
293 3 table, since it is likely that we will do more communication
294 3 with this host in the future. */
295 3 uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
296 3
297 3 /* The reply opcode is 2. */
298 3 BUF->opcode = HTONS(2);
299 3
300 3 memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
301 3 memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
C51 COMPILER V9.00 UIP_ARP 02/08/2010 20:58:32 PAGE 6
302 3 memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
303 3 memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
304 3
305 3 BUF->dipaddr[0] = BUF->sipaddr[0];
306 3 BUF->dipaddr[1] = BUF->sipaddr[1];
307 3 BUF->sipaddr[0] = uip_hostaddr[0];
308 3 BUF->sipaddr[1] = uip_hostaddr[1];
309 3
310 3 BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
311 3 uip_len = sizeof(struct arp_hdr);
312 3 }
313 2 break;
314 2 case HTONS(ARP_REPLY):
315 2 /* ARP reply. We insert or update the ARP table if it was meant
316 2 for us. */
317 2 if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
318 3 uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
319 3 }
320 2 break;
321 2 }
322 1
323 1 return;
324 1 }
325 /*-----------------------------------------------------------------------------------*/
326 /**
327 * Prepend Ethernet header to an outbound IP packet and see if we need
328 * to send out an ARP request.
329 *
330 * This function should be called before sending out an IP packet. The
331 * function checks the destination IP address of the IP packet to see
332 * what Ethernet MAC address that should be used as a destination MAC
333 * address on the Ethernet.
334 *
335 * If the destination IP address is in the local network (determined
336 * by logical ANDing of netmask and our IP address), the function
337 * checks the ARP cache to see if an entry for the destination IP
338 * address is found. If so, an Ethernet header is prepended and the
339 * function returns. If no ARP cache entry is found for the
340 * destination IP address, the packet in the uip_buf[] is replaced by
341 * an ARP request packet for the IP address. The IP packet is dropped
342 * and it is assumed that they higher level protocols (e.g., TCP)
343 * eventually will retransmit the dropped packet.
344 *
345 * If the destination IP address is not on the local network, the IP
346 * address of the default router is used instead.
347 *
348 * When the function returns, a packet is present in the uip_buf[]
349 * buffer, and the length of the packet is in the global variable
350 * uip_len.
351 */
352 /*-----------------------------------------------------------------------------------*/
353 void
354 uip_arp_out(void)
355 {
356 1 struct arp_entry *tabptr;
357 1
358 1 /* Find the destination IP address in the ARP table and construct
359 1 the Ethernet header. If the destination IP addres isn't on the
360 1 local network, we use the default router's IP address instead.
361 1
362 1 If not ARP table entry is found, we overwrite the original IP
363 1 packet with an ARP request for the IP address. */
C51 COMPILER V9.00 UIP_ARP 02/08/2010 20:58:32 PAGE 7
364 1
365 1 /* First check if destination is a local broadcast. */
366 1 if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
367 2 memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
368 2 } else {
369 2 /* Check if the destination address is on the local network. */
370 2 if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
371 3 /* Destination address was not on the local network, so we need to
372 3 use the default router's IP address instead of the destination
373 3 address when determining the MAC address. */
374 3 uip_ipaddr_copy(ipaddr, uip_draddr);
375 3 } else {
376 3 /* Else, we use the destination IP address. */
377 3 uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
378 3 }
379 2
380 2 for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
381 3 tabptr = &arp_table[i];
382 3 if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
383 4 break;
384 4 }
385 3 }
386 2
387 2 if(i == UIP_ARPTAB_SIZE) {
388 3 /* The destination address was not in our ARP table, so we
389 3 overwrite the IP packet with an ARP request. */
390 3
391 3 memset(BUF->ethhdr.dest.addr, 0xff, 6);
392 3 memset(BUF->dhwaddr.addr, 0x00, 6);
393 3 memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
394 3 memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
395 3
396 3 uip_ipaddr_copy(BUF->dipaddr, ipaddr);
397 3 uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
398 3 BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
399 3 BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
400 3 BUF->protocol = HTONS(UIP_ETHTYPE_IP);
401 3 BUF->hwlen = 6;
402 3 BUF->protolen = 4;
403 3 BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
404 3
405 3 uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
406 3
407 3 uip_len = sizeof(struct arp_hdr);
408 3 return;
409 3 }
410 2
411 2 /* Build an ethernet header. */
412 2 memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
413 2 }
414 1 memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
415 1
416 1 IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
417 1
418 1 uip_len += sizeof(struct uip_eth_hdr);
419 1 }
420 /*-----------------------------------------------------------------------------------*/
421
422 /** @} */
423 /** @} */
C51 COMPILER V9.00 UIP_ARP 02/08/2010 20:58:32 PAGE 8
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1535 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 106 12
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
IDATA SIZE = ---- ----
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 + -