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