From a6163888f3c56123b1db313743c6147ba498732c Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Fri, 8 Aug 2014 14:42:07 +0300 Subject: Add third_party libs --- third_party/uip-1.0/doc/html/a00204.html | 448 +++++++++++++++++++++++++++++++ 1 file changed, 448 insertions(+) create mode 100644 third_party/uip-1.0/doc/html/a00204.html (limited to 'third_party/uip-1.0/doc/html/a00204.html') diff --git a/third_party/uip-1.0/doc/html/a00204.html b/third_party/uip-1.0/doc/html/a00204.html new file mode 100644 index 0000000..3b8a0ae --- /dev/null +++ b/third_party/uip-1.0/doc/html/a00204.html @@ -0,0 +1,448 @@ + + +uIP 1.0: uip/uip_arp.c Source File + + + + +
+
+
+
+

uip/uip_arp.c

Go to the documentation of this file.
00001 /**
+00002  * \addtogroup uip
+00003  * @{
+00004  */
+00005 
+00006 /**
+00007  * \defgroup uiparp uIP Address Resolution Protocol
+00008  * @{
+00009  *
+00010  * The Address Resolution Protocol ARP is used for mapping between IP
+00011  * addresses and link level addresses such as the Ethernet MAC
+00012  * addresses. ARP uses broadcast queries to ask for the link level
+00013  * address of a known IP address and the host which is configured with
+00014  * the IP address for which the query was meant, will respond with its
+00015  * link level address.
+00016  *
+00017  * \note This ARP implementation only supports Ethernet.
+00018  */
+00019  
+00020 /**
+00021  * \file
+00022  * Implementation of the ARP Address Resolution Protocol.
+00023  * \author Adam Dunkels <adam@dunkels.com>
+00024  *
+00025  */
+00026 
+00027 /*
+00028  * Copyright (c) 2001-2003, Adam Dunkels.
+00029  * All rights reserved.
+00030  *
+00031  * Redistribution and use in source and binary forms, with or without
+00032  * modification, are permitted provided that the following conditions
+00033  * are met:
+00034  * 1. Redistributions of source code must retain the above copyright
+00035  *    notice, this list of conditions and the following disclaimer.
+00036  * 2. Redistributions in binary form must reproduce the above copyright
+00037  *    notice, this list of conditions and the following disclaimer in the
+00038  *    documentation and/or other materials provided with the distribution.
+00039  * 3. The name of the author may not be used to endorse or promote
+00040  *    products derived from this software without specific prior
+00041  *    written permission.
+00042  *
+00043  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
+00044  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+00045  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+00046  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+00047  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+00048  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+00049  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+00050  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+00051  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+00052  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+00053  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+00054  *
+00055  * This file is part of the uIP TCP/IP stack.
+00056  *
+00057  * $Id: uip_arp.c,v 1.8 2006/06/02 23:36:21 adam Exp $
+00058  *
+00059  */
+00060 
+00061 
+00062 #include "uip_arp.h"
+00063 
+00064 #include <string.h>
+00065 
+00066 struct arp_hdr {
+00067   struct uip_eth_hdr ethhdr;
+00068   u16_t hwtype;
+00069   u16_t protocol;
+00070   u8_t hwlen;
+00071   u8_t protolen;
+00072   u16_t opcode;
+00073   struct uip_eth_addr shwaddr;
+00074   u16_t sipaddr[2];
+00075   struct uip_eth_addr dhwaddr;
+00076   u16_t dipaddr[2];
+00077 };
+00078 
+00079 struct ethip_hdr {
+00080   struct uip_eth_hdr ethhdr;
+00081   /* IP header. */
+00082   u8_t vhl,
+00083     tos,
+00084     len[2],
+00085     ipid[2],
+00086     ipoffset[2],
+00087     ttl,
+00088     proto;
+00089   u16_t ipchksum;
+00090   u16_t srcipaddr[2],
+00091     destipaddr[2];
+00092 };
+00093 
+00094 #define ARP_REQUEST 1
+00095 #define ARP_REPLY   2
+00096 
+00097 #define ARP_HWTYPE_ETH 1
+00098 
+00099 struct arp_entry {
+00100   u16_t ipaddr[2];
+00101   struct uip_eth_addr ethaddr;
+00102   u8_t time;
+00103 };
+00104 
+00105 static const struct uip_eth_addr broadcast_ethaddr =
+00106   {{0xff,0xff,0xff,0xff,0xff,0xff}};
+00107 static const u16_t broadcast_ipaddr[2] = {0xffff,0xffff};
+00108 
+00109 static struct arp_entry arp_table[UIP_ARPTAB_SIZE];
+00110 static u16_t ipaddr[2];
+00111 static u8_t i, c;
+00112 
+00113 static u8_t arptime;
+00114 static u8_t tmpage;
+00115 
+00116 #define BUF   ((struct arp_hdr *)&uip_buf[0])
+00117 #define IPBUF ((struct ethip_hdr *)&uip_buf[0])
+00118 /*-----------------------------------------------------------------------------------*/
+00119 /**
+00120  * Initialize the ARP module.
+00121  *
+00122  */
+00123 /*-----------------------------------------------------------------------------------*/
+00124 void
+00125 uip_arp_init(void)
+00126 {
+00127   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00128     memset(arp_table[i].ipaddr, 0, 4);
+00129   }
+00130 }
+00131 /*-----------------------------------------------------------------------------------*/
+00132 /**
+00133  * Periodic ARP processing function.
+00134  *
+00135  * This function performs periodic timer processing in the ARP module
+00136  * and should be called at regular intervals. The recommended interval
+00137  * is 10 seconds between the calls.
+00138  *
+00139  */
+00140 /*-----------------------------------------------------------------------------------*/
+00141 void
+00142 uip_arp_timer(void)
+00143 {
+00144   struct arp_entry *tabptr;
+00145   
+00146   ++arptime;
+00147   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00148     tabptr = &arp_table[i];
+00149     if((tabptr->ipaddr[0] | tabptr->ipaddr[1]) != 0 &&
+00150        arptime - tabptr->time >= UIP_ARP_MAXAGE) {
+00151       memset(tabptr->ipaddr, 0, 4);
+00152     }
+00153   }
+00154 
+00155 }
+00156 /*-----------------------------------------------------------------------------------*/
+00157 static void
+00158 uip_arp_update(u16_t *ipaddr, struct uip_eth_addr *ethaddr)
+00159 {
+00160   register struct arp_entry *tabptr;
+00161   /* Walk through the ARP mapping table and try to find an entry to
+00162      update. If none is found, the IP -> MAC address mapping is
+00163      inserted in the ARP table. */
+00164   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00165 
+00166     tabptr = &arp_table[i];
+00167     /* Only check those entries that are actually in use. */
+00168     if(tabptr->ipaddr[0] != 0 &&
+00169        tabptr->ipaddr[1] != 0) {
+00170 
+00171       /* Check if the source IP address of the incoming packet matches
+00172          the IP address in this ARP table entry. */
+00173       if(ipaddr[0] == tabptr->ipaddr[0] &&
+00174          ipaddr[1] == tabptr->ipaddr[1]) {
+00175          
+00176         /* An old entry found, update this and return. */
+00177         memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
+00178         tabptr->time = arptime;
+00179 
+00180         return;
+00181       }
+00182     }
+00183   }
+00184 
+00185   /* If we get here, no existing ARP table entry was found, so we
+00186      create one. */
+00187 
+00188   /* First, we try to find an unused entry in the ARP table. */
+00189   for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00190     tabptr = &arp_table[i];
+00191     if(tabptr->ipaddr[0] == 0 &&
+00192        tabptr->ipaddr[1] == 0) {
+00193       break;
+00194     }
+00195   }
+00196 
+00197   /* If no unused entry is found, we try to find the oldest entry and
+00198      throw it away. */
+00199   if(i == UIP_ARPTAB_SIZE) {
+00200     tmpage = 0;
+00201     c = 0;
+00202     for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00203       tabptr = &arp_table[i];
+00204       if(arptime - tabptr->time > tmpage) {
+00205         tmpage = arptime - tabptr->time;
+00206         c = i;
+00207       }
+00208     }
+00209     i = c;
+00210     tabptr = &arp_table[i];
+00211   }
+00212 
+00213   /* Now, i is the ARP table entry which we will fill with the new
+00214      information. */
+00215   memcpy(tabptr->ipaddr, ipaddr, 4);
+00216   memcpy(tabptr->ethaddr.addr, ethaddr->addr, 6);
+00217   tabptr->time = arptime;
+00218 }
+00219 /*-----------------------------------------------------------------------------------*/
+00220 /**
+00221  * ARP processing for incoming IP packets
+00222  *
+00223  * This function should be called by the device driver when an IP
+00224  * packet has been received. The function will check if the address is
+00225  * in the ARP cache, and if so the ARP cache entry will be
+00226  * refreshed. If no ARP cache entry was found, a new one is created.
+00227  *
+00228  * This function expects an IP packet with a prepended Ethernet header
+00229  * in the uip_buf[] buffer, and the length of the packet in the global
+00230  * variable uip_len.
+00231  */
+00232 /*-----------------------------------------------------------------------------------*/
+00233 #if 0
+00234 void
+00235 uip_arp_ipin(void)
+00236 {
+00237   uip_len -= sizeof(struct uip_eth_hdr);
+00238         
+00239   /* Only insert/update an entry if the source IP address of the
+00240      incoming IP packet comes from a host on the local network. */
+00241   if((IPBUF->srcipaddr[0] & uip_netmask[0]) !=
+00242      (uip_hostaddr[0] & uip_netmask[0])) {
+00243     return;
+00244   }
+00245   if((IPBUF->srcipaddr[1] & uip_netmask[1]) !=
+00246      (uip_hostaddr[1] & uip_netmask[1])) {
+00247     return;
+00248   }
+00249   uip_arp_update(IPBUF->srcipaddr, &(IPBUF->ethhdr.src));
+00250   
+00251   return;
+00252 }
+00253 #endif /* 0 */
+00254 /*-----------------------------------------------------------------------------------*/
+00255 /**
+00256  * ARP processing for incoming ARP packets.
+00257  *
+00258  * This function should be called by the device driver when an ARP
+00259  * packet has been received. The function will act differently
+00260  * depending on the ARP packet type: if it is a reply for a request
+00261  * that we previously sent out, the ARP cache will be filled in with
+00262  * the values from the ARP reply. If the incoming ARP packet is an ARP
+00263  * request for our IP address, an ARP reply packet is created and put
+00264  * into the uip_buf[] buffer.
+00265  *
+00266  * When the function returns, the value of the global variable uip_len
+00267  * indicates whether the device driver should send out a packet or
+00268  * not. If uip_len is zero, no packet should be sent. If uip_len is
+00269  * non-zero, it contains the length of the outbound packet that is
+00270  * present in the uip_buf[] buffer.
+00271  *
+00272  * This function expects an ARP packet with a prepended Ethernet
+00273  * header in the uip_buf[] buffer, and the length of the packet in the
+00274  * global variable uip_len.
+00275  */
+00276 /*-----------------------------------------------------------------------------------*/
+00277 void
+00278 uip_arp_arpin(void)
+00279 {
+00280   
+00281   if(uip_len < sizeof(struct arp_hdr)) {
+00282     uip_len = 0;
+00283     return;
+00284   }
+00285   uip_len = 0;
+00286   
+00287   switch(BUF->opcode) {
+00288   case HTONS(ARP_REQUEST):
+00289     /* ARP request. If it asked for our address, we send out a
+00290        reply. */
+00291     if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
+00292       /* First, we register the one who made the request in our ARP
+00293          table, since it is likely that we will do more communication
+00294          with this host in the future. */
+00295       uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
+00296       
+00297       /* The reply opcode is 2. */
+00298       BUF->opcode = HTONS(2);
+00299 
+00300       memcpy(BUF->dhwaddr.addr, BUF->shwaddr.addr, 6);
+00301       memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
+00302       memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+00303       memcpy(BUF->ethhdr.dest.addr, BUF->dhwaddr.addr, 6);
+00304       
+00305       BUF->dipaddr[0] = BUF->sipaddr[0];
+00306       BUF->dipaddr[1] = BUF->sipaddr[1];
+00307       BUF->sipaddr[0] = uip_hostaddr[0];
+00308       BUF->sipaddr[1] = uip_hostaddr[1];
+00309 
+00310       BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
+00311       uip_len = sizeof(struct arp_hdr);
+00312     }
+00313     break;
+00314   case HTONS(ARP_REPLY):
+00315     /* ARP reply. We insert or update the ARP table if it was meant
+00316        for us. */
+00317     if(uip_ipaddr_cmp(BUF->dipaddr, uip_hostaddr)) {
+00318       uip_arp_update(BUF->sipaddr, &BUF->shwaddr);
+00319     }
+00320     break;
+00321   }
+00322 
+00323   return;
+00324 }
+00325 /*-----------------------------------------------------------------------------------*/
+00326 /**
+00327  * Prepend Ethernet header to an outbound IP packet and see if we need
+00328  * to send out an ARP request.
+00329  *
+00330  * This function should be called before sending out an IP packet. The
+00331  * function checks the destination IP address of the IP packet to see
+00332  * what Ethernet MAC address that should be used as a destination MAC
+00333  * address on the Ethernet.
+00334  *
+00335  * If the destination IP address is in the local network (determined
+00336  * by logical ANDing of netmask and our IP address), the function
+00337  * checks the ARP cache to see if an entry for the destination IP
+00338  * address is found. If so, an Ethernet header is prepended and the
+00339  * function returns. If no ARP cache entry is found for the
+00340  * destination IP address, the packet in the uip_buf[] is replaced by
+00341  * an ARP request packet for the IP address. The IP packet is dropped
+00342  * and it is assumed that they higher level protocols (e.g., TCP)
+00343  * eventually will retransmit the dropped packet.
+00344  *
+00345  * If the destination IP address is not on the local network, the IP
+00346  * address of the default router is used instead.
+00347  *
+00348  * When the function returns, a packet is present in the uip_buf[]
+00349  * buffer, and the length of the packet is in the global variable
+00350  * uip_len.
+00351  */
+00352 /*-----------------------------------------------------------------------------------*/
+00353 void
+00354 uip_arp_out(void)
+00355 {
+00356   struct arp_entry *tabptr;
+00357   
+00358   /* Find the destination IP address in the ARP table and construct
+00359      the Ethernet header. If the destination IP addres isn't on the
+00360      local network, we use the default router's IP address instead.
+00361 
+00362      If not ARP table entry is found, we overwrite the original IP
+00363      packet with an ARP request for the IP address. */
+00364 
+00365   /* First check if destination is a local broadcast. */
+00366   if(uip_ipaddr_cmp(IPBUF->destipaddr, broadcast_ipaddr)) {
+00367     memcpy(IPBUF->ethhdr.dest.addr, broadcast_ethaddr.addr, 6);
+00368   } else {
+00369     /* Check if the destination address is on the local network. */
+00370     if(!uip_ipaddr_maskcmp(IPBUF->destipaddr, uip_hostaddr, uip_netmask)) {
+00371       /* Destination address was not on the local network, so we need to
+00372          use the default router's IP address instead of the destination
+00373          address when determining the MAC address. */
+00374       uip_ipaddr_copy(ipaddr, uip_draddr);
+00375     } else {
+00376       /* Else, we use the destination IP address. */
+00377       uip_ipaddr_copy(ipaddr, IPBUF->destipaddr);
+00378     }
+00379       
+00380     for(i = 0; i < UIP_ARPTAB_SIZE; ++i) {
+00381       tabptr = &arp_table[i];
+00382       if(uip_ipaddr_cmp(ipaddr, tabptr->ipaddr)) {
+00383         break;
+00384       }
+00385     }
+00386 
+00387     if(i == UIP_ARPTAB_SIZE) {
+00388       /* The destination address was not in our ARP table, so we
+00389          overwrite the IP packet with an ARP request. */
+00390 
+00391       memset(BUF->ethhdr.dest.addr, 0xff, 6);
+00392       memset(BUF->dhwaddr.addr, 0x00, 6);
+00393       memcpy(BUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+00394       memcpy(BUF->shwaddr.addr, uip_ethaddr.addr, 6);
+00395     
+00396       uip_ipaddr_copy(BUF->dipaddr, ipaddr);
+00397       uip_ipaddr_copy(BUF->sipaddr, uip_hostaddr);
+00398       BUF->opcode = HTONS(ARP_REQUEST); /* ARP request. */
+00399       BUF->hwtype = HTONS(ARP_HWTYPE_ETH);
+00400       BUF->protocol = HTONS(UIP_ETHTYPE_IP);
+00401       BUF->hwlen = 6;
+00402       BUF->protolen = 4;
+00403       BUF->ethhdr.type = HTONS(UIP_ETHTYPE_ARP);
+00404 
+00405       uip_appdata = &uip_buf[UIP_TCPIP_HLEN + UIP_LLH_LEN];
+00406     
+00407       uip_len = sizeof(struct arp_hdr);
+00408       return;
+00409     }
+00410 
+00411     /* Build an ethernet header. */
+00412     memcpy(IPBUF->ethhdr.dest.addr, tabptr->ethaddr.addr, 6);
+00413   }
+00414   memcpy(IPBUF->ethhdr.src.addr, uip_ethaddr.addr, 6);
+00415   
+00416   IPBUF->ethhdr.type = HTONS(UIP_ETHTYPE_IP);
+00417 
+00418   uip_len += sizeof(struct uip_eth_hdr);
+00419 }
+00420 /*-----------------------------------------------------------------------------------*/
+00421 
+00422 /** @} */
+00423 /** @} */
+

Generated on Mon Jun 12 10:23:01 2006 for uIP 1.0 by  + +doxygen 1.4.6
+ + -- cgit v1.3.1