示例#1
0
void uip_build_arp_request(struct uip_stack *ustack, u16_t *ipaddr)
{
	struct arp_hdr *arp;
	struct uip_eth_hdr *eth;

	arp = (struct arp_hdr *)ustack->network_layer;
	eth = (struct uip_eth_hdr *)ustack->data_link_layer;

	/* The destination address was not in our ARP table, so we
	   overwrite the IP packet with an ARP request. */

	memset(eth->dest.addr, 0xff, 6);
	memset(arp->dhwaddr.addr, 0x00, 6);
	memcpy(eth->src.addr, ustack->uip_ethaddr.addr, 6);
	memcpy(arp->shwaddr.addr, ustack->uip_ethaddr.addr, 6);

	uip_ip4addr_copy(arp->dipaddr, ipaddr);
	uip_ip4addr_copy(arp->sipaddr, ustack->hostaddr);
	arp->opcode = const_htons(ARP_REQUEST);	/* ARP request. */
	arp->hwtype = const_htons(ARP_HWTYPE_ETH);
	arp->protocol = const_htons(UIP_ETHTYPE_IPv4);
	arp->hwlen = 6;
	arp->protolen = 4;
	eth->type = const_htons(UIP_ETHTYPE_ARP);

	ustack->uip_appdata = &ustack->uip_buf[UIP_TCP_IPv4_HLEN + UIP_LLH_LEN];

	ustack->uip_len = sizeof(*arp) + sizeof(*eth);
}
示例#2
0
void
uip_arp_arpin(nic_interface_t *nic_iface,
	      struct uip_stack *ustack, packet_t *pkt)
{
	struct arp_hdr *arp;
	struct uip_eth_hdr *eth;

	if (pkt->buf_size < sizeof(struct arp_hdr)) {
		pkt->buf_size = 0;
		return;
	}
	pkt->buf_size = 0;

	eth = (struct uip_eth_hdr *)pkt->data_link_layer;
	arp = (struct arp_hdr *)pkt->network_layer;

	switch (arp->opcode) {
	case const_htons(ARP_REQUEST):
		/* ARP request. If it asked for our address, we send out a
		   reply. */
		if (uip_ip4addr_cmp(arp->dipaddr, ustack->hostaddr)) {
			/* First, we register the one who made the request in
			   our ARP table, since it is likely that we will do
			   more communication with this host in the future. */
			uip_arp_update(arp->sipaddr, &arp->shwaddr);

			/* The reply opcode is 2. */
			arp->opcode = htons(2);

			memcpy(arp->dhwaddr.addr, arp->shwaddr.addr, 6);
			memcpy(arp->shwaddr.addr, ustack->uip_ethaddr.addr, 6);
			memcpy(eth->src.addr, ustack->uip_ethaddr.addr, 6);
			memcpy(eth->dest.addr, arp->dhwaddr.addr, 6);

			arp->dipaddr[0] = arp->sipaddr[0];
			arp->dipaddr[1] = arp->sipaddr[1];
			arp->sipaddr[0] = ustack->hostaddr[0];
			arp->sipaddr[1] = ustack->hostaddr[1];

			if (nic_iface->vlan_id == 0) {
				eth->type = htons(UIP_ETHTYPE_ARP);
				pkt->buf_size = sizeof(*arp) + sizeof(*eth);
			} else {
				eth->type = htons(UIP_ETHTYPE_8021Q);
				pkt->buf_size = sizeof(*arp) +
						sizeof(struct uip_vlan_eth_hdr);
			}
		}
		break;
	case const_htons(ARP_REPLY):
		uip_arp_update(arp->sipaddr, &arp->shwaddr);
		break;
	default:
		LOG_WARN("Unknown ARP opcode: %d", ntohs(arp->opcode));
		break;
	}

	return;
}
示例#3
0
int is_vlan_packet(struct uip_vlan_eth_hdr *hdr)
{
	/*  The TPID field in a 802.1Q Header must be 0x8100 */
	if (hdr->tpid == const_htons(UIP_ETHTYPE_8021Q))
		return 1;

	return 0;
}