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

📄 dhclient.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	dmalloc_longterm = dmalloc_outstanding;	dmalloc_outstanding = 0;#endif	/* If we're not supposed to wait before getting the address,	   don't. */	if (nowait)		go_daemon ();	/* If we're not going to daemonize, write the pid file	   now. */	if (no_daemon || nowait)		write_client_pid_file ();	/* Start dispatching packets and timeouts... */	dispatch ();	/*NOTREACHED*/	return 0;}static void usage (){	log_info ("%s %s", message, DHCP_VERSION);	log_info (copyright);	log_info (arr);	log_info (url);	log_error ("Usage: dhclient [-1dqr] [-nw] [-p <port>] %s",		   "[-s server]");	log_error ("                [-cf config-file] [-lf lease-file]%s",		   "[-pf pid-file] [-e VAR=val]");	log_fatal ("                [-sf script-file] [interface]");}isc_result_t find_class (struct class **c,		const char *s, const char *file, int line){	return 0;}int check_collection (packet, lease, collection)	struct packet *packet;	struct lease *lease;	struct collection *collection;{	return 0;}void classify (packet, class)	struct packet *packet;	struct class *class;{}int unbill_class (lease, class)	struct lease *lease;	struct class *class;{	return 0;}int find_subnet (struct subnet **sp,		 struct iaddr addr, const char *file, int line){	return 0;}/* Individual States: *  * Each routine is called from the dhclient_state_machine() in one of * these conditions: * -> entering INIT state * -> recvpacket_flag == 0: timeout in this state * -> otherwise: received a packet in this state * * Return conditions as handled by dhclient_state_machine(): * Returns 1, sendpacket_flag = 1: send packet, reset timer. * Returns 1, sendpacket_flag = 0: just reset the timer (wait for a milestone). * Returns 0: finish the nap which was interrupted for no good reason. * * Several per-interface variables are used to keep track of the process: *   active_lease: the lease that is being used on the interface *                 (null pointer if not configured yet). *   offered_leases: leases corresponding to DHCPOFFER messages that have *		     been sent to us by DHCP servers. *   acked_leases: leases corresponding to DHCPACK messages that have been *		   sent to us by DHCP servers. *   sendpacket: DHCP packet we're trying to send. *   destination: IP address to send sendpacket to * In addition, there are several relevant per-lease variables. *   T1_expiry, T2_expiry, lease_expiry: lease milestones * In the active lease, these control the process of renewing the lease; * In leases on the acked_leases list, this simply determines when we * can no longer legitimately use the lease. */void state_reboot (cpp)	void *cpp;{	struct client_state *client = cpp;	/* If we don't remember an active lease, go straight to INIT. */	if (!client -> active ||	    client -> active -> is_bootp ||	    client -> active -> expiry <= cur_time) {		state_init (client);		return;	}	/* We are in the rebooting state. */	client -> state = S_REBOOTING;	/* make_request doesn't initialize xid because it normally comes	   from the DHCPDISCOVER, but we haven't sent a DHCPDISCOVER,	   so pick an xid now. */	client -> xid = random ();	/* Make a DHCPREQUEST packet, and set appropriate per-interface	   flags. */	make_request (client, client -> active);	client -> destination = iaddr_broadcast;	client -> first_sending = cur_time;	client -> interval = client -> config -> initial_interval;	/* Zap the medium list... */	client -> medium = (struct string_list *)0;	/* Send out the first DHCPREQUEST packet. */	send_request (client);}/* Called when a lease has completely expired and we've been unable to   renew it. */void state_init (cpp)	void *cpp;{	struct client_state *client = cpp;	ASSERT_STATE(state, S_INIT);	/* Make a DHCPDISCOVER packet, and set appropriate per-interface	   flags. */	make_discover (client, client -> active);	client -> xid = client -> packet.xid;	client -> destination = iaddr_broadcast;	client -> state = S_SELECTING;	client -> first_sending = cur_time;	client -> interval = client -> config -> initial_interval;	/* Add an immediate timeout to cause the first DHCPDISCOVER packet	   to go out. */	send_discover (client);}/* state_selecting is called when one or more DHCPOFFER packets have been   received and a configurable period of time has passed. */void state_selecting (cpp)	void *cpp;{	struct client_state *client = cpp;	struct client_lease *lp, *next, *picked;	ASSERT_STATE(state, S_SELECTING);	/* Cancel state_selecting and send_discover timeouts, since either	   one could have got us here. */	cancel_timeout (state_selecting, client);	cancel_timeout (send_discover, client);	/* We have received one or more DHCPOFFER packets.   Currently,	   the only criterion by which we judge leases is whether or	   not we get a response when we arp for them. */	picked = (struct client_lease *)0;	for (lp = client -> offered_leases; lp; lp = next) {		next = lp -> next;		/* Check to see if we got an ARPREPLY for the address		   in this particular lease. */		if (!picked) {			picked = lp;			picked -> next = (struct client_lease *)0;		} else {		      freeit:			destroy_client_lease (lp);		}	}	client -> offered_leases = (struct client_lease *)0;	/* If we just tossed all the leases we were offered, go back	   to square one. */	if (!picked) {		client -> state = S_INIT;		state_init (client);		return;	}	/* If it was a BOOTREPLY, we can just take the address right now. */	if (picked -> is_bootp) {		client -> new = picked;		/* Make up some lease expiry times		   XXX these should be configurable. */		client -> new -> expiry = cur_time + 12000;		client -> new -> renewal += cur_time + 8000;		client -> new -> rebind += cur_time + 10000;		client -> state = S_REQUESTING;		/* Bind to the address we received. */		bind_lease (client);		return;	}	/* Go to the REQUESTING state. */	client -> destination = iaddr_broadcast;	client -> state = S_REQUESTING;	client -> first_sending = cur_time;	client -> interval = client -> config -> initial_interval;	/* Make a DHCPREQUEST packet from the lease we picked. */	make_request (client, picked);	client -> xid = client -> packet.xid;	/* Toss the lease we picked - we'll get it back in a DHCPACK. */	destroy_client_lease (picked);	/* Add an immediate timeout to send the first DHCPREQUEST packet. */	send_request (client);}  /* state_requesting is called when we receive a DHCPACK message after   having sent out one or more DHCPREQUEST packets. */void dhcpack (packet)	struct packet *packet;{	struct interface_info *ip = packet -> interface;	struct client_state *client;	struct client_lease *lease;	struct option_cache *oc;	struct data_string ds;	int i;		/* If we're not receptive to an offer right now, or if the offer	   has an unrecognizable transaction id, then just drop it. */	for (client = ip -> client; client; client = client -> next) {		if (client -> xid == packet -> raw -> xid)			break;	}	if (!client ||	    (packet -> interface -> hw_address.hlen - 1 !=	     packet -> raw -> hlen) ||	    (memcmp (&packet -> interface -> hw_address.hbuf [1],		     packet -> raw -> chaddr, packet -> raw -> hlen))) {#if defined (DEBUG)		log_debug ("DHCPACK in wrong transaction.");#endif		return;	}	if (client -> state != S_REBOOTING &&	    client -> state != S_REQUESTING &&	    client -> state != S_RENEWING &&	    client -> state != S_REBINDING) {#if defined (DEBUG)		log_debug ("DHCPACK in wrong state.");#endif		return;	}	log_info ("DHCPACK from %s", piaddr (packet -> client_addr));	lease = packet_to_lease (packet, client);	if (!lease) {		log_info ("packet_to_lease failed.");		return;	}	client -> new = lease;	/* Stop resending DHCPREQUEST. */	cancel_timeout (send_request, client);	/* Figure out the lease time. */	oc = lookup_option (&dhcp_universe, client -> new -> options,			    DHO_DHCP_LEASE_TIME);	memset (&ds, 0, sizeof ds);	if (oc &&	    evaluate_option_cache (&ds, packet, (struct lease *)0, client,				   packet -> options, client -> new -> options,				   &global_scope, oc, MDL)) {		if (ds.len > 3)			client -> new -> expiry = getULong (ds.data);		else			client -> new -> expiry = 0;		data_string_forget (&ds, MDL);	} else			client -> new -> expiry = 0;	if (!client -> new -> expiry) {		log_error ("no expiry time on offered lease.");		/* XXX this is going to be bad - if this _does_		   XXX happen, we should probably dynamically 		   XXX disqualify the DHCP server that gave us the		   XXX bad packet from future selections and		   XXX then go back into the init state. */		state_init (client);		return;	}	/* A number that looks negative here is really just very large,	   because the lease expiry offset is unsigned. */	if (client -> new -> expiry < 0)		client -> new -> expiry = TIME_MAX;	/* Take the server-provided renewal time if there is one. */	oc = lookup_option (&dhcp_universe, client -> new -> options,			    DHO_DHCP_RENEWAL_TIME);	if (oc &&	    evaluate_option_cache (&ds, packet, (struct lease *)0, client,				   packet -> options, client -> new -> options,				   &global_scope, oc, MDL)) {		if (ds.len > 3)			client -> new -> renewal = getULong (ds.data);		else			client -> new -> renewal = 0;		data_string_forget (&ds, MDL);	} else			client -> new -> renewal = 0;	/* If it wasn't specified by the server, calculate it. */	if (!client -> new -> renewal)		client -> new -> renewal = client -> new -> expiry / 2 + 1;	if (client -> new -> renewal <= 0)		client -> new -> renewal = TIME_MAX;	/* Now introduce some randomness to the renewal time: */	if (client -> new -> renewal <= TIME_MAX / 3 - 3)		client -> new -> renewal =				(((client -> new -> renewal + 3) * 3 / 4) +				    (random () % /* XXX NUMS */				     ((client -> new -> renewal + 3) / 4)));	/* Same deal with the rebind time. */	oc = lookup_option (&dhcp_universe, client -> new -> options,			    DHO_DHCP_REBINDING_TIME);	if (oc &&	    evaluate_option_cache (&ds, packet, (struct lease *)0, client,				   packet -> options, client -> new -> options,				   &global_scope, oc, MDL)) {		if (ds.len > 3)			client -> new -> rebind = getULong (ds.data);		else			client -> new -> rebind = 0;		data_string_forget (&ds, MDL);	} else			client -> new -> rebind = 0;	if (client -> new -> rebind <= 0) {		if (client -> new -> expiry <= TIME_MAX / 7)			client -> new -> rebind =					client -> new -> expiry * 7 / 8;		else			client -> new -> rebind =					client -> new -> expiry / 8 * 7;	}	/* Make sure our randomness didn't run the renewal time past the	   rebind time. */	if (client -> new -> renewal > client -> new -> rebind) {		if (client -> new -> rebind <= TIME_MAX / 3)			client -> new -> renewal =					client -> new -> rebind * 3 / 4;		else			client -> new -> renewal =					client -> new -> rebind / 4 * 3;	}	client -> new -> expiry += cur_time;	/* Lease lengths can never be negative. */	if (client -> new -> expiry < cur_time)		client -> new -> expiry = TIME_MAX;	client -> new -> renewal += cur_time;	if (client -> new -> renewal < cur_time)		client -> new -> renewal = TIME_MAX;	client -> new -> rebind += cur_time;	if (client -> new -> rebind < cur_time)		client -> new -> rebind = TIME_MAX;	bind_lease (client);}void bind_lease (client)	struct client_state *client;{	struct interface_info *ip = client -> interface;	/* Remember the medium. */	client -> new -> medium = client -> medium;	/* Run the client script with the new parameters. */	script_init (client, (client -> state == S_REQUESTING			  ? "BOUND"			  : (client -> state == S_RENEWING			     ? "RENEW"			     : (client -> state == S_REBOOTING				? "REBOOT" : "REBIND"))),		     client -> new -> medium);	if (client -> active && client -> state != S_REBOOTING)		script_write_params (client, "old_", client -> active);	script_write_params (client, "new_", client -> new);	if (client -> alias)		script_write_params (client, "alias_", client -> alias);	/* If the BOUND/RENEW code detects another machine using the	   offered address, it exits nonzero.  We need to send a	   DHCPDECLINE and toss the lease. */	if (script_go (client)) {		make_decline (client, client -> new);		send_decline (client);		destroy_client_lease (client -> new);		client -> new = (struct client_lease *)0;		state_init (client);		return;	}	/* Write out the new lease. */	write_client_lease (client, client -> new, 0, 0);	/* Replace the old active lease with the new one. */	if (client -> active)		destroy_client_lease (client -> active);	client -> active = client -> new;	client -> new = (struct client_lease *)0;	/* Set up a timeout to start the renewal process. */	add_timeout (client -> active -> renewal,		     state_bound, client, 0, 0);	log_info ("bound to %s -- renewal in %ld seconds.",	      piaddr (client -> active -> address),	      (long)(client -> active -> renewal - cur_time));	client -> state = S_BOUND;	reinitialize_interfaces ();	go_daemon ();	if (client -> config -> do_forward_update) {

⌨️ 快捷键说明

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