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

📄 dhclient.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		client -> dns_update_timeout = 1;		add_timeout (cur_time + 1, client_dns_update_timeout,			     client, 0, 0);	}}  /* state_bound is called when we've successfully bound to a particular   lease, but the renewal time on that lease has expired.   We are   expected to unicast a DHCPREQUEST to the server that gave us our   original lease. */void state_bound (cpp)	void *cpp;{	struct client_state *client = cpp;	int i;	struct option_cache *oc;	struct data_string ds;	ASSERT_STATE(state, S_BOUND);	/* T1 has expired. */	make_request (client, client -> active);	client -> xid = client -> packet.xid;	memset (&ds, 0, sizeof ds);	oc = lookup_option (&dhcp_universe, client -> active -> options,			    DHO_DHCP_SERVER_IDENTIFIER);	if (oc &&	    evaluate_option_cache (&ds, (struct packet *)0, (struct lease *)0,				   client, (struct option_state *)0,				   client -> active -> options,				   &global_scope, oc, MDL)) {		if (ds.len > 3) {			memcpy (client -> destination.iabuf, ds.data, 4);			client -> destination.len = 4;		} else			client -> destination = iaddr_broadcast;	} else		client -> destination = iaddr_broadcast;	client -> first_sending = cur_time;	client -> interval = client -> config -> initial_interval;	client -> state = S_RENEWING;	/* Send the first packet immediately. */	send_request (client);}  /* state_stop is called when we've been told to shut down.   We unconfigure   the interfaces, and then stop operating until told otherwise. */void state_stop (cpp)	void *cpp;{	struct client_state *client = cpp;	int i;	/* Cancel all timeouts. */	cancel_timeout (state_selecting, client);	cancel_timeout (send_discover, client);	cancel_timeout (send_request, client);	cancel_timeout (state_bound, client);	/* If we have an address, unconfigure it. */	if (client -> active) {		script_init (client, "STOP", client -> active -> medium);		script_write_params (client, "old_", client -> active);		if (client -> alias)			script_write_params (client, "alias_",					     client -> alias);		script_go (client);	}}  int commit_leases (){	return 0;}int write_lease (lease)	struct lease *lease;{	return 0;}int write_host (host)	struct host_decl *host;{	return 0;}void db_startup (testp)	int testp;{}void bootp (packet)	struct packet *packet;{	struct iaddrlist *ap;	if (packet -> raw -> op != BOOTREPLY)		return;	/* If there's a reject list, make sure this packet's sender isn't	   on it. */	for (ap = packet -> interface -> client -> config -> reject_list;	     ap; ap = ap -> next) {		if (addr_eq (packet -> client_addr, ap -> addr)) {			log_info ("BOOTREPLY from %s rejected.",			      piaddr (ap -> addr));			return;		}	}		dhcpoffer (packet);}void dhcp (packet)	struct packet *packet;{	struct iaddrlist *ap;	void (*handler) PROTO ((struct packet *));	const char *type;	switch (packet -> packet_type) {	      case DHCPOFFER:		handler = dhcpoffer;		type = "DHCPOFFER";		break;	      case DHCPNAK:		handler = dhcpnak;		type = "DHCPNACK";		break;	      case DHCPACK:		handler = dhcpack;		type = "DHCPACK";		break;	      default:		return;	}	/* If there's a reject list, make sure this packet's sender isn't	   on it. */	for (ap = packet -> interface -> client -> config -> reject_list;	     ap; ap = ap -> next) {		if (addr_eq (packet -> client_addr, ap -> addr)) {			log_info ("%s from %s rejected.",			      type, piaddr (ap -> addr));			return;		}	}	(*handler) (packet);}void dhcpoffer (packet)	struct packet *packet;{	struct interface_info *ip = packet -> interface;	struct client_state *client;	struct client_lease *lease, *lp;	int i;	int stop_selecting;	const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";	struct iaddrlist *ap;	struct option_cache *oc;	char obuf [1024];	#ifdef DEBUG_PACKET	dump_packet (packet);#endif		/* Find a client state that matches the xid... */	for (client = ip -> client; client; client = client -> next)		if (client -> xid == packet -> raw -> xid)			break;	/* If we're not receptive to an offer right now, or if the offer	   has an unrecognizable transaction id, then just drop it. */	if (!client ||	    client -> state != S_SELECTING ||	    (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 ("%s in wrong transaction.", name);#endif		return;	}	sprintf (obuf, "%s from %s", name, piaddr (packet -> client_addr));	/* If this lease doesn't supply the minimum required parameters,	   blow it off. */	if (client -> config -> required_options) {	    for (i = 0; client -> config -> required_options [i]; i++) {		if (!lookup_option		    (&dhcp_universe, packet -> options,		     client -> config -> required_options [i])) {		    log_info ("%s: no %s option.",			      obuf, (dhcp_universe.options				     [client -> config -> required_options [i]]				     -> name));				return;			}		}	}	/* If we've already seen this lease, don't record it again. */	for (lease = client -> offered_leases; lease; lease = lease -> next) {		if (lease -> address.len == sizeof packet -> raw -> yiaddr &&		    !memcmp (lease -> address.iabuf,			     &packet -> raw -> yiaddr, lease -> address.len)) {			log_debug ("%s: already seen.", obuf);			return;		}	}	lease = packet_to_lease (packet, client);	if (!lease) {		log_info ("%s: packet_to_lease failed.", obuf);		return;	}	/* If this lease was acquired through a BOOTREPLY, record that	   fact. */	if (!packet -> options_valid || !packet -> packet_type)		lease -> is_bootp = 1;	/* Record the medium under which this lease was offered. */	lease -> medium = client -> medium;	/* Figure out when we're supposed to stop selecting. */	stop_selecting = (client -> first_sending +			  client -> config -> select_interval);	/* If this is the lease we asked for, put it at the head of the	   list, and don't mess with the arp request timeout. */	if (lease -> address.len == client -> requested_address.len &&	    !memcmp (lease -> address.iabuf,		     client -> requested_address.iabuf,		     client -> requested_address.len)) {		lease -> next = client -> offered_leases;		client -> offered_leases = lease;	} else {		/* Put the lease at the end of the list. */		lease -> next = (struct client_lease *)0;		if (!client -> offered_leases)			client -> offered_leases = lease;		else {			for (lp = client -> offered_leases; lp -> next;			     lp = lp -> next)				;			lp -> next = lease;		}	}	/* If the selecting interval has expired, go immediately to	   state_selecting().  Otherwise, time out into	   state_selecting at the select interval. */	if (stop_selecting <= 0)		state_selecting (client);	else {		add_timeout (stop_selecting, state_selecting, client, 0, 0);		cancel_timeout (send_discover, client);	}	log_info ("%s", obuf);}/* Allocate a client_lease structure and initialize it from the parameters   in the specified packet. */struct client_lease *packet_to_lease (packet, client)	struct packet *packet;	struct client_state *client;{	struct client_lease *lease;	unsigned i;	struct option_cache *oc;	struct data_string data;	lease = (struct client_lease *)new_client_lease (MDL);	if (!lease) {		log_error ("packet_to_lease: no memory to record lease.\n");		return (struct client_lease *)0;	}	memset (lease, 0, sizeof *lease);	/* Copy the lease options. */	option_state_reference (&lease -> options, packet -> options, MDL);	lease -> address.len = sizeof (packet -> raw -> yiaddr);	memcpy (lease -> address.iabuf, &packet -> raw -> yiaddr,		lease -> address.len);	memset (&data, 0, sizeof data);	if (client -> config -> vendor_space_name) {		i = DHO_VENDOR_ENCAPSULATED_OPTIONS;		/* See if there was a vendor encapsulation option. */		oc = lookup_option (&dhcp_universe, lease -> options, i);		if (oc &&		    client -> config -> vendor_space_name &&		    evaluate_option_cache (&data, packet,					   (struct lease *)0, client,					   packet -> options, lease -> options,					   &global_scope, oc, MDL)) {			if (data.len) {				parse_encapsulated_suboptions					(packet -> options, &dhcp_options [i],					 data.data, data.len, &dhcp_universe,					 client -> config -> vendor_space_name						);			}			data_string_forget (&data, MDL);		}	} else		i = 0;	/* Figure out the overload flag. */	oc = lookup_option (&dhcp_universe, lease -> options,			    DHO_DHCP_OPTION_OVERLOAD);	if (oc &&	    evaluate_option_cache (&data, packet, (struct lease *)0, client,				   packet -> options, lease -> options,				   &global_scope, oc, MDL)) {		if (data.len > 0)			i = data.data [0];		else			i = 0;		data_string_forget (&data, MDL);	} else		i = 0;	/* If the server name was filled out, copy it. */	if (!(i & 2) && packet -> raw -> sname [0]) {		unsigned len;		/* Don't count on the NUL terminator. */		for (len = 0; len < 64; len++)			if (!packet -> raw -> sname [len])				break;		lease -> server_name = dmalloc (len + 1, MDL);		if (!lease -> server_name) {			log_error ("dhcpoffer: no memory for filename.\n");			destroy_client_lease (lease);			return (struct client_lease *)0;		} else {			memcpy (lease -> server_name,				packet -> raw -> sname, len);			lease -> server_name [len] = 0;		}	}	/* Ditto for the filename. */	if (!(i & 1) && packet -> raw -> file [0]) {		unsigned len;		/* Don't count on the NUL terminator. */		for (len = 0; len < 64; len++)			if (!packet -> raw -> file [len])				break;		lease -> filename = dmalloc (len + 1, MDL);		if (!lease -> filename) {			log_error ("dhcpoffer: no memory for filename.\n");			destroy_client_lease (lease);			return (struct client_lease *)0;		} else {			memcpy (lease -> filename,				packet -> raw -> file, len);			lease -> filename [len] = 0;		}	}	execute_statements_in_scope ((struct binding_value **)0,				     (struct packet *)packet,				     (struct lease *)0, client,				     lease -> options, lease -> options,				     &global_scope,				     client -> config -> on_receipt,				     (struct group *)0);	return lease;}	void dhcpnak (packet)	struct packet *packet;{	struct interface_info *ip = packet -> interface;	struct client_state *client;	/* Find a client state that matches the xid... */	for (client = ip -> client; client; client = client -> next)		if (client -> xid == packet -> raw -> xid)			break;	/* If we're not receptive to an offer right now, or if the offer	   has an unrecognizable transaction id, then just drop it. */	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 ("DHCPNAK 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 ("DHCPNAK in wrong state.");#endif		return;	}	log_info ("DHCPNAK from %s", piaddr (packet -> client_addr));	if (!client -> active) {#if defined (DEBUG)		log_info ("DHCPNAK with no active lease.\n");#endif		return;	}	destroy_client_lease (client -> active);	client -> active = (struct client_lease *)0;	/* Stop sending DHCPREQUEST packets... */	cancel_timeout (send_request, client);	client -> state = S_INIT;	state_init (client);}/* Send out a DHCPDISCOVER packet, and set a timeout to send out another   one after the right interval has expired.  If we don't get an offer by   the time we reach the panic interval, call the panic function. */

⌨️ 快捷键说明

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