Beispiel #1
0
/* NOINLINE: limit stack usage in caller */
static NOINLINE void send_inform(struct dhcp_packet *oldpacket)
{
	struct dhcp_packet packet;

	/* "If a client has obtained a network address through some other means
	 * (e.g., manual configuration), it may use a DHCPINFORM request message
	 * to obtain other local configuration parameters.  Servers receiving a
	 * DHCPINFORM message construct a DHCPACK message with any local
	 * configuration parameters appropriate for the client without:
	 * allocating a new address, checking for an existing binding, filling
	 * in 'yiaddr' or including lease time parameters.  The servers SHOULD
	 * unicast the DHCPACK reply to the address given in the 'ciaddr' field
	 * of the DHCPINFORM message.
	 * ...
	 * The server responds to a DHCPINFORM message by sending a DHCPACK
	 * message directly to the address given in the 'ciaddr' field
	 * of the DHCPINFORM message.  The server MUST NOT send a lease
	 * expiration time to the client and SHOULD NOT fill in 'yiaddr'."
	 */
//TODO: do a few sanity checks: is ciaddr set?
//Better yet: is ciaddr == IP source addr?
	init_packet(&packet, oldpacket, DHCPACK);
	add_server_options(&packet);

	send_packet(&packet, /*force_bcast:*/ 0);
}
Beispiel #2
0
/* NOINLINE: limit stack usage in caller */
static NOINLINE void send_ACK(struct dhcp_packet *oldpacket, uint32_t yiaddr)
{
	struct dhcp_packet packet;
	uint32_t lease_time_sec;
	struct in_addr addr;
	const char *p_host_name;

	init_packet(&packet, oldpacket, DHCPACK);
	packet.yiaddr = yiaddr;

	lease_time_sec = select_lease_time(oldpacket);
	udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec));

	add_server_options(&packet);

	addr.s_addr = yiaddr;
	bb_info_msg("Sending ACK to %s", inet_ntoa(addr));
	send_packet(&packet, /*force_bcast:*/ 0);

	p_host_name = (const char*) udhcp_get_option(oldpacket, DHCP_HOST_NAME);
	add_lease(packet.chaddr, packet.yiaddr,
		lease_time_sec,
		p_host_name,
		p_host_name ? (unsigned char)p_host_name[OPT_LEN - OPT_DATA] : 0
	);
	if (ENABLE_FEATURE_UDHCPD_WRITE_LEASES_EARLY) {
		/* rewrite the file with leases at every new acceptance */
		write_leases();
	}
}
Beispiel #3
0
static void send_ACK(GDHCPServer *dhcp_server,
		struct dhcp_packet *client_packet, uint32_t dest)
{
	struct dhcp_packet packet;
	uint32_t lease_time_sec;
	struct in_addr addr;

	init_packet(dhcp_server, &packet, client_packet, DHCPACK);
	packet.yiaddr = htonl(dest);

	lease_time_sec = dhcp_server->lease_seconds;

	dhcp_add_option_uint32(&packet, DHCP_LEASE_TIME, lease_time_sec);

	add_server_options(dhcp_server, &packet);

	addr.s_addr = htonl(dest);

	debug(dhcp_server, "Sending ACK to %s", inet_ntoa(addr));

	send_packet_to_client(dhcp_server, &packet);

	add_lease(dhcp_server, 0, packet.chaddr, packet.yiaddr);

	if (dhcp_server->event_fn)
		dhcp_server->event_fn(ether_ntoa((void*)packet.chaddr),
				      inet_ntoa(addr),
				      dhcp_server->fn_data);
}
Beispiel #4
0
static void send_inform(GDHCPServer *dhcp_server,
				struct dhcp_packet *client_packet)
{
	struct dhcp_packet packet;

	init_packet(dhcp_server, &packet, client_packet, DHCPACK);
	add_server_options(dhcp_server, &packet);
	send_packet_to_client(dhcp_server, &packet);
}
Beispiel #5
0
static void send_offer(GDHCPServer *dhcp_server,
			struct dhcp_packet *client_packet,
				struct dhcp_lease *lease,
					uint32_t requested_nip)
{
	struct dhcp_packet packet;
	struct in_addr addr;

	init_packet(dhcp_server, &packet, client_packet, DHCPOFFER);

	if (lease)
		packet.yiaddr = htonl(lease->lease_nip);
	else if (check_requested_nip(dhcp_server, requested_nip))
		packet.yiaddr = htonl(requested_nip);
	else
		packet.yiaddr = htonl(find_free_or_expired_nip(
					dhcp_server, client_packet->chaddr));

	debug(dhcp_server, "find yiaddr %u", packet.yiaddr);

	if (!packet.yiaddr) {
		debug(dhcp_server, "Err: Can not found lease and send offer");
		return;
	}

	lease = add_lease(dhcp_server, OFFER_TIME,
				packet.chaddr, packet.yiaddr);
	if (!lease) {
		debug(dhcp_server,
				"Err: No free IP addresses. OFFER abandoned");
		return;
	}

	dhcp_add_option_uint32(&packet, DHCP_LEASE_TIME,
						dhcp_server->lease_seconds);
	add_server_options(dhcp_server, &packet);

	addr.s_addr = packet.yiaddr;

	debug(dhcp_server, "Sending OFFER of %s", inet_ntoa(addr));
	send_packet_to_client(dhcp_server, &packet);
}
// update everyone on the current netgame options
void multi_options_update_netgame()
{
	ubyte data[MAX_PACKET_SIZE],code;
	int packet_size = 0;
	
	Assert(Net_player->flags & NETINFO_FLAG_GAME_HOST);

	// build the header and add the opcode
	BUILD_HEADER(OPTIONS_UPDATE);
	code = MULTI_OPTION_SERVER;
	ADD_DATA(code);

	// add the netgame options
	add_server_options(data, &packet_size, &Netgame.options);

	// send the packet
	if(Net_player->flags & NETINFO_FLAG_AM_MASTER){
		multi_io_send_to_all_reliable(data, packet_size);
	} else {
		multi_io_send_reliable(Net_player, data, packet_size);
	}
}
Beispiel #7
0
static void send_ACK(GDHCPServer *dhcp_server,
		struct dhcp_packet *client_packet, uint32_t yiaddr)
{
	struct dhcp_packet packet;
	uint32_t lease_time_sec;
	struct in_addr addr;

	init_packet(dhcp_server, &packet, client_packet, DHCPACK);
	packet.yiaddr = yiaddr;

	lease_time_sec = dhcp_server->lease_seconds;

	dhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec));

	add_server_options(dhcp_server, &packet);

	addr.s_addr = yiaddr;

	debug(dhcp_server, "Sending ACK to %s", inet_ntoa(addr));

	send_packet_to_client(dhcp_server, &packet);

	add_lease(dhcp_server, 0, packet.chaddr, packet.yiaddr);
}
Beispiel #8
0
/* NOINLINE: limit stack usage in caller */
static NOINLINE void send_offer(struct dhcp_packet *oldpacket,
		uint32_t static_lease_nip,
		struct dyn_lease *lease,
		uint8_t *requested_ip_opt,
		unsigned arpping_ms)
{
	struct dhcp_packet packet;
	uint32_t lease_time_sec;
	struct in_addr addr;

	init_packet(&packet, oldpacket, DHCPOFFER);

	/* If it is a static lease, use its IP */
	packet.yiaddr = static_lease_nip;
	/* Else: */
	if (!static_lease_nip) {
		/* We have no static lease for client's chaddr */
		uint32_t req_nip;
		const char *p_host_name;

		if (lease) {
			/* We have a dynamic lease for client's chaddr.
			 * Reuse its IP (even if lease is expired).
			 * Note that we ignore requested IP in this case.
			 */
			packet.yiaddr = lease->lease_nip;
		}
		/* Or: if client has requested an IP */
		else if (requested_ip_opt != NULL
		 /* (read IP) */
		 && (move_from_unaligned32(req_nip, requested_ip_opt), 1)
		 /* and the IP is in the lease range */
		 && ntohl(req_nip) >= server_config.start_ip
		 && ntohl(req_nip) <= server_config.end_ip
		 /* and */
		 && (  !(lease = find_lease_by_nip(req_nip)) /* is not already taken */
		    || is_expired_lease(lease) /* or is taken, but expired */
		    )
		) {
			packet.yiaddr = req_nip;
		}
		else {
			/* Otherwise, find a free IP */
			packet.yiaddr = find_free_or_expired_nip(oldpacket->chaddr, arpping_ms);
		}

		if (!packet.yiaddr) {
			bb_error_msg("no free IP addresses. OFFER abandoned");
			return;
		}
		/* Reserve the IP for a short time hoping to get DHCPREQUEST soon */
		p_host_name = (const char*) udhcp_get_option(oldpacket, DHCP_HOST_NAME);
		lease = add_lease(packet.chaddr, packet.yiaddr,
				server_config.offer_time,
				p_host_name,
				p_host_name ? (unsigned char)p_host_name[OPT_LEN - OPT_DATA] : 0
		);
		if (!lease) {
			bb_error_msg("no free IP addresses. OFFER abandoned");
			return;
		}
	}

	lease_time_sec = select_lease_time(oldpacket);
	udhcp_add_simple_option(&packet, DHCP_LEASE_TIME, htonl(lease_time_sec));
	add_server_options(&packet);

	addr.s_addr = packet.yiaddr;
	bb_info_msg("Sending OFFER of %s", inet_ntoa(addr));
	/* send_packet emits error message itself if it detects failure */
	send_packet(&packet, /*force_bcast:*/ 0);
}