Пример #1
0
/**
 * Check if "dst" is an IPv4 address that proxy remaps to host's
 * loopback.
 */
static int
proxy_ip4_is_mapped_loopback(struct netif *netif, const ip_addr_t *dst, ip_addr_t *lo)
{
    u32_t off;
    const struct ip4_lomap *lomap;
    size_t i;

    LWIP_ASSERT1(dst != NULL);

    if (g_proxy_options->lomap_desc == NULL) {
        return 0;
    }

    if (!ip_addr_netcmp(dst, &netif->ip_addr, &netif->netmask)) {
        return 0;
    }

    /* XXX: TODO: check netif is a proxying netif! */

    off = ntohl(ip4_addr_get_u32(dst) & ~ip4_addr_get_u32(&netif->netmask));
    lomap = g_proxy_options->lomap_desc->lomap;
    for (i = 0; i < g_proxy_options->lomap_desc->num_lomap; ++i) {
        if (off == lomap[i].off) {
            if (lo != NULL) {
                ip_addr_copy(*lo, lomap[i].loaddr);
            }
            return 1;
        }
    }
    return 0;
}
Пример #2
0
/**
 * Determine if an address is a broadcast address on a network interface 
 * 
 * @param addr address to be checked
 * @param netif the network interface against which the address is checked
 * @return returns non-zero if the address is a broadcast address
 */
u8_t
ip4_addr_isbroadcast(u32_t addr, const struct netif *netif)
{
  ip_addr_t ipaddr;
  ip4_addr_set_u32(&ipaddr, addr);

  /* all ones (broadcast) or all zeroes (old skool broadcast) */
  if ((~addr == IPADDR_ANY) ||
      (addr == IPADDR_ANY)) {
    return 1;
  /* no broadcast support on this network interface? */
  } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) {
    /* the given address cannot be a broadcast address
     * nor can we check against any broadcast addresses */
    return 0;
  /* address matches network interface address exactly? => no broadcast */
  } else if (addr == ip4_addr_get_u32(&netif->ip_addr)) {
    return 0;
  /*  on the same (sub) network... */
  } else if (ip_addr_netcmp(&ipaddr, &(netif->ip_addr), &(netif->netmask))
         /* ...and host identifier bits are all ones? =>... */
          && ((addr & ~ip4_addr_get_u32(&netif->netmask)) ==
           (IPADDR_BROADCAST & ~ip4_addr_get_u32(&netif->netmask)))) {
    /* => network broadcast address */
    return 1;
  } else {
    return 0;
  }
}
Пример #3
0
/**
 * Ascii internet address interpretation routine.
 * The value returned is in network order.
 *
 * @param cp IP address in ascii represenation (e.g. "127.0.0.1")
 * @return ip address in network order
 */
uint32_t ipaddr_addr(const char *cp)
{
	ip_addr_t val;

	if (ipaddr_aton(cp, &val)) {
		return ip4_addr_get_u32(&val);
	}
	return IPADDR_NONE;
}
Пример #4
0
/**
 * Ascii internet address interpretation routine.
 * The value returned is in network order.
 *
 * @param cp IP address in ascii represenation (e.g. "127.0.0.1")
 * @return ip address in network order
 */
u32_t ICACHE_FLASH_ATTR
ipaddr_addr(const char *cp)
{
  ip_addr_t val;

  if (ipaddr_aton(cp, &val)) {
    return ip4_addr_get_u32(&val);
  }
  return (IPADDR_NONE);
}
Пример #5
0
/**
 * Mapping from loopback to local network for inbound (port-forwarded)
 * connections.
 *
 * Copy "src" to "dst" with ip_addr_set(dst, src), but if "src" is a
 * host's loopback address, copy local network address that maps it to
 * "dst".
 */
int
pxremap_inbound_ip4(ip_addr_t *dst, ip_addr_t *src)
{
    struct netif *netif;
    const struct ip4_lomap *lomap;
    unsigned int i;

    if (ip4_addr1(src) != IP_LOOPBACKNET) {
        ip_addr_set(dst, src);
        return PXREMAP_ASIS;
    }

    if (g_proxy_options->lomap_desc == NULL) {
        return PXREMAP_FAILED;
    }

#if 0 /* ?TODO: with multiple interfaces we need to consider fwspec::dst */
    netif = ip_route(target);
    if (netif == NULL) {
        return PXREMAP_FAILED;
    }
#else
    netif = netif_list;
    LWIP_ASSERT1(netif != NULL);
    LWIP_ASSERT1(netif->next == NULL);
#endif

    lomap = g_proxy_options->lomap_desc->lomap;
    for (i = 0; i < g_proxy_options->lomap_desc->num_lomap; ++i) {
        if (ip_addr_cmp(src, &lomap[i].loaddr)) {
            ip_addr_t net;

            ip_addr_get_network(&net, &netif->ip_addr, &netif->netmask);
            ip4_addr_set_u32(dst,
                             htonl(ntohl(ip4_addr_get_u32(&net))
                                   + lomap[i].off));
            return PXREMAP_MAPPED;
        }
    }

    return PXREMAP_FAILED;
}
Пример #6
0
/**
 * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used.
 *
 * @param addr ip address in network order to convert
 * @param buf target buffer where the string is stored
 * @param buflen length of buf
 * @return either pointer to buf which now holds the ASCII
 *         representation of addr or NULL if buf was too small
 */
char *
ipaddr_ntoa_r(const ip_addr_t *addr, char *buf, int buflen)
{
  u32_t s_addr;
  char inv[3];
  char *rp;
  u8_t *ap;
  u8_t rem;
  u8_t n;
  u8_t i;
  int len = 0;

  s_addr = ip4_addr_get_u32(addr);

  rp = buf;
  ap = (u8_t *)&s_addr;
  for(n = 0; n < 4; n++) {
    i = 0;
    do {
      rem = *ap % (u8_t)10;
      *ap /= (u8_t)10;
      inv[i++] = '0' + rem;
    } while(*ap);
    while(i--) {
      if (len++ >= buflen) {
        return NULL;
      }
      *rp++ = inv[i];
    }
    if (len++ >= buflen) {
      return NULL;
    }
    *rp++ = '.';
    ap++;
  }
  *--rp = 0;
  return buf;
}
Пример #7
0
/* send a DHCP OFFER to a DHCP DISCOVER */
int sendOffer(struct dhcpMessage *oldpacket)
{
#ifdef DHCPD_HEAP_REPLACE_STACK
	struct dhcpMessage *packet;
#else
	struct dhcpMessage packet;
#endif
	struct dhcpOfferedAddr *lease = NULL;
	u_int32_t req_align, lease_time_align = server_config.lease;
	unsigned char *req, *lease_time;
	struct option_set *curr;
	//struct in_addr addr;

#ifdef DHCPD_HEAP_REPLACE_STACK
	packet = calloc(1,sizeof(struct dhcpMessage));
	if (!packet) {
		DHCPD_LOG(LOG_ERR, "Calloc failed...%d",__LINE__);
		return -1;
	}
	init_packet(packet, oldpacket, DHCPOFFER);
#else
	init_packet(&packet, oldpacket, DHCPOFFER);
#endif

	/* ADDME: if static, short circuit */
	/* the client is in our lease/offered table */
	if ((lease = find_lease_by_chaddr(oldpacket->chaddr))) {
		if (!lease_expired(lease))
			lease_time_align = lease->expires - time(0);
#ifdef DHCPD_HEAP_REPLACE_STACK
		packet->yiaddr = lease->yiaddr;
#else
		packet.yiaddr = lease->yiaddr;
#endif
	/* Or the client has a requested ip */
	} else if ((req = get_option(oldpacket, DHCP_REQUESTED_IP)) &&

		   /* Don't look here (ugly hackish thing to do) */
		   memcpy(&req_align, req, 4) &&

		   /* and the ip is in the lease range */
		   ntohl(req_align) >= ntohl(server_config.start) &&
		   ntohl(req_align) <= ntohl(server_config.end) &&

		   /* and its not already taken/offered */ /* ADDME: check that its not a static lease */
		   ((!(lease = find_lease_by_yiaddr(req_align)) ||

		   /* or its taken, but expired */ /* ADDME: or maybe in here */
		   lease_expired(lease)))) {
#ifdef DHCPD_HEAP_REPLACE_STACK
				packet->yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */
#else
				packet.yiaddr = req_align; /* FIXME: oh my, is there a host using this IP? */
#endif

	/* otherwise, find a free IP */ /*ADDME: is it a static lease? */
	} else {
#ifdef DHCPD_HEAP_REPLACE_STACK
		packet->yiaddr = find_address(0);
		/* try for an expired lease */
		if (!packet->yiaddr) packet->yiaddr = find_address(1);
#else
		packet.yiaddr = find_address(0);

		/* try for an expired lease */
		if (!packet.yiaddr) packet.yiaddr = find_address(1);
#endif
	}
#ifdef DHCPD_HEAP_REPLACE_STACK
	if(!(packet->yiaddr)) {
		if (packet != NULL)
			free(packet);

#else
	if(!packet.yiaddr) {
#endif
		DHCPD_LOG(LOG_WARNING, "no IP addresses to give -- OFFER abandoned");
		return -1;
	}
#ifdef DHCPD_HEAP_REPLACE_STACK
	if (!add_lease(packet->chaddr, packet->yiaddr, server_config.offer_time)) {
		if (packet != NULL) {
			free(packet);
			packet = NULL;
		}
#else
	if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time)) {
#endif
		DHCPD_LOG(LOG_WARNING, "lease pool is full -- OFFER abandoned");
		return -1;
	}

	if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) {
		memcpy(&lease_time_align, lease_time, 4);
		lease_time_align = ntohl(lease_time_align);
		if (lease_time_align > server_config.lease)
			lease_time_align = server_config.lease;
	}

	/* Make sure we aren't just using the lease time from the previous offer */
	if (lease_time_align < server_config.min_lease)
		lease_time_align = server_config.lease;
	/* ADDME: end of short circuit */
#ifdef DHCPD_HEAP_REPLACE_STACK
	struct netif *netif = netif_find(server_config.interface);

	add_simple_option(packet->options, DHCP_LEASE_TIME, htonl(lease_time_align));
#ifdef __CONFIG_LWIP_V1
	add_simple_option(packet->options, DHCP_SUBNET, ip4_addr_get_u32(&netif->netmask));
	add_simple_option(packet->options, DHCP_ROUTER, ip4_addr_get_u32(&netif->gw));
	add_simple_option(packet->options, DHCP_DNS_SERVER, ip4_addr_get_u32(&netif->ip_addr));
#elif LWIP_IPV4 /* now only for IPv4 */
	add_simple_option(packet->options, DHCP_SUBNET, ip4_addr_get_u32(ip_2_ip4(&netif->netmask)));
	add_simple_option(packet->options, DHCP_ROUTER, ip4_addr_get_u32(ip_2_ip4(&netif->gw)));
	add_simple_option(packet->options, DHCP_DNS_SERVER, ip4_addr_get_u32(ip_2_ip4(&netif->ip_addr)));
#else
	#error "IPv4 not support!"
#endif

#else
	add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align));
#endif

	curr = server_config.options;
	while (curr) {
		if (curr->data[OPT_CODE] != DHCP_LEASE_TIME)
#ifdef DHCPD_HEAP_REPLACE_STACK
			add_option_string(packet->options, curr->data);
#else
			add_option_string(packet.options, curr->data);
#endif
		curr = curr->next;
	}
#ifdef DHCPD_HEAP_REPLACE_STACK
	add_bootp_options(packet);

	//addr.s_addr = packet->yiaddr;
	DHCPD_LOG(LOG_INFO, "sending OFFER of %s", inet_ntoa(packet->yiaddr));
	int ret = send_packet(packet, 0);
	if (packet != NULL) {
		free(packet);
		packet = NULL;
	}
	return ret;
#else
	add_bootp_options(&packet);

	addr.s_addr = packet.yiaddr;
	DHCPD_LOG(LOG_INFO, "sending OFFER of %s", inet_ntoa(addr));
	return send_packet(&packet, 0);
#endif
}


int sendNAK(struct dhcpMessage *oldpacket)
{
#ifdef DHCPD_HEAP_REPLACE_STACK
	struct dhcpMessage *packet;
#else
	struct dhcpMessage packet;
#endif
#ifdef DHCPD_HEAP_REPLACE_STACK
	packet = calloc(1,sizeof(struct dhcpMessage));
	if (!packet)
		DHCPD_LOG(LOG_ERR, "Calloc failed...%d",__LINE__);
	init_packet(packet, oldpacket, DHCPNAK);
#else
	init_packet(&packet, oldpacket, DHCPNAK);
#endif

	DEBUG(LOG_INFO, "sending NAK");
#ifdef DHCPD_HEAP_REPLACE_STACK
	int ret = send_packet(packet, 1);
	if (packet != NULL)
		free(packet);
	return ret;
#else
	return send_packet(&packet, 1);
#endif
}


int sendACK(struct dhcpMessage *oldpacket, u_int32_t yiaddr)
{
#ifdef DHCPD_HEAP_REPLACE_STACK
	struct dhcpMessage *packet;
#else
	struct dhcpMessage packet;
#endif
	struct option_set *curr;
	unsigned char *lease_time;
	u_int32_t lease_time_align = server_config.lease;
	//struct in_addr addr;

#ifdef DHCPD_HEAP_REPLACE_STACK
	packet = calloc(1,sizeof(struct dhcpMessage));
	if (!packet)
		DHCPD_LOG(LOG_ERR, "Calloc failed...%d",__LINE__);
	init_packet(packet, oldpacket, DHCPACK);
	packet->yiaddr = yiaddr;
#else
	init_packet(&packet, oldpacket, DHCPACK);

	packet.yiaddr = yiaddr;
#endif

	if ((lease_time = get_option(oldpacket, DHCP_LEASE_TIME))) {
		memcpy(&lease_time_align, lease_time, 4);
		lease_time_align = ntohl(lease_time_align);
		if (lease_time_align > server_config.lease)
			lease_time_align = server_config.lease;
		else if (lease_time_align < server_config.min_lease)
			lease_time_align = server_config.lease;
	}
#ifdef DHCPD_HEAP_REPLACE_STACK
	struct netif *netif = netif_find(server_config.interface);

	add_simple_option(packet->options, DHCP_LEASE_TIME, htonl(lease_time_align));
#ifdef __CONFIG_LWIP_V1
	add_simple_option(packet->options, DHCP_SUBNET, ip4_addr_get_u32(&netif->netmask));
	add_simple_option(packet->options, DHCP_ROUTER, ip4_addr_get_u32(&netif->gw));
	add_simple_option(packet->options, DHCP_DNS_SERVER, ip4_addr_get_u32(&netif->ip_addr));
#elif LWIP_IPV4 /* now only for IPv4 */
	add_simple_option(packet->options, DHCP_SUBNET, ip4_addr_get_u32(ip_2_ip4(&netif->netmask)));
	add_simple_option(packet->options, DHCP_ROUTER, ip4_addr_get_u32(ip_2_ip4(&netif->gw)));
	add_simple_option(packet->options, DHCP_DNS_SERVER, ip4_addr_get_u32(ip_2_ip4(&netif->ip_addr)));
#else
	#error "IPv4 not support!"
#endif

#else
	add_simple_option(packet.options, DHCP_LEASE_TIME, htonl(lease_time_align));
#endif
	curr = server_config.options;
	while (curr) {
		if (curr->data[OPT_CODE] != DHCP_LEASE_TIME)
#ifdef DHCPD_HEAP_REPLACE_STACK
			add_option_string(packet->options, curr->data);
#else
			add_option_string(packet.options, curr->data);
#endif
		curr = curr->next;
	}
#ifdef DHCPD_HEAP_REPLACE_STACK
	add_bootp_options(packet);

	//addr.s_addr = packet->yiaddr;
	DHCPD_LOG(LOG_INFO, "sending ACK to %s", inet_ntoa(packet->yiaddr));
	int ret = 0;
	if (send_packet(packet, 0) < 0)
		ret = -1;

	add_lease(packet->chaddr, packet->yiaddr, lease_time_align);

	if (packet)
		free(packet);
	return ret;
#else
	add_bootp_options(&packet);

	//addr.s_addr = packet.yiaddr;
	DHCPD_LOG(LOG_INFO, "sending ACK to %s", inet_ntoa(packet->yiaddr));

	if (send_packet(&packet, 0) < 0)
		return -1;

	add_lease(packet.chaddr, packet.yiaddr, lease_time_align);
	return 0;
#endif
}


int send_inform(struct dhcpMessage *oldpacket)
{
#ifdef DHCPD_HEAP_REPLACE_STACK
	struct dhcpMessage *packet;
#else
	struct dhcpMessage packet;
#endif
	struct option_set *curr;
#ifdef DHCPD_HEAP_REPLACE_STACK
	packet = calloc(1,sizeof(struct dhcpMessage));
	if (!packet)
		DHCPD_LOG(LOG_ERR, "Calloc failed...%d",__LINE__);
	init_packet(packet, oldpacket, DHCPACK);
#else
	init_packet(&packet, oldpacket, DHCPACK);
#endif

	curr = server_config.options;
	while (curr) {
		if (curr->data[OPT_CODE] != DHCP_LEASE_TIME)
#ifdef DHCPD_HEAP_REPLACE_STACK
			add_option_string(packet->options, curr->data);
#else
			add_option_string(packet.options, curr->data);
#endif
		curr = curr->next;
	}
#ifdef DHCPD_HEAP_REPLACE_STACK
	add_bootp_options(packet);

	int ret = send_packet(packet, 0);
	if (packet)
		free(packet);
	return ret;
#else
	add_bootp_options(&packet);

	return send_packet(&packet, 0);
#endif
}