Пример #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
/*---------------------------------------------------------------------------*/
static int prepare_and_send_buf(coap_context_t *ctx, session_t *session,
				uint8_t *data, size_t len)
{
  struct net_buf *buf;
  int max_data_len;

  /* This net_buf gets sent to network, so it is not released
   * by this function unless there was an error and buf was
   * not actually sent.
   */
  buf = ip_buf_get_tx(ctx->net_ctx);
  if (!buf) {
    len = -ENOBUFS;
    goto out;
  }

  max_data_len = IP_BUF_MAX_DATA - UIP_IPUDPH_LEN;

  PRINTF("%s: reply to peer data %p len %d\n", __FUNCTION__, data, len);

  if (len > max_data_len) {
    PRINTF("%s: too much (%d bytes) data to send (max %d bytes)\n",
	  __FUNCTION__, len, max_data_len);
    ip_buf_unref(buf);
    len = -EINVAL;
    goto out;
  }

  /* Note that we have reversed the addresses here
   * because net_reply() will reverse them again.
   */
#ifdef CONFIG_NETWORKING_WITH_IPV6
  uip_ip6addr_copy(&NET_BUF_IP(buf)->destipaddr, (uip_ip6addr_t *)&ctx->my_addr.in6_addr);
  uip_ip6addr_copy(&NET_BUF_IP(buf)->srcipaddr,
		   (uip_ip6addr_t *)&session->addr.ipaddr);
#else
  uip_ip4addr_copy(&NET_BUF_IP(buf)->destipaddr,
		   (uip_ip4addr_t *)&ctx->my_addr.in_addr);
  uip_ip4addr_copy(&NET_BUF_IP(buf)->srcipaddr,
		   (uip_ip4addr_t *)&session->addr.ipaddr);
#endif
  NET_BUF_UDP(buf)->destport = uip_ntohs(ctx->my_port);
  NET_BUF_UDP(buf)->srcport = session->addr.port;

  uip_set_udp_conn(buf) = net_context_get_udp_connection(ctx->net_ctx);

  memcpy(net_buf_add(buf, len), data, len);
  ip_buf_appdatalen(buf) = len;
  ip_buf_appdata(buf) = buf->data + ip_buf_reserve(buf);

  if (net_reply(ctx->net_ctx, buf)) {
    ip_buf_unref(buf);
  }
out:
  return len;
}
Пример #3
0
dest_ipv4_addr_t
uip_determine_dest_ipv4_addr(struct uip_stack *ustack, u16_t *ipaddr)
{
	struct arp_hdr *arp;
	struct uip_eth_hdr *eth;
	struct ip_hdr *ip_buf;

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

	/* Find the destination IP address in the ARP table and construct
	   the Ethernet header. If the destination IP addres isn't on the
	   local network, we use the default router's IP address instead.

	   If not ARP table entry is found, we overwrite the original IP
	   packet with an ARP request for the IP address. */

	/* First check if destination is a local broadcast. */
	if (uip_ip4addr_cmp(ip_buf->destipaddr, broadcast_ipaddr)) {
		memcpy(&eth->dest, broadcast_ethaddr.addr, 6);

		return LOCAL_BROADCAST;
	} else {
		/* Check if the destination address is on the local network. */
		if (!uip_ip4addr_maskcmp(ip_buf->destipaddr,
					 ustack->hostaddr, ustack->netmask)) {
			/* Destination address was not on the local network,
			   so we need to use the default router's IP address
			   instead of the destination address when determining
			   the MAC address. */
			uip_ip4addr_copy(ipaddr, ustack->default_route_addr);
		} else {
			/* Else, we use the destination IP address. */
			uip_ip4addr_copy(ipaddr, ip_buf->destipaddr);
		}

		return NONLOCAL_BROADCAST;
	}
}
Пример #4
0
/*---------------------------------------------------------------------------*/
struct ip64_addrmap_entry *
ip64_addrmap_create(const uip_ip6addr_t *ip6addr,
                    uint16_t ip6port,
                    const uip_ip4addr_t *ip4addr,
                    uint16_t ip4port,
                    uint8_t protocol)
{
    struct ip64_addrmap_entry *m;

    check_age();
    m = memb_alloc(&entrymemb);
    if(m == NULL) {
        /* We could not allocate an entry, try to recycle one and try to
           allocate again. */
        if(recycle()) {
            m = memb_alloc(&entrymemb);
        }
    }
    if(m != NULL) {
        uip_ip4addr_copy(&m->ip4addr, ip4addr);
        m->ip4port = ip4port;
        uip_ip6addr_copy(&m->ip6addr, ip6addr);
        m->ip6port = ip6port;
        m->protocol = protocol;
        m->flags = FLAGS_NONE;
        m->ip6to4 = 1;
        m->ip4to6 = 0;
        timer_set(&m->timer, 0);

        /* Pick a new, unused local port. First make sure that the
           mapped_port number does not belong to any active connection. If
           so, we keep increasing the mapped_port until we're free. */
        {
            struct ip64_addrmap_entry *n;
            n = list_head(entrylist);
            while(n != NULL) {
                if(n->mapped_port == mapped_port) {
                    increase_mapped_port();
                    n = list_head(entrylist);
                } else {
                    n = list_item_next(m);
                }
            }
        }
        m->mapped_port = mapped_port;
        increase_mapped_port();

        list_add(entrylist, m);
        return m;
    }
    return NULL;
}