📄 uip_arp.lst
字号:
186 2 }
187 1 if((IPBUF->srcipaddr[1] & uip_arp_netmask[1]) !=
188 1 (uip_hostaddr[1] & uip_arp_netmask[1])) {
189 2 return;
190 2 }
191 1 uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
192 1
193 1 return;
194 1 }
195 /*-----------------------------------------------------------------------------------*/
196 /**
197 * ARP processing for incoming ARP packets.
198 *
199 * This function should be called by the device driver when an ARP
200 * packet has been received. The function will act differently
201 * depending on the ARP packet type: if it is a reply for a request
202 * that we previously sent out, the ARP cache will be filled in with
203 * the values from the ARP reply. If the incoming ARP packet is an ARP
204 * request for our IP address, an ARP reply packet is created and put
205 * into the uip_buf[] buffer.
206 *
207 * When the function returns, the value of the global variable uip_len
208 * indicates whether the device driver should send out a packet or
209 * not. If uip_len is zero, no packet should be sent. If uip_len is
210 * non-zero, it contains the length of the outbound packet that is
211 * present in the uip_buf[] buffer.
212 *
213 * This function expects an ARP packet with a prepended Ethernet
214 * header in the uip_buf[] buffer, and the length of the packet in the
215 * global variable uip_len.
216 */
217 /*-----------------------------------------------------------------------------------*/
218 void
219 uip_arp_arpin(void)
220 {
221 1
222 1 if(uip_len < sizeof(struct arp_hdr)) {
223 2 uip_len = 0;
224 2 return;
225 2 }
226 1
227 1 uip_len = 0;
228 1
229 1 switch(BUF->opcode) {
230 2 case HTONS(ARP_REQUEST):
231 2 /* ARP request. If it asked for our address, we send out a
232 2 reply. */
233 2 if(BUF->dipaddr[0] == uip_hostaddr[0] &&
234 2 BUF->dipaddr[1] == uip_hostaddr[1]) {
235 3 /* The reply opcode is 2. */
236 3 BUF->opcode = HTONS(2);
237 3
238 3 memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
239 3 memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
240 3 memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
C51 COMPILER V8.02 UIP_ARP 10/13/2008 17:11:19 PAGE 5
241 3 memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
242 3
243 3 BUF->dipaddr[0] = BUF->sipaddr[0];
244 3 BUF->dipaddr[1] = BUF->sipaddr[1];
245 3 BUF->sipaddr[0] = uip_hostaddr[0];
246 3 BUF->sipaddr[1] = uip_hostaddr[1];
247 3
248 3 BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
249 3 uip_len = sizeof(struct arp_hdr);
250 3 }
251 2 break;
252 2 case HTONS(ARP_REPLY):
253 2 /* ARP reply. We insert or update the ARP table if it was meant
254 2 for us. */
255 2 if(BUF->dipaddr[0] == uip_hostaddr[0] &&
256 2 BUF->dipaddr[1] == uip_hostaddr[1]) {
257 3
258 3 uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
259 3 }
260 2 break;
261 2 }
262 1
263 1 return;
264 1 }
265 /*-----------------------------------------------------------------------------------*/
266 /**
267 * Prepend Ethernet header to an outbound IP packet and see if we need
268 * to send out an ARP request.
269 *
270 * This function should be called before sending out an IP packet. The
271 * function checks the destination IP address of the IP packet to see
272 * what Ethernet MAC address that should be used as a destination MAC
273 * address on the Ethernet.
274 *
275 * If the destination IP address is in the local network (determined
276 * by logical ANDing of netmask and our IP address), the function
277 * checks the ARP cache to see if an entry for the destination IP
278 * address is found. If so, an Ethernet header is prepended and the
279 * function returns. If no ARP cache entry is found for the
280 * destination IP address, the packet in the uip_buf[] is replaced by
281 * an ARP request packet for the IP address. The IP packet is dropped
282 * and it is assumed that they higher level protocols (e.g., TCP)
283 * eventually will retransmit the dropped packet.
284 *
285 * If the destination IP address is not on the local network, the IP
286 * address of the default router is used instead.
287 *
288 * When the function returns, a packet is present in the uip_buf[]
289 * buffer, and the length of the packet is in the global variable
290 * uip_len.
291 */
292 /*-----------------------------------------------------------------------------------*/
293 void
294 uip_arp_out(void)
295 {
296 1 struct arp_entry *tabptr;
297 1 /* Find the destination IP address in the ARP table and construct
298 1 the Ethernet header. If the destination IP addres isn't on the
299 1 local network, we use the default router's IP address instead.
300 1
301 1 If not ARP table entry is found, we overwrite the original IP
302 1 packet with an ARP request for the IP address. */
C51 COMPILER V8.02 UIP_ARP 10/13/2008 17:11:19 PAGE 6
303 1
304 1 /* Check if the destination address is on the local network. */
305 1 if((IPBUF->destipaddr[0] & uip_arp_netmask[0]) !=
306 1 (uip_hostaddr[0] & uip_arp_netmask[0]) ||
307 1 (IPBUF->destipaddr[1] & uip_arp_netmask[1]) !=
308 1 (uip_hostaddr[1] & uip_arp_netmask[1])) {
309 2 /* Destination address was not on the local network, so we need to
310 2 use the default router's IP address instead of the destination
311 2 address when determining the MAC address. */
312 2 ipaddr[0] = uip_arp_draddr[0];
313 2 ipaddr[1] = uip_arp_draddr[1];
314 2 } else {
315 2 /* Else, we use the destination IP address. */
316 2 ipaddr[0] = IPBUF->destipaddr[0];
317 2 ipaddr[1] = IPBUF->destipaddr[1];
318 2 }
319 1
320 1 for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
321 2 tabptr = &arp_table[i];
322 2 if(ipaddr[0] == tabptr->ipaddr[0] &&
323 2 ipaddr[1] == tabptr->ipaddr[1])
324 2 break;
325 2 }
326 1
327 1 if(i == UIP_ARPTAB_SIZE) {
328 2 /* The destination address was not in our ARP table, so we
329 2 overwrite the IP packet with an ARP request. */
330 2
331 2 memset(BUF->ethhdr.dest.addr, 0xff, 6);
332 2 memset(BUF->dhwaddr.addr, 0x00, 6);
333 2 memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
334 2 memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
335 2
336 2 BUF->dipaddr[0] = ipaddr[0];
337 2 BUF->dipaddr[1] = ipaddr[1];
338 2 BUF->sipaddr[0] = uip_hostaddr[0];
339 2 BUF->sipaddr[1] = uip_hostaddr[1];
340 2 BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
341 2 BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
342 2 BUF->protocol = HTONS(UIP_ETHTYPE_IP);
343 2 BUF->hwlen = 6;
344 2 BUF->protolen = 4;
345 2 BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
346 2
347 2 uip_appdata = &uip_buf[40 + UIP_LLH_LEN];
348 2
349 2 uip_len = sizeof(struct arp_hdr);
350 2 return;
351 2 }
352 1
353 1 /* Build an ethernet header. */
354 1 memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
355 1 memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
356 1
357 1 IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
358 1
359 1 uip_len += sizeof(struct uip_eth_hdr);
360 1 }
361 /*-----------------------------------------------------------------------------------*/
362
363 /** @} */
364 /** @} */
C51 COMPILER V8.02 UIP_ARP 10/13/2008 17:11:19 PAGE 7
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 1496 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 36 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 + -