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

📄 dhcp.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
		    find_lease_by_hw_addr			    (&seek, lease -> hardware_addr.hbuf,			     lease -> hardware_addr.hlen, MDL);		    if (!seek)			    break;		    if (seek == lease && !seek -> n_hw) {			    lease_dereference (&seek, MDL);			    break;		    }		    next = (struct lease *)0;		    while (seek) {			if (seek -> n_hw)			    lease_reference (&next, seek -> n_hw, MDL);			if (seek != lease &&			    seek -> binding_state != FTS_RELEASED &&			    seek -> binding_state != FTS_EXPIRED &&			    seek -> binding_state != FTS_RESET &&			    seek -> binding_state != FTS_FREE &&			    seek -> binding_state != FTS_BACKUP)				break;			lease_dereference (&seek, MDL);			if (next) {			    lease_reference (&seek, next, MDL);			    lease_dereference (&next, MDL);			}		    }		    if (next)			lease_dereference (&next, MDL);		    if (seek) {			release_lease (seek, packet);			lease_dereference (&seek, MDL);		    } else			break;		} while (1);	    }	}		/* Make sure this packet satisfies the configured minimum	   number of seconds. */	memset (&d1, 0, sizeof d1);	if (offer == DHCPOFFER &&	    (oc = lookup_option (&server_universe, state -> options,				 SV_MIN_SECS))) {		if (evaluate_option_cache (&d1, packet, lease,					   (struct client_state *)0,					   packet -> options, state -> options,					   &lease -> scope, oc, MDL)) {			if (d1.len &&			    ntohs (packet -> raw -> secs) < d1.data [0]) {				log_info ("%s: %d secs < %d", msg,					  ntohs (packet -> raw -> secs),					  d1.data [0]);				data_string_forget (&d1, MDL);				free_lease_state (state, MDL);				return;			}			data_string_forget (&d1, MDL);		}	}	/* Try to find a matching host declaration for this lease. */	if (!lease -> host) {		struct host_decl *hp = (struct host_decl *)0;		struct host_decl *h;		/* Try to find a host_decl that matches the client		   identifier or hardware address on the packet, and		   has no fixed IP address.   If there is one, hang		   it off the lease so that its option definitions		   can be used. */		oc = lookup_option (&dhcp_universe, packet -> options,				    DHO_DHCP_CLIENT_IDENTIFIER);		if (oc &&		    evaluate_option_cache (&d1, packet, lease,					   (struct client_state *)0,					   packet -> options, state -> options,					   &lease -> scope, oc, MDL)) {			find_hosts_by_uid (&hp, d1.data, d1.len, MDL);			data_string_forget (&d1, MDL);			if (hp)				host_reference (&lease -> host, hp, MDL);		}		if (!hp) {			find_hosts_by_haddr (&hp,					     packet -> raw -> htype,					     packet -> raw -> chaddr,					     packet -> raw -> hlen,					     MDL);			for (h = hp; h; h = h -> n_ipaddr) {				if (!h -> fixed_addr)					break;			}			if (h)				host_reference (&lease -> host, h, MDL);		}		if (hp)			host_dereference (&hp, MDL);	}	/* If we have a host_decl structure, run the options associated	   with its group.  Wether the host decl struct is old or not. */	if (lease -> host)		execute_statements_in_scope ((struct binding_value **)0,					     packet, lease,					     (struct client_state *)0,					     packet -> options,					     state -> options, &lease -> scope,					     lease -> host -> group,					     (lease -> pool					      ? lease -> pool -> group					      : lease -> subnet -> group));	/* Drop the request if it's not allowed for this client.   By	   default, unknown clients are allowed. */	if (!lease -> host &&	    (oc = lookup_option (&server_universe, state -> options,				 SV_BOOT_UNKNOWN_CLIENTS)) &&	    !evaluate_boolean_option_cache (&ignorep,					    packet, lease,					    (struct client_state *)0,					    packet -> options,					    state -> options,					    &lease -> scope, oc, MDL)) {		if (!ignorep)			log_info ("%s: unknown client", msg);		free_lease_state (state, MDL);		return;	} 	/* Drop the request if it's not allowed for this client. */	if (!offer &&	    (oc = lookup_option (&server_universe, state -> options,				   SV_ALLOW_BOOTP)) &&	    !evaluate_boolean_option_cache (&ignorep,					    packet, lease,					    (struct client_state *)0,					    packet -> options,					    state -> options,					    &lease -> scope, oc, MDL)) {		if (!ignorep)			log_info ("%s: bootp disallowed", msg);		free_lease_state (state, MDL);		return;	} 	/* Drop the request if booting is specifically denied. */	oc = lookup_option (&server_universe, state -> options,			    SV_ALLOW_BOOTING);	if (oc &&	    !evaluate_boolean_option_cache (&ignorep,					    packet, lease,					    (struct client_state *)0,					    packet -> options,					    state -> options,					    &lease -> scope, oc, MDL)) {		if (!ignorep)			log_info ("%s: booting disallowed", msg);		free_lease_state (state, MDL);		return;	}	/* If we are configured to do per-class billing, do it. */	if (have_billing_classes && !(lease -> flags & STATIC_LEASE)) {		/* See if the lease is currently being billed to a		   class, and if so, whether or not it can continue to		   be billed to that class. */		if (lease -> billing_class) {			for (i = 0; i < packet -> class_count; i++)				if (packet -> classes [i] ==				    lease -> billing_class)					break;			if (i == packet -> class_count)				unbill_class (lease, lease -> billing_class);		}				/* If we don't have an active billing, see if we need		   one, and if we do, try to do so. */		if (!lease -> billing_class) {			for (i = 0; i < packet -> class_count; i++) {				if (packet -> classes [i] -> lease_limit)					break;			}			if (i != packet -> class_count) {				for (i = 0; i < packet -> class_count; i++)					if ((packet -> 					     classes [i] -> lease_limit) &&					    bill_class (lease,							packet -> classes [i]))						break;				if (i == packet -> class_count) {					log_info ("%s: no available billing",						  msg);					free_lease_state (state, MDL);					/* XXX probably not necessary: */					return;				}			}		}	}	/* Figure out the filename. */	oc = lookup_option (&server_universe, state -> options, SV_FILENAME);	if (oc)		evaluate_option_cache (&state -> filename, packet, lease,				       (struct client_state *)0,				       packet -> options, state -> options,				       &lease -> scope, oc, MDL);	/* Choose a server name as above. */	oc = lookup_option (&server_universe, state -> options,			    SV_SERVER_NAME);	if (oc)		evaluate_option_cache (&state -> server_name, packet, lease,				       (struct client_state *)0,				       packet -> options, state -> options,				       &lease -> scope, oc, MDL);	/* At this point, we have a lease that we can offer the client.	   Now we construct a lease structure that contains what we want,	   and call supersede_lease to do the right thing with it. */	lt = (struct lease *)0;	result = lease_allocate (&lt, MDL);	if (result != ISC_R_SUCCESS) {		log_info ("%s: can't allocate temporary lease structure: %s",			  msg, isc_result_totext (result));		free_lease_state (state, MDL);		return;	}			/* Use the ip address of the lease that we finally found in	   the database. */	lt -> ip_addr = lease -> ip_addr;	/* Start now. */	lt -> starts = cur_time;	/* Figure out how long a lease to assign.    If this is a	   dynamic BOOTP lease, its duration must be infinite. */	if (offer) {		default_lease_time = DEFAULT_DEFAULT_LEASE_TIME;		if ((oc = lookup_option (&server_universe, state -> options,					 SV_DEFAULT_LEASE_TIME))) {			if (evaluate_option_cache (&d1, packet, lease,						   (struct client_state *)0,						   packet -> options,						   state -> options,						   &lease -> scope, oc, MDL)) {				if (d1.len == sizeof (u_int32_t))					default_lease_time =						getULong (d1.data);				data_string_forget (&d1, MDL);			}		}		if ((oc = lookup_option (&dhcp_universe, packet -> options,					 DHO_DHCP_LEASE_TIME)))			s1 = evaluate_option_cache (&d1, packet, lease,						    (struct client_state *)0,						    packet -> options,						    state -> options,						    &lease -> scope, oc, MDL);		else			s1 = 0;		if (s1 && d1.len == sizeof (u_int32_t)) {			lease_time = getULong (d1.data);			data_string_forget (&d1, MDL);		} else {			if (s1)				data_string_forget (&d1, MDL);			lease_time = default_lease_time;		}				/* See if there's a maximum lease time. */		max_lease_time = DEFAULT_MAX_LEASE_TIME;		if ((oc = lookup_option (&server_universe, state -> options,					 SV_MAX_LEASE_TIME))) {			if (evaluate_option_cache (&d1, packet, lease,						   (struct client_state *)0,						   packet -> options,						   state -> options,						   &lease -> scope, oc, MDL)) {				if (d1.len == sizeof (u_int32_t))					max_lease_time =						getULong (d1.data);				data_string_forget (&d1, MDL);			}		}		/* Enforce the maximum lease length. */		if (lease_time < 0 /* XXX */		    || lease_time > max_lease_time)			lease_time = max_lease_time;					min_lease_time = DEFAULT_MIN_LEASE_TIME;		if (min_lease_time > max_lease_time)			min_lease_time = max_lease_time;		if ((oc = lookup_option (&server_universe, state -> options,					 SV_MIN_LEASE_TIME))) {			if (evaluate_option_cache (&d1, packet, lease,						   (struct client_state *)0,						   packet -> options,						   state -> options,						   &lease -> scope, oc, MDL)) {				if (d1.len == sizeof (u_int32_t))					min_lease_time = getULong (d1.data);				data_string_forget (&d1, MDL);			}		}		if (lease_time < min_lease_time) {			if (min_lease_time)				lease_time = min_lease_time;			else				lease_time = default_lease_time;		}#if defined (FAILOVER_PROTOCOL)		/* Okay, we know the lease duration.   Now check the		   failover state, if any. */		if (lease -> tsfp) {			lt ->tsfp = lease ->tsfp;		}		if (lease -> pool && lease -> pool -> failover_peer) {			dhcp_failover_state_t *peer =			    lease -> pool -> failover_peer;			/* If the lease time we arrived at exceeds what			   the peer has, we can only issue a lease of			   peer -> mclt, but we can tell the peer we			   want something longer in the future. */			/* XXX This may result in updates that only push			   XXX the peer's expiry time for this lease up			   XXX by a few seconds - think about this again			   XXX later. */			if (lease_time > peer -> mclt &&			    cur_time + lease_time > lease -> tsfp) {				/* Here we're assuming that if we don't have				   to update tstp, there's already an update				   queued.   May want to revisit this.  */				if (peer -> me.state != partner_down &&				    cur_time + lease_time > lease -> tstp)					lt -> tstp = (cur_time + lease_time +						      peer -> mclt / 2);				/* Now choose a lease time that is either				   MCLT, for a lease that's never before been				   assigned, or TSFP + MCLT for a lease that				   has.				   XXX Note that TSFP may be < cur_time.				   XXX What do we do in this case?				   XXX should the expiry timer on the lease				   XXX set tsfp and tstp to zero? */				if (lease -> tsfp < cur_time) {					lease_time = peer -> mclt;				} else {					lease_time = (lease -> tsfp  - cur_time						      + peer -> mclt);				}			} else {				if (cur_time + lease_time > lease -> tsfp &&				    lease_time > peer -> mclt / 2) {					lt -> tstp = (cur_time + lease_time +						      peer -> mclt / 2);				} else { 					lt -> tstp = (cur_time + lease_time +						      lease_time / 2);				}			}			lt -> cltt = cur_time;		}#endif /* FAILOVER_PROTOCOL */		/* If the lease duration causes the time value to wrap,		   use the maximum expiry time. */		if (cur_time + lease_time < cur_time)			state -> offered_expiry = MAX_TIME - 1;		else			state -> offered_expiry = cur_time + lease_time;		if (when)			lt -> ends = when;		else			lt -> ends = state -> offered_expiry;		/* Don't make lease active until we actually get a		   DHCPREQUEST. */		if (offer == DHCPACK)			lt -> next_binding_state = FTS_ACTIVE;		else			lt -> next_binding_state = lease -> binding_state;	} else {		lease_time = MAX_TIME - cur_time;		if ((oc = lookup_option (&server_universe, state -> options,					 SV_BOOTP_LEASE_LENGTH))) {			if (evaluate_option_cache (&d1, packet, lease,						   (struct client_state *)0,						   packet -> options,						   state -> options,						   &lease -> scope, oc, MDL)) {				if (d1.len == sizeof (u_int32_t))					lease_time = getULong (d1.data);				data_string_forget (&d1, MDL);			}		}		if ((oc = lookup_option (&server_universe, state -> options,					 SV_BOOTP_LEASE_CUTOFF))) {			if (evaluate_option_cache (&d1, packet, lease,						   (struct client_state *)0,						   packet -> options,						   state -> options,						   &lease -> scope,

⌨️ 快捷键说明

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