Ejemplo n.º 1
0
/** \brief return true is the ip_addr is public (aka not local and not private not linklocal)
 */
bool ip_addr_t::is_public() const throw()
{
	if( is_null() )			return false;
	if( !is_fully_qualified() )	return false;
	if( is_private() )		return false;
	if( is_localhost() )		return false;	
	if( is_linklocal() )		return false;
	return true;
}
/**
 * Resolve and fill-in Ethernet address header for outgoing packet.
 *
 * If ARP has the Ethernet address in cache, the given packet is
 * returned, ready to be sent.
 *
 * If ARP does not have the Ethernet address in cache the packet is
 * queued (if enabled and space available) and a ARP request is sent.
 * This ARP request is returned as a pbuf, which should be sent by
 * the caller.
 *
 * A returned non-NULL packet should be sent by the caller.
 *
 * If ARP failed to allocate resources, NULL is returned.
 *
 * @param netif The lwIP network interface which the IP packet will be sent on.
 * @param ipaddr The IP address of the packet destination.
 * @param pbuf The pbuf(s) containing the IP packet to be sent.
 *
 * @return If non-NULL, a packet ready to be sent by caller.
 *
 * @return
 * - ERR_BUF Could not make room for Ethernet header.
 * - ERR_MEM Hardware address unknown, and no more ARP entries available
 *   to query for address or queue the packet.
 * - ERR_RTE No route to destination (no gateway to external networks).
 */
err_t
etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
{
  struct eth_addr *dest, *srcaddr, mcastaddr;
  struct eth_hdr *ethhdr;
  err_t result = ERR_OK;
  struct ip_hdr *iphdr;  //615wu
	
  iphdr = q->payload;	//615wu	
	
  /* make room for Ethernet header - should not fail */
  if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {
    /* bail out */
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
    LINK_STATS_INC(link.lenerr);
    return ERR_BUF;
  }

  /* assume unresolved Ethernet address */
  dest = NULL;
  /* Determine on destination hardware address. Broadcasts and multicasts
   * are special, other IP addresses are looked up in the ARP table. */
	
  /* destination IP address is an IP broadcast address? */
  if (ip_addr_isany(ipaddr) || ip_addr_isbroadcast(ipaddr, netif)) {
    /* broadcast on Ethernet also */
    dest = (struct eth_addr *)&ethbroadcast;
  /* destination IP address is an IP multicast address? */
  } else if (ip_addr_ismulticast(ipaddr)) {
    /* Hash IP multicast address to MAC address. */
    mcastaddr.addr[0] = 0x01;
    mcastaddr.addr[1] = 0x00;
    mcastaddr.addr[2] = 0x5e;
    mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f;
    mcastaddr.addr[4] = ip4_addr3(ipaddr);
    mcastaddr.addr[5] = ip4_addr4(ipaddr);
    /* destination Ethernet address is multicast */
    dest = &mcastaddr;
  /* destination IP address is an IP unicast address */
  } else {
    /* outside local network? */
    if (!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))  
#if 0	//ZOT716u2
#ifdef O_AXIS 
      /* Open TCP/IP layer hole */
        &&  ( !TCP_HOLE_FLAG || ( IPH_PROTO(iphdr) == IP_PROTO_UDP ) )//615wu 
#endif//O_AXIS      
#endif	//ZOT716u2  
#ifdef RENDEZVOUS
		&&  (!mRENVEnable || ( !ip_addr_ismulticast(&(iphdr->dest)) && !is_linklocal((iphdr->dest))) )
#endif//RENDEZVOUS
      ) {
      /* interface has default gateway? */
      if (netif->gw.addr != 0) {
        /* send to hardware address of default gateway IP address */
        ipaddr = &(netif->gw);
      /* no default gateway available */
      } else {
        /* no route to destination error */
        return ERR_RTE;
      }
    }
    /* queue on destination Ethernet address belonging to ipaddr */
    return etharp_query(netif, ipaddr, q);
  }

  /* destination Ethernet address known */
  if (dest != NULL) {
    u8_t i;
    /* obtain source Ethernet address of the given interface */
    srcaddr = (struct eth_addr *)netif->hwaddr;
    /* A valid IP->MAC address mapping was found, fill in the
     * Ethernet header for the outgoing packet */
    ethhdr = q->payload;
    for (i = 0; i < netif->hwaddr_len; i++) {
      ethhdr->dest.addr[i] = dest->addr[i];
      ethhdr->src.addr[i] = srcaddr->addr[i];
    }
    ethhdr->type = htons(ETHTYPE_IP);
    /* send packet */
    result = netif->linkoutput(netif, q);
  }
  return result;
}