⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dhclient.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 5 页
字号:
	i  = DHO_DHCP_PARAMETER_REQUEST_LIST;
	options[i] = &option_elements[i];
	options[i]->value = ip->client->config->requested_options;
	options[i]->len = ip->client->config->requested_option_count;
	options[i]->buf_size =
		ip->client->config->requested_option_count;
	options[i]->timeout = 0xFFFFFFFF;

	/* If we had an address, try to get it again. */
	if (lease) {
		ip->client->requested_address = lease->address;
		i = DHO_DHCP_REQUESTED_ADDRESS;
		options[i] = &option_elements[i];
		options[i]->value = lease->address.iabuf;
		options[i]->len = lease->address.len;
		options[i]->buf_size = lease->address.len;
		options[i]->timeout = 0xFFFFFFFF;
	} else
		ip->client->requested_address.len = 0;

	/* Send any options requested in the config file. */
	for (i = 0; i < 256; i++)
		if (!options[i] &&
		    ip->client->config->send_options[i].data) {
			options[i] = &option_elements[i];
			options[i]->value =
			    ip->client->config->send_options[i].data;
			options[i]->len =
			    ip->client->config->send_options[i].len;
			options[i]->buf_size =
			    ip->client->config->send_options[i].len;
			options[i]->timeout = 0xFFFFFFFF;
		}

	/* Set up the option buffer... */
	ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
	    options, 0, 0, 0, NULL, 0);
	if (ip->client->packet_length < BOOTP_MIN_LEN)
		ip->client->packet_length = BOOTP_MIN_LEN;

	ip->client->packet.op = BOOTREQUEST;
	ip->client->packet.htype = ip->hw_address.htype;
	ip->client->packet.hlen = ip->hw_address.hlen;
	ip->client->packet.hops = 0;
	ip->client->packet.xid = RtlRandom(&foo);
	ip->client->packet.secs = 0; /* filled in by send_discover. */
	ip->client->packet.flags = 0;

	memset(&(ip->client->packet.ciaddr),
	    0, sizeof(ip->client->packet.ciaddr));
	memset(&(ip->client->packet.yiaddr),
	    0, sizeof(ip->client->packet.yiaddr));
	memset(&(ip->client->packet.siaddr),
	    0, sizeof(ip->client->packet.siaddr));
	memset(&(ip->client->packet.giaddr),
	    0, sizeof(ip->client->packet.giaddr));
	memcpy(ip->client->packet.chaddr,
	    ip->hw_address.haddr, ip->hw_address.hlen);
}


void
make_request(struct interface_info *ip, struct client_lease * lease)
{
	unsigned char request = DHCPREQUEST;
	struct tree_cache *options[256];
	struct tree_cache option_elements[256];
	int i;

	memset(options, 0, sizeof(options));
	memset(&ip->client->packet, 0, sizeof(ip->client->packet));

	/* Set DHCP_MESSAGE_TYPE to DHCPREQUEST */
	i = DHO_DHCP_MESSAGE_TYPE;
	options[i] = &option_elements[i];
	options[i]->value = &request;
	options[i]->len = sizeof(request);
	options[i]->buf_size = sizeof(request);
	options[i]->timeout = 0xFFFFFFFF;

	/* Request the options we want */
	i = DHO_DHCP_PARAMETER_REQUEST_LIST;
	options[i] = &option_elements[i];
	options[i]->value = ip->client->config->requested_options;
	options[i]->len = ip->client->config->requested_option_count;
	options[i]->buf_size =
		ip->client->config->requested_option_count;
	options[i]->timeout = 0xFFFFFFFF;

	/* If we are requesting an address that hasn't yet been assigned
	   to us, use the DHCP Requested Address option. */
	if (ip->client->state == S_REQUESTING) {
		/* Send back the server identifier... */
		i = DHO_DHCP_SERVER_IDENTIFIER;
		options[i] = &option_elements[i];
		options[i]->value = lease->options[i].data;
		options[i]->len = lease->options[i].len;
		options[i]->buf_size = lease->options[i].len;
		options[i]->timeout = 0xFFFFFFFF;
	}
	if (ip->client->state == S_REQUESTING ||
	    ip->client->state == S_REBOOTING) {
		ip->client->requested_address = lease->address;
		i = DHO_DHCP_REQUESTED_ADDRESS;
		options[i] = &option_elements[i];
		options[i]->value = lease->address.iabuf;
		options[i]->len = lease->address.len;
		options[i]->buf_size = lease->address.len;
		options[i]->timeout = 0xFFFFFFFF;
	} else
		ip->client->requested_address.len = 0;

	/* Send any options requested in the config file. */
	for (i = 0; i < 256; i++)
		if (!options[i] &&
		    ip->client->config->send_options[i].data) {
			options[i] = &option_elements[i];
			options[i]->value =
			    ip->client->config->send_options[i].data;
			options[i]->len =
			    ip->client->config->send_options[i].len;
			options[i]->buf_size =
			    ip->client->config->send_options[i].len;
			options[i]->timeout = 0xFFFFFFFF;
		}

	/* Set up the option buffer... */
	ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
	    options, 0, 0, 0, NULL, 0);
	if (ip->client->packet_length < BOOTP_MIN_LEN)
		ip->client->packet_length = BOOTP_MIN_LEN;

	ip->client->packet.op = BOOTREQUEST;
	ip->client->packet.htype = ip->hw_address.htype;
	ip->client->packet.hlen = ip->hw_address.hlen;
	ip->client->packet.hops = 0;
	ip->client->packet.xid = ip->client->xid;
	ip->client->packet.secs = 0; /* Filled in by send_request. */

	/* If we own the address we're requesting, put it in ciaddr;
	   otherwise set ciaddr to zero. */
	if (ip->client->state == S_BOUND ||
	    ip->client->state == S_RENEWING ||
	    ip->client->state == S_REBINDING) {
		memcpy(&ip->client->packet.ciaddr,
		    lease->address.iabuf, lease->address.len);
		ip->client->packet.flags = 0;
	} else {
		memset(&ip->client->packet.ciaddr, 0,
		    sizeof(ip->client->packet.ciaddr));
		ip->client->packet.flags = 0;
	}

	memset(&ip->client->packet.yiaddr, 0,
	    sizeof(ip->client->packet.yiaddr));
	memset(&ip->client->packet.siaddr, 0,
	    sizeof(ip->client->packet.siaddr));
	memset(&ip->client->packet.giaddr, 0,
	    sizeof(ip->client->packet.giaddr));
	memcpy(ip->client->packet.chaddr,
	    ip->hw_address.haddr, ip->hw_address.hlen);
}

void
make_decline(struct interface_info *ip, struct client_lease *lease)
{
	struct tree_cache *options[256], message_type_tree;
	struct tree_cache requested_address_tree;
	struct tree_cache server_id_tree, client_id_tree;
	unsigned char decline = DHCPDECLINE;
	int i;

	memset(options, 0, sizeof(options));
	memset(&ip->client->packet, 0, sizeof(ip->client->packet));

	/* Set DHCP_MESSAGE_TYPE to DHCPDECLINE */
	i = DHO_DHCP_MESSAGE_TYPE;
	options[i] = &message_type_tree;
	options[i]->value = &decline;
	options[i]->len = sizeof(decline);
	options[i]->buf_size = sizeof(decline);
	options[i]->timeout = 0xFFFFFFFF;

	/* Send back the server identifier... */
	i = DHO_DHCP_SERVER_IDENTIFIER;
	options[i] = &server_id_tree;
	options[i]->value = lease->options[i].data;
	options[i]->len = lease->options[i].len;
	options[i]->buf_size = lease->options[i].len;
	options[i]->timeout = 0xFFFFFFFF;

	/* Send back the address we're declining. */
	i = DHO_DHCP_REQUESTED_ADDRESS;
	options[i] = &requested_address_tree;
	options[i]->value = lease->address.iabuf;
	options[i]->len = lease->address.len;
	options[i]->buf_size = lease->address.len;
	options[i]->timeout = 0xFFFFFFFF;

	/* Send the uid if the user supplied one. */
	i = DHO_DHCP_CLIENT_IDENTIFIER;
	if (ip->client->config->send_options[i].len) {
		options[i] = &client_id_tree;
		options[i]->value = ip->client->config->send_options[i].data;
		options[i]->len = ip->client->config->send_options[i].len;
		options[i]->buf_size = ip->client->config->send_options[i].len;
		options[i]->timeout = 0xFFFFFFFF;
	}


	/* Set up the option buffer... */
	ip->client->packet_length = cons_options(NULL, &ip->client->packet, 0,
	    options, 0, 0, 0, NULL, 0);
	if (ip->client->packet_length < BOOTP_MIN_LEN)
		ip->client->packet_length = BOOTP_MIN_LEN;

	ip->client->packet.op = BOOTREQUEST;
	ip->client->packet.htype = ip->hw_address.htype;
	ip->client->packet.hlen = ip->hw_address.hlen;
	ip->client->packet.hops = 0;
	ip->client->packet.xid = ip->client->xid;
	ip->client->packet.secs = 0; /* Filled in by send_request. */
	ip->client->packet.flags = 0;

	/* ciaddr must always be zero. */
	memset(&ip->client->packet.ciaddr, 0,
	    sizeof(ip->client->packet.ciaddr));
	memset(&ip->client->packet.yiaddr, 0,
	    sizeof(ip->client->packet.yiaddr));
	memset(&ip->client->packet.siaddr, 0,
	    sizeof(ip->client->packet.siaddr));
	memset(&ip->client->packet.giaddr, 0,
	    sizeof(ip->client->packet.giaddr));
	memcpy(ip->client->packet.chaddr,
	    ip->hw_address.haddr, ip->hw_address.hlen);
}

void
free_client_lease(struct client_lease *lease)
{
	int i;

	if (lease->server_name)
		free(lease->server_name);
	if (lease->filename)
		free(lease->filename);
	for (i = 0; i < 256; i++) {
		if (lease->options[i].len)
			free(lease->options[i].data);
	}
	free(lease);
}

FILE *leaseFile;

void
rewrite_client_leases(void)
{
	struct client_lease *lp;

	if (!leaseFile) {
		leaseFile = fopen(path_dhclient_db, "w");
		if (!leaseFile)
			error("can't create %s: %m", path_dhclient_db);
	} else {
		fflush(leaseFile);
		rewind(leaseFile);
	}

	for (lp = ifi->client->leases; lp; lp = lp->next)
		write_client_lease(ifi, lp, 1);
	if (ifi->client->active)
		write_client_lease(ifi, ifi->client->active, 1);

	fflush(leaseFile);
}

void
write_client_lease(struct interface_info *ip, struct client_lease *lease,
    int rewrite)
{
	static int leases_written;
	struct tm *t;
	int i;

	if (!rewrite) {
		if (leases_written++ > 20) {
			rewrite_client_leases();
			leases_written = 0;
		}
	}

	/* If the lease came from the config file, we don't need to stash
	   a copy in the lease database. */
	if (lease->is_static)
		return;

	if (!leaseFile) {	/* XXX */
		leaseFile = fopen(path_dhclient_db, "w");
		if (!leaseFile)
			error("can't create %s: %m", path_dhclient_db);
	}

	fprintf(leaseFile, "lease {\n");
	if (lease->is_bootp)
		fprintf(leaseFile, "  bootp;\n");
	fprintf(leaseFile, "  interface \"%s\";\n", ip->name);
	fprintf(leaseFile, "  fixed-address %s;\n", piaddr(lease->address));
	if (lease->filename)
		fprintf(leaseFile, "  filename \"%s\";\n", lease->filename);
	if (lease->server_name)
		fprintf(leaseFile, "  server-name \"%s\";\n",
		    lease->server_name);
	if (lease->medium)
		fprintf(leaseFile, "  medium \"%s\";\n", lease->medium->string);
	for (i = 0; i < 256; i++)
		if (lease->options[i].len)
			fprintf(leaseFile, "  option %s %s;\n",
			    dhcp_options[i].name,
			    pretty_print_option(i, lease->options[i].data,
			    lease->options[i].len, 1, 1));

	t = gmtime(&lease->renewal);
	fprintf(leaseFile, "  renew %d %d/%d/%d %02d:%02d:%02d;\n",
	    t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
	    t->tm_hour, t->tm_min, t->tm_sec);
	t = gmtime(&lease->rebind);
	fprintf(leaseFile, "  rebind %d %d/%d/%d %02d:%02d:%02d;\n",
	    t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
	    t->tm_hour, t->tm_min, t->tm_sec);
	t = gmtime(&lease->expiry);
	fprintf(leaseFile, "  expire %d %d/%d/%d %02d:%02d:%02d;\n",
	    t->tm_wday, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
	    t->tm_hour, t->tm_min, t->tm_sec);
	fprintf(leaseFile, "}\n");
	fflush(leaseFile);
}

void
script_init(char *reason, struct string_list *medium)
{
	size_t		 len, mediumlen = 0;
	struct imsg_hdr	 hdr;
	struct buf	*buf;
	int		 errs;

	if (medium != NULL && medium->string != NULL)
		mediumlen = strlen(medium->string);

	hdr.code = IMSG_SCRIPT_INIT;
	hdr.len = sizeof(struct imsg_hdr) +
	    sizeof(size_t) + mediumlen +
	    sizeof(size_t) + strlen(reason);

	if ((buf = buf_open(hdr.len)) == NULL)
		error("buf_open: %m");

	errs = 0;
	errs += buf_add(buf, &hdr, sizeof(hdr));
	errs += buf_add(buf, &mediumlen, sizeof(mediumlen));
	if (mediumlen > 0)
		errs += buf_add(buf, medium->string, mediumlen);
	len = strlen(reason);
	errs += buf_add(buf, &len, sizeof(len));
	errs += buf_add(buf, reason, len);

	if (errs)
		error("buf_add: %m");

	if (buf_close(privfd, buf) == -1)
		error("buf_close: %m");
}

void
priv_script_init(char *reason, char *medium)
{
	struct interface_info *ip = ifi;

	if (ip) {
            // XXX Do we need to do anything?
        }
}

void
priv_script_write_params(char *prefix, struct client_lease *lease)
{
	struct interface_info *ip = ifi;
	u_int8_t dbuf[1500];
	int i, len = 0;

#if 0
	script_set_env(ip->client, prefix, "ip_address",
	    piaddr(lease->address));
#endif

	if (lease->options[DHO_SUBNET_MASK].len &&
	    (lease->options[DHO_SUBNET_MASK].len <
	    sizeof(lease->address.iabuf))) {
		struct iaddr netmask, subnet, broadcast;

		memcpy(netmask.iabuf, lease->options[DHO_SUBNET_MASK].data,
		    lease->options[DHO_SUBNET_MASK].len);
		netmask.len = lease->options[DHO_SUBNET_MASK].len;

		subnet = subnet_number(lease->address, netmask);
		if (subnet.len) {
#if 0
			script_set_env(ip->client, prefix, "network_number",
			    piaddr(subnet));
#endif
			if (!lease->options[DHO_BROADCAST_ADDRESS].len) {
				broadcast = broadcast_addr(subnet, netmask);
				if (broadcast.len)
#if 0
					script_set_env(ip->client, prefix,
					    "broadcast_address",
					    piaddr(broadcast));
#else
                                ;
#endif
			}
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -