void
etharp_ip_input(struct netif *netif, struct pbuf *p)
{
  struct ethip_hdr *hdr;

  /* Only insert an entry if the source IP address of the
     incoming IP packet comes from a host on the local network. */
  hdr = p->payload;
  /* source is on local network? */
//Receive another network IP packet. 
#if 0 //20090224
  if (!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask)) 
#if 0	//ZOT716u2
#ifdef O_AXIS
    /* Open TCP/IP layer hole */
  	   && !TCP_HOLE_FLAG //615wu
#endif// O_AXIS 
#endif	//ZOT716u2
#ifdef RENDEZVOUS
		&& !mRENVEnable
#endif//RENDEZVOUS
  	) {
    /* do nothing */
    return;
  }
#endif //0 //20090224

  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
  /* update ARP table, ask to insert entry */
  update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), ETHARP_CREATE);
}
예제 #2
0
파일: etharp.c 프로젝트: kissthink/LikeOS
/*-----------------------------------------------------------------------------------*/
struct pbuf *
etharp_ip_input(struct netif *netif, struct pbuf *p)
{
    struct ethip_hdr *hdr;

    hdr = p->payload;

    /* Only insert/update an entry if the source IP address of the
       incoming IP packet comes from a host on the local network. */
    if(!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
        return NULL;
    }
    if(ip_addr_isbroadcast(&(hdr->ip.src), &(netif->netmask))) {
        return NULL;
    }
    DEBUGF(ETHARP_DEBUG, ("etharp_ip_input: updating ETHARP table.\n"));
    if (ip_addr_isbroadcast(&(hdr->ip.dest), &(netif->netmask)))
        return update_arp_entry(&(hdr->ip.src), &(hdr->eth.src), 0);
    else
        return update_arp_entry(&(hdr->ip.src), &(hdr->eth.src), 1);
}
예제 #3
0
파일: etharp.c 프로젝트: CNCBASHER/gcc4mbed
/** Add a new static entry to the ARP table. If an entry exists for the
 * specified IP address, this entry is overwritten.
 * If packets are queued for the specified IP address, they are sent out.
 *
 * @param ipaddr IP address for the new static entry
 * @param ethaddr ethernet address for the new static entry
 * @return @see return values of etharp_add_static_entry
 */
err_t
etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr)
{
  struct netif *netif;
  LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
    ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
    ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
    ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));

  netif = ip_route(ipaddr);
  if (netif == NULL) {
    return ERR_RTE;
  }

  return update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
}
예제 #4
0
/**
 * Updates the ARP table using the given packet.
 *
 * Uses the incoming IP packet's source address to update the
 * ARP cache for the local network. The function does not alter
 * or free the packet. This function must be called before the
 * packet p is passed to the IP layer.
 *
 * @param netif The lwIP network interface on which the IP packet pbuf arrived.
 * @param pbuf The IP packet that arrived on netif.
 * 
 * @return NULL
 *
 * @see pbuf_free()
 */
struct pbuf *
etharp_ip_input(struct netif *netif, struct pbuf *p)
{
  struct ethip_hdr *hdr;
  
  /* Only insert an entry if the source IP address of the
     incoming IP packet comes from a host on the local network. */
  hdr = p->payload;
  /* source is on local network? */
  if (!ip_addr_maskcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
    /* do nothing */
    return NULL;
  }
  
  DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
  /* update ARP table, ask to insert entry */
  update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), ARP_INSERT_FLAG);
  return NULL;
}
/**
 * Updates the ARP table using the given IP packet.
 *
 * Uses the incoming IP packet's source address to update the
 * ARP cache for the local network. The function does not alter
 * or free the packet. This function must be called before the
 * packet p is passed to the IP layer.
 *
 * @param netif The lwIP network interface on which the IP packet pbuf arrived.
 * @param pbuf The IP packet that arrived on netif.
 *
 * @return NULL
 *
 * @see pbuf_free()
 */
void
etharp_ip_input(struct netif *netif, struct pbuf *p)
{
  struct ethip_hdr *hdr;
  LWIP_ASSERT("netif != NULL", netif != NULL);
  /* Only insert an entry if the source IP address of the
     incoming IP packet comes from a host on the local network. */
  hdr = p->payload;
  /* source is not on the local network? */
  if (!ip_addr_netcmp(&(hdr->ip.src), &(netif->ip_addr), &(netif->netmask))) {
    /* do nothing */
    return;
  }

  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip_input: updating ETHARP table.\n"));
  /* update ARP table */
  /* @todo We could use ETHARP_TRY_HARD if we think we are going to talk
   * back soon (for example, if the destination IP address is ours. */
  update_arp_entry(netif, &(hdr->ip.src), &(hdr->eth.src), 0);
}
예제 #6
0
/**
 * Updates the ARP table using the given IP packet.
 *
 * Uses the incoming IP packet's source address to update the
 * ARP cache for the local network. The function does not alter
 * or free the packet. This function must be called before the
 * packet p is passed to the IP layer.
 *
 * @param netif The lwIP network interface on which the IP packet pbuf arrived.
 * @param pbuf The IP packet that arrived on netif.
 *
 * @return NULL
 *
 * @see pbuf_free()
 */
static void
etharp_ip4_input(struct netif *netif, struct pbuf *p)
{
  struct ethip4_hdr *hdr;
  struct ip_addr src4;

  /* Only insert an entry if the source IP address of the
     incoming IP packet comes from a host on the local network. */
  hdr = p->payload;
  IP64_CONV(&src4,&(hdr->ip.src));
  if (!ip_addr_list_maskfind(netif->addrs, &(src4))) {
    /* do nothing */
    return;
  }

  LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_ip4_input: updating ETHARP table.\n"));
  /* update ARP table, ask to insert entry */
  update_arp_entry(netif, &(src4), &(hdr->eth.src), ARP_INSERT_FLAG);
  return;
}
예제 #7
0
파일: pcnet.c 프로젝트: juur/FailOS
void handle_frame(struct eth_dev *e, struct net_dev *nd,
                  struct pcnet_rx_32 *f)
{
    //int i;
    uint8 *b = (uint8 *)(0L + f->RBADR);
    struct eth_frame *tmp;
    struct ip_hdr *iph;

    /*
       printf("handle_frame:\n"
       "ENP:%x STP:%x BUFF:%x CRC:%x OFLO:%x FRAM:%x\n"
       "ERR:%x OWN:%x BCNT:%x MCNT:%x\n",
       f->ENP, f->STP, f->BUFF, f->CRC, f->OFLO, f->FRAM,
       f->ERR, f->OWN, f->BCNT, f->MCNT);
       */

    tmp = kmalloc(f->BCNT, "eth_frame", NULL);
    memcpy(tmp, b, f->BCNT);
    tmp->len = ntohs(tmp->len);
    //	printf("src: ");
    //	print_mac(tmp->src);
    //	printf(" dst: ");
    //	print_mac(tmp->dst),
    //	printf(" len: %lx\n", tmp->len);
    //	printf("nd->upper: %x\n", nd->upper);

    switch(tmp->len)
    {
    case ETHPROTO_IP:
        iph = (struct ip_hdr *)&tmp->data;
        update_arp_entry( ntohl(iph->src), tmp->src, nd );
        break;
    case ETHPROTO_ARP:
        arp_handle(nd, (uint8 *)&tmp->data, f->MCNT-(6+6+2));
        break;
    }

    nd->upper->ops->recv(nd, nd->upper, (uint8 *)&tmp->data, f->MCNT-(6+6+2));
    kfree(tmp);
}
예제 #8
0
/**
 * Update (or insert) a IP/MAC address pair in the ARP cache.
 *
 * If a pending entry is resolved, any queued packets will be sent
 * at this point.
 *
 * @param netif netif related to this entry (used for NETIF_ADDRHINT)
 * @param ipaddr IP address of the inserted ARP entry.
 * @param ethaddr Ethernet address of the inserted ARP entry.
 * @param flags @see definition of ETHARP_FLAG_*
 *
 * @return
 * - ERR_OK Succesfully updated ARP cache.
 * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set.
 * - ERR_ARG Non-unicast address given, those will not appear in ARP cache.
 *
 * @see pbuf_free()
 */
static err_t
update_arp_entry(struct netif *netif, ip_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags)
{
	s8_t i;
	LWIP_ASSERT("netif->hwaddr_len == ETHARP_HWADDR_LEN", netif->hwaddr_len == ETHARP_HWADDR_LEN);
	LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
				ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
				ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
				ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));
	/* non-unicast address? */
	if (ip_addr_isany(ipaddr) ||
		ip_addr_isbroadcast(ipaddr, netif) ||
		ip_addr_ismulticast(ipaddr)) {
		LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: will not add non-unicast IP address to ARP cache\n"));
		return ERR_ARG;
	}
	/* find or create ARP entry */
	i = find_entry(ipaddr, flags);
	/* bail out if no entry could be found */
	if (i < 0) {
		return (err_t)i;
	}

#if ETHARP_SUPPORT_STATIC_ENTRIES
	if (flags & ETHARP_FLAG_STATIC_ENTRY) {
		/* record static type */
		arp_table[i].static_entry = 1;
	}
#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */

	/* mark it stable */
	arp_table[i].state = ETHARP_STATE_STABLE;

#if LWIP_SNMP
	/* record network interface */
	arp_table[i].netif = netif;
#endif /* LWIP_SNMP */
	/* insert in SNMP ARP index tree */
	snmp_insert_arpidx_tree(netif, &arp_table[i].ipaddr);

	LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i));
	/* update address */
	ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr);
	/* reset time stamp */
	arp_table[i].ctime = 0;
	/* this is where we will send out queued packets! */
#if ARP_QUEUEING
	while (arp_table[i].q != NULL) {
		struct pbuf *p;
		/* remember remainder of queue */
		struct etharp_q_entry *q = arp_table[i].q;
		/* pop first item off the queue */
		arp_table[i].q = q->next;
		/* get the packet pointer */
		p = q->p;
		/* now queue entry can be freed */
		memp_free(MEMP_ARP_QUEUE, q);
#else /* ARP_QUEUEING */
	if (arp_table[i].q != NULL) {
		struct pbuf *p = arp_table[i].q;
		arp_table[i].q = NULL;
#endif /* ARP_QUEUEING */
		/* send the queued IP packet */
		etharp_send_ip(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr);
		/* free the queued IP packet */
		pbuf_free(p);
	}
	return ERR_OK;
}

#if ETHARP_SUPPORT_STATIC_ENTRIES
/** Add a new static entry to the ARP table. If an entry exists for the
 * specified IP address, this entry is overwritten.
 * If packets are queued for the specified IP address, they are sent out.
 *
 * @param ipaddr IP address for the new static entry
 * @param ethaddr ethernet address for the new static entry
 * @return @see return values of etharp_add_static_entry
 */
err_t
etharp_add_static_entry(ip_addr_t *ipaddr, struct eth_addr *ethaddr)
{
	struct netif *netif;
	LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n",
				ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr),
				ethaddr->addr[0], ethaddr->addr[1], ethaddr->addr[2],
				ethaddr->addr[3], ethaddr->addr[4], ethaddr->addr[5]));

	netif = ip_route(ipaddr);
	if (netif == NULL) {
		return ERR_RTE;
	}

	return update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY);
}

/** Remove a static entry from the ARP table previously added with a call to
 * etharp_add_static_entry.
 *
 * @param ipaddr IP address of the static entry to remove
 * @return ERR_OK: entry removed
 *         ERR_MEM: entry wasn't found
 *         ERR_ARG: entry wasn't a static entry but a dynamic one
 */
err_t
etharp_remove_static_entry(ip_addr_t *ipaddr)
{
	s8_t i;
	LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n",
				ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr)));

	/* find or create ARP entry */
	i = find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY);
	/* bail out if no entry could be found */
	if (i < 0) {
		return (err_t)i;
	}

	if ((arp_table[i].state != ETHARP_STATE_STABLE) ||
		(arp_table[i].static_entry == 0)) {
		/* entry wasn't a static entry, cannot remove it */
		return ERR_ARG;
	}
	/* entry found, free it */
	free_entry(i);
	return ERR_OK;
}
/**
 * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache  
 * send out queued IP packets. Updates cache with snooped address pairs.
 *
 * Should be called for incoming ARP packets. The pbuf in the argument
 * is freed by this function.
 *
 * @param netif The lwIP network interface on which the ARP packet pbuf arrived.
 * @param pbuf The ARP packet that arrived on netif. Is freed by this function.
 * @param ethaddr Ethernet address of netif.
 *
 * @return NULL
 *
 * @see pbuf_free()
 */
void
etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
{
  struct etharp_hdr *hdr;
  /* these are aligned properly, whereas the ARP header fields might not be */
  struct ip_addr sipaddr, dipaddr;
  u8_t i;
  u8_t for_us;

  LWIP_ASSERT("netif != NULL", netif != NULL);
  
  /* drop short ARP packets */
  if (p->tot_len < sizeof(struct etharp_hdr)) {
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%"S16_F"/%"S16_F")\n", p->tot_len, sizeof(struct etharp_hdr)));
    pbuf_free(p);
    return;
  }

  hdr = p->payload;
 
  /* get aligned copies of addresses */
  *(struct ip_addr2 *)&sipaddr = hdr->sipaddr;
  *(struct ip_addr2 *)&dipaddr = hdr->dipaddr;

  /* this interface is not configured? */
  if (netif->ip_addr.addr == 0) {
    for_us = 0;
  } else {
    /* ARP packet directed to us? */
    for_us = ip_addr_cmp(&dipaddr, &(netif->ip_addr));
  }

  /* ARP message directed to us? */
  if (for_us) {
    /* add IP address in ARP cache; assume requester wants to talk to us.
     * can result in directly sending the queued packets for this host. */
    update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), ETHARP_TRY_HARD);
  /* ARP message not directed to us? */
  } else {
    /* update the source IP address in the cache, if present */
    update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), 0);
  }

  /* now act on the message itself */
  switch (htons(hdr->opcode)) {
  /* ARP request? */
  case ARP_REQUEST:
    /* ARP request. If it asked for our address, we send out a
     * reply. In any case, we time-stamp any existing ARP entry,
     * and possiby send out an IP packet that was queued on it. */

    LWIP_DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
    /* ARP request for our address? */
    if (for_us) {

      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
      /* re-use pbuf to send ARP reply */
      hdr->opcode = htons(ARP_REPLY);

      hdr->dipaddr = hdr->sipaddr;
      hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;

      for(i = 0; i < netif->hwaddr_len; ++i) {
        hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
        hdr->shwaddr.addr[i] = ethaddr->addr[i];
        hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
        hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
      }

      hdr->hwtype = htons(HWTYPE_ETHERNET);
      ARPH_HWLEN_SET(hdr, netif->hwaddr_len);

      hdr->proto = htons(ETHTYPE_IP);
      ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));

      hdr->ethhdr.type = htons(ETHTYPE_ARP);
      /* return ARP reply */
      netif->linkoutput(netif, p);
    /* we are not configured? */
    } else if (netif->ip_addr.addr == 0) {
      /* { for_us == 0 and netif->ip_addr.addr == 0 } */
      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
    /* request was not directed to us */
    } else {
      /* { for_us == 0 and netif->ip_addr.addr != 0 } */
      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));
    }
    break;
  case ARP_REPLY:
    /* ARP reply. We already updated the ARP cache earlier. */
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
    /* DHCP wants to know about ARP replies from any host with an
     * IP address also offered to us by the DHCP server. We do not
     * want to take a duplicate IP address on a single network.
     * @todo How should we handle redundant (fail-over) interfaces?
     * */
    dhcp_arp_reply(netif, &sipaddr);
#endif
    break;
  default:
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %"S16_F"\n", htons(hdr->opcode)));
    break;
  }
  /* free ARP packet */
  pbuf_free(p);
}
예제 #10
0
파일: etharp.c 프로젝트: kissthink/LikeOS
/*-----------------------------------------------------------------------------------*/
struct pbuf *
etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p, struct pbuf **queued)
{
    struct etharp_hdr *hdr;
    u8_t i;

    if(p->tot_len < sizeof(struct etharp_hdr)) {
        DEBUGF(ETHARP_DEBUG, ("etharp_etharp_input: packet too short (%d/%d)\n", (int) p->tot_len, (int) sizeof(struct etharp_hdr)));
        return NULL;
    }

    hdr = p->payload;

    switch(htons(hdr->opcode)) {
    case ARP_REQUEST:
        *queued = update_arp_entry(&(hdr->sipaddr), &(hdr->shwaddr), 0);
        /* ARP request. If it asked for our address, we send out a
           reply. */
        DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: ARP request\n"));
        if(!memcmp(&(hdr->dipaddr), &(netif->ip_addr), sizeof (hdr->dipaddr))) {
            pbuf_ref(p);
            hdr->opcode = htons(ARP_REPLY);

            memcpy (&(hdr->dipaddr), &(hdr->sipaddr), sizeof (hdr->dipaddr));
            memcpy (&(hdr->sipaddr), &(netif->ip_addr), sizeof (hdr->sipaddr));

            for(i = 0; i < 6; ++i) {
                hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
                hdr->shwaddr.addr[i] = ethaddr->addr[i];
                hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
                hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
            }

            hdr->hwtype = htons(HWTYPE_ETHERNET);
            ARPH_HWLEN_SET(hdr, 6);

            hdr->proto = htons(ETHTYPE_IP);
            ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));

            hdr->ethhdr.type = htons(ETHTYPE_ARP);
            return p;
        }
        break;
    case ARP_REPLY:
        /* ARP reply. We insert or update the ARP table. */
        DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: ARP reply\n"));
        if(!memcmp (&(hdr->dipaddr), &(netif->ip_addr), sizeof (hdr->dipaddr))) {
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
            dhcp_arp_reply(&hdr->sipaddr);
#endif
            /* add_arp_entry() will return a pbuf that has previously been
            queued waiting for an ARP reply. */
        }
        /* whether its destined for us or not, we update the arp table */
        return add_arp_entry(&(hdr->sipaddr), &(hdr->shwaddr));
        break;
    default:
        DEBUGF(ETHARP_DEBUG, ("etharp_arp_input: unknown type %d\n", htons(hdr->opcode)));
        break;
    }

    return NULL;
}
예제 #11
0
/**
 * Responds to ARP requests, updates ARP entries and sends queued IP packets.
 * 
 * Should be called for incoming ARP packets. The pbuf in the argument
 * is freed by this function.
 *
 * @param netif The lwIP network interface on which the ARP packet pbuf arrived.
 * @param pbuf The ARP packet that arrived on netif. Is freed by this function.
 * @param ethaddr Ethernet address of netif.
 *
 * @return NULL
 *
 * @see pbuf_free()
 */
struct pbuf *
etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
{
  struct etharp_hdr *hdr;
  u8_t i;

  /* drop short ARP packets */
  if (p->tot_len < sizeof(struct etharp_hdr)) {
    DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet too short (%ld/%u)\n", p->tot_len, sizeof(struct etharp_hdr)));
    pbuf_free(p);
    return NULL;
  }

  hdr = p->payload;

  switch (htons(hdr->opcode)) {
  /* ARP request? */
  case ARP_REQUEST:
    /* ARP request. If it asked for our address, we send out a
    reply. In any case, we time-stamp any existing ARP entry,
    and possiby send out an IP packet that was queued on it. */

    DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
    /* we are not configured? */
    if (netif->ip_addr.addr == 0) {
      DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
      pbuf_free(p);
      return NULL;
    }
    /* update the ARP cache */
    update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0);
    /* ARP request for our address? */
    if (ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {

      DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
      /* re-use pbuf to send ARP reply */
      hdr->opcode = htons(ARP_REPLY);

      ip_addr_set(&(hdr->dipaddr), &(hdr->sipaddr));
      ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));

      for(i = 0; i < netif->hwaddr_len; ++i) {
        hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
        hdr->shwaddr.addr[i] = ethaddr->addr[i];
        hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
        hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
      }

      hdr->hwtype = htons(HWTYPE_ETHERNET);
      ARPH_HWLEN_SET(hdr, netif->hwaddr_len);

        hdr->proto = htons(ETHTYPE_IP);
      ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));      

        hdr->ethhdr.type = htons(ETHTYPE_ARP);      
      /* return ARP reply */
      netif->linkoutput(netif, p);
    } else {
      DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request was not for us.\n"));
    }
    break;
  case ARP_REPLY:    
    /* ARP reply. We insert or update the ARP table. */
    DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
    /* DHCP needs to know about ARP replies */
    dhcp_arp_reply(netif, &hdr->sipaddr);
#endif
    /* ARP reply directed to us? */
    if (ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr))) {
      DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply is for us\n"));
      /* update_the ARP cache, ask to insert */
      update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG);
    /* ARP reply not directed to us */
    } else {
      DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply is not for us\n"));
      /* update the destination address pair */
      update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0);
      /* update the destination address pair */
      update_arp_entry(netif, &(hdr->dipaddr), &(hdr->dhwaddr), 0);
    }
    break;
  default:
    DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode)));
    break;
  }
  /* free ARP packet */
  pbuf_free(p);
  p = NULL;
  /* nothing to send, we did it! */
  return NULL;
}
/**
 * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache  
 * send out queued IP packets. Updates cache with snooped address pairs.
 *
 * Should be called for incoming ARP packets. The pbuf in the argument
 * is freed by this function.
 *
 * @param netif The lwIP network interface on which the ARP packet pbuf arrived.
 * @param pbuf The ARP packet that arrived on netif. Is freed by this function.
 * @param ethaddr Ethernet address of netif.
 *
 * @return NULL
 *
 * @see pbuf_free()
 */
void
etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
{
  struct etharp_hdr *hdr;
  /* these are aligned properly, whereas the ARP header fields might not be */
  struct ip_addr sipaddr, dipaddr;
  u8_t i;
  u8_t for_us;

  /* drop short ARP packets */
  if (p->tot_len < sizeof(struct etharp_hdr)) {
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%d/%d)\n", p->tot_len, sizeof(struct etharp_hdr)));
    pbuf_free(p);
    return;
  }

  hdr = p->payload;
 
  /* get aligned copies of addresses */
  *(struct ip_addr2 *)&sipaddr = hdr->sipaddr;
  *(struct ip_addr2 *)&dipaddr = hdr->dipaddr;

  /* this interface is not configured? */
  if (netif->ip_addr.addr == 0) {
    for_us = 0;
  } else {
    /* ARP packet directed to us? */
    for_us = ip_addr_cmp(&dipaddr, &(netif->ip_addr));
  }

  /* ARP message directed to us? */
  if (for_us) {
    /* add IP address in ARP cache; assume requester wants to talk to us.
     * can result in directly sending the queued packets for this host. */
    update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), ETHARP_CREATE);
  /* ARP message not directed to us? */
  } else {
    /* update the source IP address in the cache, if present */
    update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), 0);
  }

  /* now act on the message itself */
  switch (htons(hdr->opcode)) {
  /* ARP request? */
  case ARP_REQUEST:
    /* ARP request. If it asked for our address, we send out a
     * reply. In any case, we time-stamp any existing ARP entry,
     * and possiby send out an IP packet that was queued on it. */

    LWIP_DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
    /* ARP request for our address? */
    if (for_us) {

      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
      /* re-use pbuf to send ARP reply */
      hdr->opcode = htons(ARP_REPLY);

      hdr->dipaddr = hdr->sipaddr;
      hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;

      for(i = 0; i < netif->hwaddr_len; ++i) {
        hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
        hdr->shwaddr.addr[i] = ethaddr->addr[i];
        hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
        hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
      }

      hdr->hwtype = htons(HWTYPE_ETHERNET);
      ARPH_HWLEN_SET(hdr, netif->hwaddr_len);

      hdr->proto = htons(ETHTYPE_IP);
      ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));

      hdr->ethhdr.type = htons(ETHTYPE_ARP);
      /* return ARP reply */
      netif->linkoutput(netif, p);
      
#ifdef LINKLOCAL_IP //Ron Add for Rendzvous 12/10/04    
	  if( mRENVEnable && (LinkLocal_get_current_state() != NO_USE ) 
	  		&& is_linklocal_ip( dipaddr.addr ) )
	  {
	  		if( (LinkLocal_get_current_state() != IDLE) && ip_conflict_cnt++ == 0 )
  	  			linklocal_alarm();
  	  		else if( (LinkLocal_get_current_state() == IDLE) && ip_conflict_cnt++ == 0) 	
  	  		{
  	  			linklocal_alarm();
  	  		}
  	  }
#endif	  
    /* we are not configured? */
    } else if (netif->ip_addr.addr == 0) {
      /* { for_us == 0 and netif->ip_addr.addr == 0 } */
#ifdef LINKLOCAL_IP //Ron Add for Rendzvous 12/10/04    
		if( mRENVEnable && (LinkLocal_get_current_state() != NO_USE )
		  		&& is_linklocal_ip( dipaddr.addr ) )
		{
			if( (LinkLocal_get_current_state() != IDLE) && ip_conflict_cnt++ == 0 )
  	  			linklocal_alarm();
  	  		else if( (LinkLocal_get_current_state() == IDLE) && ip_conflict_cnt++ == 0) 	
  	  		{
  	  			linklocal_alarm();
  	  		}
  	  		
   		    	hdr->opcode = htons(ARP_REPLY);
				
				hdr->sipaddr = hdr->dipaddr;
				hdr->dipaddr = *(struct ip_addr2 *)&netif->ip_addr;
//		      hdr->dipaddr = hdr->sipaddr;
//		      hdr->sipaddr = *(struct ip_addr2 *)&netif->ip_addr;
				
		
				for(i = 0; i < netif->hwaddr_len; ++i) {
					hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
					hdr->shwaddr.addr[i] = ethaddr->addr[i];
					hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
					hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
				}
		
				hdr->hwtype = htons(HWTYPE_ETHERNET);
				ARPH_HWLEN_SET(hdr, netif->hwaddr_len);
				
				hdr->proto = htons(ETHTYPE_IP);
				ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));
				
				hdr->ethhdr.type = htons(ETHTYPE_ARP);
				
				netif->linkoutput(netif, p);
		      
		}
#endif 
      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
    /* request was not directed to us */
    } else {
      /* { for_us == 0 and netif->ip_addr.addr != 0 } */
      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP request was not for us.\n"));
    }
    break;
  case ARP_REPLY:
    /* ARP reply. We already updated the ARP cache earlier. */
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
    /* DHCP wants to know about ARP replies to our wanna-have-address */
    if (for_us){ 
    	dhcp_arp_reply(netif, &sipaddr);
    }
    	
#endif

#ifdef LINKLOCAL_IP //Ron Add for Rendzvous 12/10/04    
		if( mRENVEnable && (LinkLocal_get_current_state() != NO_USE ) && is_linklocal_ip( sipaddr.addr )  )
		{
	  		if( (LinkLocal_get_current_state() != IDLE) && ip_conflict_cnt++ == 0 )
  	  			linklocal_alarm();
  	  		else if( (LinkLocal_get_current_state() == IDLE) && ip_conflict_cnt++ == 0) 	
  	  		{
  	  			linklocal_alarm();
  	  		}
  	  	}
#endif	  

    break;
  default:
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode)));
    break;
  }
  /* free ARP packet */
  pbuf_free(p);
}
예제 #13
0
파일: etharp.c 프로젝트: aliasxerog/xv6plus
/**
 * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache  
 * send out queued IP packets. Updates cache with snooped address pairs.
 *
 * Should be called for incoming ARP packets. The pbuf in the argument
 * is freed by this function.
 *
 * @param netif The lwIP network interface on which the ARP packet pbuf arrived.
 * @param pbuf The ARP packet that arrived on netif. Is freed by this function.
 * @param ethaddr Ethernet address of netif.
 *
 * @return NULL
 *
 * @see pbuf_free()
 */
struct pbuf *
etharp_arp_input(struct netif *netif, struct eth_addr *ethaddr, struct pbuf *p)
{
  struct etharp_hdr *hdr;
  u8_t i;
  u8_t for_us;

  /* drop short ARP packets */
  if (p->tot_len < sizeof(struct etharp_hdr)) {
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE | 1, ("etharp_arp_input: packet dropped, too short (%d/%d)\n", p->tot_len, sizeof(struct etharp_hdr)));
    pbuf_free(p);
    return NULL;
  }

  hdr = p->payload;
 
  /* this interface is not configured? */
  if (netif->ip_addr.addr == 0) {
    for_us = 0;
  } else {
    /* ARP packet directed to us? */
    for_us = ip_addr_cmp(&(hdr->dipaddr), &(netif->ip_addr));
  }

  /* add or update entries in the ARP cache */
  if (for_us) {
    /* insert IP address in ARP cache (assume requester wants to talk to us)
     * we might even send out a queued packet to this host */
    update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), ARP_INSERT_FLAG);
  /* request was not directed to us, but snoop anyway */
  } else {
    /* update the source IP address in the cache */
    update_arp_entry(netif, &(hdr->sipaddr), &(hdr->shwaddr), 0);
  }

  switch (htons(hdr->opcode)) {
  /* ARP request? */
  case ARP_REQUEST:
    /* ARP request. If it asked for our address, we send out a
    reply. In any case, we time-stamp any existing ARP entry,
    and possiby send out an IP packet that was queued on it. */

    LWIP_DEBUGF (ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request\n"));
    /* we are not configured? */
    if (netif->ip_addr.addr == 0) {
      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: we are unconfigured, ARP request ignored.\n"));
      pbuf_free(p);
      return NULL;
    }
    /* ARP request for our address? */
    if (for_us) {

      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: replying to ARP request for our IP address\n"));
      /* re-use pbuf to send ARP reply */
      hdr->opcode = htons(ARP_REPLY);

      ip_addr_set(&(hdr->dipaddr), &(hdr->sipaddr));
      ip_addr_set(&(hdr->sipaddr), &(netif->ip_addr));

      for(i = 0; i < netif->hwaddr_len; ++i) {
        hdr->dhwaddr.addr[i] = hdr->shwaddr.addr[i];
        hdr->shwaddr.addr[i] = ethaddr->addr[i];
        hdr->ethhdr.dest.addr[i] = hdr->dhwaddr.addr[i];
        hdr->ethhdr.src.addr[i] = ethaddr->addr[i];
      }

      hdr->hwtype = htons(HWTYPE_ETHERNET);
      ARPH_HWLEN_SET(hdr, netif->hwaddr_len);

      hdr->proto = htons(ETHTYPE_IP);
      ARPH_PROTOLEN_SET(hdr, sizeof(struct ip_addr));

      hdr->ethhdr.type = htons(ETHTYPE_ARP);
      /* return ARP reply */
      netif->linkoutput(netif, p);

    /* request was not directed to us */
    } else {
      LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP request was not for us.\n"));
    }
    break;
  case ARP_REPLY:
    /* ARP reply. We insert or update the ARP table later. */
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: incoming ARP reply\n"));
#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK)
    /* DHCP wants to know about ARP replies to our wanna-have-address */
    if (for_us) dhcp_arp_reply(netif, &hdr->sipaddr);
#endif
    break;
  default:
    LWIP_DEBUGF(ETHARP_DEBUG | DBG_TRACE, ("etharp_arp_input: ARP unknown opcode type %d\n", htons(hdr->opcode)));
    break;
  }
  /* free ARP packet */
  pbuf_free(p);
  p = NULL;
  /* nothing to send, we did it! */
  return NULL;
}
예제 #14
0
파일: raslink.c 프로젝트: 0x00dec0de/Rovnix
NDIS_STATUS 
	WAN_AddRasLink (
		IN PKIP_NDIS_ADAPTER pAdapter,
		IN PNDIS_WAN_LINE_UP pWanLineUp
		)
{
	NDIS_STATUS nStatus = NDIS_STATUS_SUCCESS;
	PKIP_RAS_LINK RasLink = NULL;
	
	ULONG OsVersion = OsGetMajorVersion();

	DBGLOG(( LTrace, "Local MAC: %.2X%.2X%.2X%.2X%.2X%.2X Remote MAC: %.2X%.2X%.2X%.2X%.2X%.2X\n", 
				pWanLineUp->LocalAddress[0],
				pWanLineUp->LocalAddress[1],
				pWanLineUp->LocalAddress[2],
				pWanLineUp->LocalAddress[3],
				pWanLineUp->LocalAddress[4],
				pWanLineUp->LocalAddress[5],
				pWanLineUp->RemoteAddress[0],
				pWanLineUp->RemoteAddress[1],
				pWanLineUp->RemoteAddress[2],
				pWanLineUp->RemoteAddress[3],
				pWanLineUp->RemoteAddress[4],
				pWanLineUp->RemoteAddress[5]
				));

	if ( pWanLineUp->ProtocolType != ETHTYPE_IP ){
		return NDIS_STATUS_SUCCESS;
	}

	if ( OsVersion < 5 ){
		if ( pWanLineUp->ProtocolBufferLength < sizeof(WAN_IP_INFO_NT)){
			return NDIS_STATUS_SUCCESS;
		}
	}else if ( OsVersion < 6 ){
		if ( pWanLineUp->ProtocolBufferLength < sizeof(WAN_IP_INFO_W2K)){
			return NDIS_STATUS_SUCCESS;
		}
	}else if ( OsVersion < 7 ){
		if ( pWanLineUp->ProtocolBufferLength < sizeof(WAN_IP_INFO_VISTA)){
			return NDIS_STATUS_SUCCESS;
		}
	}

	// To avoid RAS entries duplications
	if (WAN_CheckForContext(pAdapter, &pWanLineUp->LocalAddress[2]) == FALSE )
	{
		RasLink = NDIS_AllocateRasLink( pAdapter, pWanLineUp );
		if ( RasLink == NULL ) {
			nStatus = NDIS_STATUS_RESOURCES;
		}else{
			
			if ( OsVersion < 5 ){
				PWAN_IP_INFO_NT WanIpInfo = (PWAN_IP_INFO_NT)pWanLineUp->ProtocolBuffer;
				ip4_addr_set_u32(&RasLink->IpAddr,WanIpInfo->IpAddress);
				ip4_addr_set_u32(&RasLink->IpMask,IPADDR_BROADCAST);
			}else if ( OsVersion < 6 ){
				PWAN_IP_INFO_W2K WanIpInfo = (PWAN_IP_INFO_W2K)pWanLineUp->ProtocolBuffer;
				ip4_addr_set_u32(&RasLink->IpAddr,WanIpInfo->LocalIpAddress);
				ip4_addr_set_u32(&RasLink->IpMask,WanIpInfo->IpSubnetMask);
				ip4_addr_set_u32(&RasLink->RemoteIpAddr,WanIpInfo->RemoteIpAddress);
			}else if ( OsVersion < 7 ){
				PWAN_IP_INFO_VISTA WanIpInfo = (PWAN_IP_INFO_VISTA)pWanLineUp->ProtocolBuffer;
				ip4_addr_set_u32(&RasLink->IpAddr,WanIpInfo->LocalIpAddress);
				ip4_addr_set_u32(&RasLink->IpMask,WanIpInfo->IpSubnetMask);
				ip4_addr_set_u32(&RasLink->RemoteIpAddr,WanIpInfo->RemoteIpAddress);
			}

			ProtocolBindAdapter(
				(PKIP_NDIS_INTERFACE)RasLink,
				RasLink->IpAddr.addr,
				RasLink->IpMask.addr,
				RasLink->IpAddr.addr,
				TRUE
				);

			// update arp table
			update_arp_entry( 
				&RasLink->Interface.Protocol.IIF, 
				&RasLink->RemoteIpAddr, 
				(struct eth_addr*)RasLink->RemoteAddress, 
				ETHARP_FLAG_STATIC_ENTRY 
				);

			update_arp_entry( 
				&RasLink->Interface.Protocol.IIF, 
				&RasLink->IpAddr, 
				(struct eth_addr*)RasLink->RemoteAddress,
				ETHARP_FLAG_STATIC_ENTRY 
				);
		}
	}
	return nStatus;
}