Example #1
0
err_t
jif_init(struct netif *netif)
{
    struct jif *jif;
    envid_t *output_envid; 

    jif = (struct jif *) mem_malloc(sizeof(struct jif));

    if (jif == NULL) {
	LWIP_DEBUGF(NETIF_DEBUG, ("jif_init: out of memory\n"));
	return ERR_MEM;
    }

    output_envid = (envid_t *)netif->state;

    netif->state = jif;
    netif->output = jif_output;
    netif->linkoutput = low_level_output;
    memcpy(&netif->name[0], "en", 2);

    jif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);
    jif->envid = *output_envid; 

    low_level_init(netif);

    etharp_init();

    // qemu user-net is dumb; if the host OS does not send and ARP request
    // first, the qemu will send packets destined for the host using the mac
    // addr 00:00:00:00:00; do a arp request for the user-net NAT at 10.0.2.2
    uint32_t ipaddr = inet_addr("10.0.2.2");
    etharp_query(netif, (struct ip_addr *) &ipaddr, 0);

    return ERR_OK;
}
Example #2
0
/**
 * Bring an interface up, available for processing
 * traffic.
 *
 * @note: Enabling DHCP on a down interface will make it come
 * up once configured.
 *
 * @see dhcp_start()
 */
void netif_set_up(struct netif *netif)
{
  if ( !(netif->flags & NETIF_FLAG_UP )) {
    netif->flags |= NETIF_FLAG_UP;

#if LWIP_SNMP
    snmp_get_sysuptime(&netif->ts);
#endif /* LWIP_SNMP */

    NETIF_LINK_CALLBACK(netif);
    NETIF_STATUS_CALLBACK(netif);

#if LWIP_ARP_GRATUITOUS
    /** For Ethernet network interfaces, we would like to send a
     *  "gratuitous ARP"; this is an ARP packet sent by a node in order
     *  to spontaneously cause other nodes to update an entry in their
     *  ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.
     */
    if (netif->flags & NETIF_FLAG_ETHARP) {
      etharp_query(netif, &(netif->ip_addr), NULL);
    }
#endif /* LWIP_ARP */

  }
}
Example #3
0
void
netif_set_ipaddr(struct netif *netif, struct ip_addr *ipaddr)
{
  /* TODO: Handling of obsolete pcbs */
  /* See:  http://mail.gnu.org/archive/html/lwip-users/2003-03/msg00118.html */
#if LWIP_TCP
  struct tcp_pcb *pcb;
  struct tcp_pcb_listen *lpcb;

  /* address is actually being changed? */
  if ((ip_addr_cmp(ipaddr, &(netif->ip_addr))) == 0)
  {
    /* extern struct tcp_pcb *tcp_active_pcbs; defined by tcp.h */
    LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: netif address being changed\n"));
    pcb = tcp_active_pcbs;
    while (pcb != NULL) {
      /* PCB bound to current local interface address? */
      if (ip_addr_cmp(&(pcb->local_ip), &(netif->ip_addr))) {
        /* this connection must be aborted */
        struct tcp_pcb *next = pcb->next;
        LWIP_DEBUGF(NETIF_DEBUG | 1, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb));
        tcp_abort(pcb);
        pcb = next;
      } else {
        pcb = pcb->next;
      }
    }
    for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) {
      /* PCB bound to current local interface address? */
      if (ip_addr_cmp(&(lpcb->local_ip), &(netif->ip_addr))) {
        /* The PCB is listening to the old ipaddr and
         * is set to listen to the new one instead */
        ip_addr_set(&(lpcb->local_ip), ipaddr);
      }
    }
  }
#endif
  snmp_delete_ipaddridx_tree(netif);
  snmp_delete_iprteidx_tree(0,netif);
  /* set new IP address to netif */
  ip_addr_set(&(netif->ip_addr), ipaddr);
  snmp_insert_ipaddridx_tree(netif);
  snmp_insert_iprteidx_tree(0,netif);

#if 0 /* only allowed for Ethernet interfaces TODO: how can we check? */
  /** For Ethernet network interfaces, we would like to send a
   *  "gratuitous ARP"; this is an ARP packet sent by a node in order
   *  to spontaneously cause other nodes to update an entry in their
   *  ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.
   */ 
  etharp_query(netif, ipaddr, NULL);
#endif
  LWIP_DEBUGF(NETIF_DEBUG | DBG_TRACE | DBG_STATE | 3, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
    netif->name[0], netif->name[1],
    ip4_addr1(&netif->ip_addr),
    ip4_addr2(&netif->ip_addr),
    ip4_addr3(&netif->ip_addr),
    ip4_addr4(&netif->ip_addr)));
}
Example #4
0
int
netx_send_to(
    struct netxsocket_s *rlpsock,
    const netx_addr_t *destaddr,
    uint8_t *data,
    size_t datalen
)
{
    struct pbuf     *pkt;  /* Outgoing packet */
    struct eth_addr *ethaddr_ret;
    struct ip_addr  *ipaddr_ret;
    int              result;
    int              t_begin;
    struct ip_addr   dest_addr;
    ip4addr_t        addr;
    int              arp_index;

    if (!rlpsock || !rlpsock->nativesock)
        return -1;

    /* struct ip_addr *ipaddr, */
    addr = NETI_INADDR(destaddr);
    dest_addr.addr = addr;

    if (!is_multicast(addr)) {
        /* We have the arp queue turned off, so we need to make sure we have a ARP entry  */
        /* else it will fail on first try */
        result = -1;
        arp_index = etharp_find_addr(netxf_default, &dest_addr, &ethaddr_ret, &ipaddr_ret);
        if (arp_index < 0) {
            result = etharp_query(netxf_default, &dest_addr, NULL);
            if (result == ERR_OK) {
                result = -1;
                t_begin = sys_jiffies();
                /* wait 2 seconds (ARP TIMEOUT)*/
                while ((unsigned int)sys_jiffies() - t_begin < 2000) {
                    arp_index = etharp_find_addr(netxf_default, &dest_addr, &ethaddr_ret, &ipaddr_ret);
                    if (arp_index >= 0) {
                        result = 0;
                        break;
                    }
                }
            } else {
                acnlog(LOG_WARNING | LOG_NETI, "netx_send_to : ARP query failure");
                return -1;
            }
        } else
            result = 0;

        if (result != 0) {
            acnlog(LOG_WARNING | LOG_NETI, "netx_send_to : ARP failure: %d.%d.%d.%d",
                   ntohl(addr) >> 24 & 0x000000ff,
                   ntohl(addr) >> 16 & 0x000000ff,
                   ntohl(addr) >> 8 & 0x000000ff,
                   ntohl(addr) & 0x000000ff);
            return result;
        }
Example #5
0
File: network.c Project: gz/aos10
void
network_init(void)
{
    printf("\nStarting %s\n", __FUNCTION__);

    // Initialise the nslu2 hardware
    ixOsalOemInit(); 

    /* Initialise lwIP */
    mem_init();
    memp_init();
    pbuf_init();
    netif_init();
    udp_init();
    etharp_init();

    /* Setup the network interface */
    struct ip_addr netmask, ipaddr, gw;
    IP4_ADDR(&netmask, 255, 255, 255, 0);	// Standard net mask
    IP4_ADDR(&gw,      192, 168, 0, 1);		// Your host system
    IP4_ADDR(&ipaddr,  192, 168, 0, 2);		// The Slug's IP address

    struct netif *netif = netif_add(&ipaddr,&netmask,&gw, sosIfInit, ip_input);
    netif_set_default(netif);

    // Generate an arp entry for our gateway
    // We should only need to do this once, but Linux seems to love ignoring
    // ARP queries (why??!), so we keep trying until we get a response
    struct pbuf *p = etharp_query(netif, &netif->gw, NULL);
    do {
        (*netif_default->linkoutput)(netif, p);	// Direct output
        sos_usleep(100000);	// Wait a while for a reply
    } while (!etharp_entry_present(&netif->gw));
    pbuf_free(p);

    // Finish the initialisation of the nslu2 hardware
    ixOsalOSServicesFinaliseInit();


    /* Initialise NFS */
    int r = nfs_init(gw); assert(!r);

    mnt_get_export_list();	// Print out the exports on this server

    const char *msg;
    if (mnt_mount(NFS_DIR, &mnt_point))		// Mount aos_nfs
	msg = "%s: Error mounting path '%s'!\n";
    else
	msg = "Successfully mounted '%s'\n";
    printf(msg, __FUNCTION__, NFS_DIR);

    printf("Finished %s\n\n", __FUNCTION__);
}
Example #6
0
// checks if the offered address is already in use
// it does so by sending an ARP query
static void dhcp_check(struct dhcp_state *state)
{
  struct pbuf *p;
  err_t result;
  u16_t msecs;
  DEBUGF(DHCP_DEBUG, ("dhcp_check()\n"));
  p = etharp_query(state->netif, &state->offered_ip_addr, NULL);
  if(p != NULL)
  {
    DEBUGF(DHCP_DEBUG, ("dhcp_check(): sending ARP request len %u\n", p->tot_len));
    result = state->netif->linkoutput(state->netif, p);
    pbuf_free(p);

    //return /*result*/;
  }
  state->tries++;
  msecs = state->tries * 1000;
  state->request_timeout = (msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS;
  DEBUGF(DHCP_DEBUG, ("dhcp_check(): request timeout %u msecs\n", msecs));
  dhcp_set_state(state, DHCP_CHECKING);
}
Example #7
0
/**
 * Called by a driver when its link goes up
 */
void netif_set_link_up(struct netif *netif )
{
  netif->flags |= NETIF_FLAG_LINK_UP;

#if LWIP_ARP
  /** For Ethernet network interfaces, we would like to send a
   *  "gratuitous ARP"; this is an ARP packet sent by a node in order
   *  to spontaneously cause other nodes to update an entry in their
   *  ARP cache. From RFC 3220 "IP Mobility Support for IPv4" section 4.6.
   */
  if (netif->flags & NETIF_FLAG_ETHARP) {
    etharp_query(netif, &(netif->ip_addr), NULL);
  }
#endif /* LWIP_ARP */

#if LWIP_IGMP
  /* resend IGMP memberships */
  if (netif->flags & NETIF_FLAG_IGMP) {
    igmp_report_groups( netif);
  }
#endif /* LWIP_IGMP */

  NETIF_LINK_CALLBACK(netif);
}
/**
 * Resolve and fill-in Ethernet address header for outgoing packet.
 *
 * For IP multicast and broadcast, corresponding Ethernet addresses
 * are selected and the packet is transmitted on the link.
 *
 * For unicast addresses, the packet is submitted to etharp_query(). In
 * case the IP address is outside the local network, the IP address of
 * the gateway is used.
 *
 * @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
 * - ERR_RTE No route to destination (no gateway to external networks),
 * or the return type of either etharp_query() or netif->linkoutput().
 */
err_t
etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
{
  struct eth_addr *dest, *srcaddr, mcastaddr;
  struct eth_hdr *ethhdr;
  u8_t i;

  /* 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. */

  /* broadcast destination IP address? */
  if (ip_addr_isbroadcast(ipaddr, netif)) {
    /* broadcast on Ethernet also */
    dest = (struct eth_addr *)&ethbroadcast;
  /* multicast destination IP 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;
  /* unicast destination IP address? */
  } else {
    /* outside local network? */
    if (!ip_addr_netcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
      /* 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 (default gateway missing) */
        return ERR_RTE;
      }
    }
    /* queue on destination Ethernet address belonging to ipaddr */
    return etharp_query(netif, ipaddr, q);
  }

  /* continuation for multicast/broadcast destinations */
  /* obtain source Ethernet address of the given interface */
  srcaddr = (struct eth_addr *)netif->hwaddr;
  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 directly on the link */
  return netif->linkoutput(netif, q);
}
Example #9
0
/** 
 * 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 and a ARP request is sent (on a best-effort basis). This
 * ARP request is returned as a pbuf, which should be sent by the
 * caller.
 *
 * If ARP failed to allocate resources, NULL is returned.
 *
 * A returned non-NULL packet should be sent by the caller.
 *
 * @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. 
 */
struct pbuf *
etharp_output(struct netif *netif, struct ip_addr *ipaddr, struct pbuf *q)
{
  struct eth_addr *dest, *srcaddr, mcastaddr;
  struct eth_hdr *ethhdr;
  u8_t i;

  /* Make room for Ethernet header. */
  if (pbuf_header(q, sizeof(struct eth_hdr)) != 0) {    
    /* The pbuf_header() call shouldn't fail, and we'll just bail
    out if it does.. */
    DEBUGF(ETHARP_DEBUG | DBG_TRACE | 2, ("etharp_output: could not allocate room for header.\n"));
#ifdef LINK_STATS
    ++lwip_stats.link.lenerr;
#endif /* LINK_STATS */
    return NULL;
  }

  /* obtain source Ethernet address of the given interface */
  srcaddr = (struct eth_addr *)netif->hwaddr;

  /* assume unresolved Ethernet address */
  dest = NULL;
  /* Construct Ethernet header. Start with looking up deciding which
  MAC address to use as a destination address. Broadcasts and
  multicasts are special, all other 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->netmask))) {
    /* 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] = 0x0;
    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 {
    /* destination IP network address not on local network? */
    /* this occurs if the packet is routed to the default gateway on this interface */
    if (!ip_addr_maskcmp(ipaddr, &(netif->ip_addr), &(netif->netmask))) {
      /* gateway available? */
      if (netif->gw.addr != 0)
      {
        /* use the gateway IP address */
        ipaddr = &(netif->gw);
      }
      /* no gateway available? */
      else
      {
        /* IP destination address outside local network, but no gateway available */
        return NULL;
      }
    }

    /* Ethernet address for IP destination address is in ARP cache? */
    for(i = 0; i < ARP_TABLE_SIZE; ++i) {
      /* match found? */    
      if (arp_table[i].state == ETHARP_STATE_STABLE &&
        ip_addr_cmp(ipaddr, &arp_table[i].ipaddr)) {
        dest = &arp_table[i].ethaddr;
        break;
      }
    }
    /* could not find the destination Ethernet address in ARP cache? */
    if (dest == NULL) {
      /* ARP query for the IP address, submit this IP packet for queueing */
      etharp_query(netif, ipaddr, q);
      /* return nothing */
      return NULL;
    }
    /* destination Ethernet address resolved from ARP cache */
    else
    {
      /* fallthrough */
    }
  }

  /* destination Ethernet address known */
  if (dest != NULL) {
    /* A valid IP->MAC address mapping was found, so we construct 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);
    /* return the outgoing packet */
    return q;
  }
  /* never reached; here for safety */ 
  return NULL;
}
/**
 * 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;
}