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

📄 dhcp.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
				    (struct client_state *)0,				    packet -> options,				    (struct option_state *)0,				    &global_scope, oc, MDL))		return;	cip.len = 4;	memcpy (cip.iabuf, data.data, 4);	data_string_forget (&data, MDL);	find_lease_by_ip_addr (&lease, cip, MDL);	if (lease && lease -> client_hostname) {		if ((strlen (lease -> client_hostname) <= 64) &&		    db_printable (lease -> client_hostname))			s = lease -> client_hostname;		else			s = "Hostname Unsuitable for Printing";	} else		s = (char *)0;	/* %Audit% This is log output. %2004.06.17,Safe%	 * If we truncate we hope the user can get a hint from the log.	 */	snprintf (msgbuf, sizeof msgbuf,		 "DHCPDECLINE of %s from %s %s%s%svia %s",		 piaddr (cip),		 (packet -> raw -> htype		  ? print_hw_addr (packet -> raw -> htype,				   packet -> raw -> hlen,				   packet -> raw -> chaddr)		  : (lease		     ? print_hex_1 (lease -> uid_len, lease -> uid, 				    lease -> uid_len)		     : "<no identifier>")),		 s ? "(" : "", s ? s : "", s ? ") " : "",		 packet -> raw -> giaddr.s_addr		 ? inet_ntoa (packet -> raw -> giaddr)		 : packet -> interface -> name);	option_state_allocate (&options, MDL);	/* Execute statements in scope starting with the subnet scope. */	if (lease)		execute_statements_in_scope ((struct binding_value **)0,					     packet, (struct lease *)0,					     (struct client_state *)0,					     packet -> options, options,					     &global_scope,					     lease -> subnet -> group,					     (struct group *)0);	/* Execute statements in the class scopes. */	for (i = packet -> class_count; i > 0; i--) {		execute_statements_in_scope			((struct binding_value **)0, packet, (struct lease *)0,			 (struct client_state *)0, packet -> options, options,			 &global_scope, packet -> classes [i - 1] -> group,			 lease ? lease -> subnet -> group : (struct group *)0);	}	/* Drop the request if dhcpdeclines are being ignored. */	oc = lookup_option (&server_universe, options, SV_DECLINES);	if (!oc ||	    evaluate_boolean_option_cache (&ignorep, packet, lease,					   (struct client_state *)0,					   packet -> options, options,					   &lease -> scope, oc, MDL)) {	    /* If we found a lease, mark it as unusable and complain. */	    if (lease) {#if defined (FAILOVER_PROTOCOL)		if (lease -> pool && lease -> pool -> failover_peer) {		    dhcp_failover_state_t *peer =			    lease -> pool -> failover_peer;		    if (peer -> service_state == not_responding ||			peer -> service_state == service_startup) {			if (!ignorep)			    log_info ("%s: ignored%s",				      peer -> name, peer -> nrr);			goto out;		    }		    /* DHCPDECLINE messages are broadcast, so we can safely		       ignore the DHCPDECLINE if the peer has the lease.		       XXX Of course, at this point that information has been		       lost. */		}#endif		abandon_lease (lease, "declined.");		status = "abandoned";	    }	    status = "not found";	} else	    status = "ignored";	if (!ignorep)		log_info ("%s: %s", msgbuf, status);		      out:	if (options)		option_state_dereference (&options, MDL);	if (lease)		lease_dereference (&lease, MDL);}void dhcpinform (packet, ms_nulltp)	struct packet *packet;	int ms_nulltp;{	char msgbuf [1024];	struct data_string d1, prl;	struct option_cache *oc;	struct expression *expr;	struct option_state *options = (struct option_state *)0;	struct dhcp_packet raw;	struct packet outgoing;	unsigned char dhcpack = DHCPACK;	struct subnet *subnet = (struct subnet *)0;	struct iaddr cip;	unsigned i, j;	int nulltp;	struct sockaddr_in to;	struct in_addr from;	/* The client should set ciaddr to its IP address, but apparently	   it's common for clients not to do this, so we'll use their IP	   source address if they didn't set ciaddr. */	if (!packet -> raw -> ciaddr.s_addr) {		cip.len = 4;		memcpy (cip.iabuf, &packet -> client_addr, 4);	} else {		cip.len = 4;		memcpy (cip.iabuf, &packet -> raw -> ciaddr, 4);	}	/* %Audit% This is log output. %2004.06.17,Safe%	 * If we truncate we hope the user can get a hint from the log.	 */	snprintf (msgbuf, sizeof msgbuf, "DHCPINFORM from %s via %s",		 piaddr (cip), packet -> interface -> name);	/* If the IP source address is zero, don't respond. */	if (!memcmp (cip.iabuf, "\0\0\0", 4)) {		log_info ("%s: ignored (null source address).", msgbuf);		return;	}	/* Find the subnet that the client is on. */	oc = (struct option_cache *)0;	find_subnet (&subnet , cip, MDL);	/* Sourceless packets don't make sense here. */	if (!subnet) {		log_info ("%s: unknown subnet %s",			  msgbuf, inet_ntoa (packet -> raw -> giaddr));		return;	}	/* We don't respond to DHCPINFORM packets if we're not authoritative.	   It would be nice if a per-host value could override this, but	   there's overhead involved in checking this, so let's see how people	   react first. */	if (subnet && !subnet -> group -> authoritative) {		static int eso = 0;		log_info ("%s: not authoritative for subnet %s",			  msgbuf, piaddr (subnet -> net));		if (!eso) {			log_info ("If this DHCP server is authoritative for%s",				  " that subnet,");			log_info ("please write an `authoritative;' directi%s",				  "ve either in the");			log_info ("subnet declaration or in some scope that%s",				  " encloses the");			log_info ("subnet declaration - for example, write %s",				  "it at the top");			log_info ("of the dhcpd.conf file.");		}		if (eso++ == 100)			eso = 0;		subnet_dereference (&subnet, MDL);		return;	}	memset (&d1, 0, sizeof d1);	option_state_allocate (&options, MDL);	memset (&outgoing, 0, sizeof outgoing);	memset (&raw, 0, sizeof raw);	outgoing.raw = &raw;	/* Execute statements in scope starting with the subnet scope. */	if (subnet)		execute_statements_in_scope ((struct binding_value **)0,					     packet, (struct lease *)0,					     (struct client_state *)0,					     packet -> options, options,					     &global_scope, subnet -> group,					     (struct group *)0);	/* Execute statements in the class scopes. */	for (i = packet -> class_count; i > 0; i--) {		execute_statements_in_scope			((struct binding_value **)0, packet, (struct lease *)0,			 (struct client_state *)0, packet -> options, options,			 &global_scope, packet -> classes [i - 1] -> group,			 subnet ? subnet -> group : (struct group *)0);	}	/* Figure out the filename. */	memset (&d1, 0, sizeof d1);	oc = lookup_option (&server_universe, options, SV_FILENAME);	if (oc &&	    evaluate_option_cache (&d1, packet, (struct lease *)0,				   (struct client_state *)0,				   packet -> options, (struct option_state *)0,				   &global_scope, oc, MDL)) {		i = d1.len;		if (i > sizeof raw.file)			i = sizeof raw.file;		else			raw.file [i] = 0;		memcpy (raw.file, d1.data, i);		data_string_forget (&d1, MDL);	}	/* Choose a server name as above. */	oc = lookup_option (&server_universe, options, SV_SERVER_NAME);	if (oc &&	    evaluate_option_cache (&d1, packet, (struct lease *)0,				   (struct client_state *)0,				   packet -> options, (struct option_state *)0,				   &global_scope, oc, MDL)) {		i = d1.len;		if (i > sizeof raw.sname)			i = sizeof raw.sname;		else			raw.sname [i] = 0;		memcpy (raw.sname, d1.data, i);		data_string_forget (&d1, MDL);	}	/* Set a flag if this client is a lame Microsoft client that NUL	   terminates string options and expects us to do likewise. */	nulltp = 0;	if ((oc = lookup_option (&dhcp_universe, packet -> options,				 DHO_HOST_NAME))) {		if (evaluate_option_cache (&d1, packet, (struct lease *)0,					   (struct client_state *)0,					   packet -> options, options,					   &global_scope, oc, MDL)) {			if (d1.data [d1.len - 1] == '\0')				nulltp = 1;			data_string_forget (&d1, MDL);		}	}	/* Put in DHCP-specific options. */	i = DHO_DHCP_MESSAGE_TYPE;	oc = (struct option_cache *)0;	if (option_cache_allocate (&oc, MDL)) {		if (make_const_data (&oc -> expression,				     &dhcpack, 1, 0, 0, MDL)) {			oc -> option = dhcp_universe.options [i];			save_option (&dhcp_universe, options, oc);		}		option_cache_dereference (&oc, MDL);	}	i = DHO_DHCP_SERVER_IDENTIFIER;	if (!(oc = lookup_option (&dhcp_universe, options, i))) {	      use_primary:		oc = (struct option_cache *)0;		if (option_cache_allocate (&oc, MDL)) {			if (make_const_data			    (&oc -> expression,			     ((unsigned char *)			      &packet -> interface -> primary_address),			     sizeof packet -> interface -> primary_address,			     0, 0, MDL)) {				oc -> option =					dhcp_universe.options [i];				save_option (&dhcp_universe,					     options, oc);			}			option_cache_dereference (&oc, MDL);		}		from = packet -> interface -> primary_address;	} else {		if (evaluate_option_cache (&d1, packet, (struct lease *)0,					   (struct client_state *)0,					   packet -> options, options,					   &global_scope, oc, MDL)) {			if (!d1.len || d1.len != sizeof from) {				data_string_forget (&d1, MDL);				goto use_primary;			}			memcpy (&from, d1.data, sizeof from);			data_string_forget (&d1, MDL);		} else			goto use_primary;	}	/* Use the subnet mask from the subnet declaration if no other	   mask has been provided. */	i = DHO_SUBNET_MASK;	if (subnet && !lookup_option (&dhcp_universe, options, i)) {		oc = (struct option_cache *)0;		if (option_cache_allocate (&oc, MDL)) {			if (make_const_data (&oc -> expression,					     subnet -> netmask.iabuf,					     subnet -> netmask.len,					     0, 0, MDL)) {				oc -> option = dhcp_universe.options [i];				save_option (&dhcp_universe, options, oc);			}			option_cache_dereference (&oc, MDL);		}	}	/* If a site option space has been specified, use that for	   site option codes. */	i = SV_SITE_OPTION_SPACE;	if ((oc = lookup_option (&server_universe, options, i)) &&	    evaluate_option_cache (&d1, packet, (struct lease *)0,				   (struct client_state *)0,				   packet -> options, options,				   &global_scope, oc, MDL)) {		struct universe *u = (struct universe *)0;				if (!universe_hash_lookup (&u, universe_hash,					   (const char *)d1.data, d1.len,					   MDL)) {			log_error ("unknown option space %s.", d1.data);			option_state_dereference (&options, MDL);			if (subnet)				subnet_dereference (&subnet, MDL);			return;		}		options -> site_universe = u -> index;		options -> site_code_min = 128; /* XXX */		data_string_forget (&d1, MDL);	} else {		options -> site_universe = dhcp_universe.index;		options -> site_code_min = 0; /* Trust me, it works. */	}	memset (&prl, 0, sizeof prl);	/* Use the parameter list from the scope if there is one. */	oc = lookup_option (&dhcp_universe, options,			    DHO_DHCP_PARAMETER_REQUEST_LIST);	/* Otherwise, if the client has provided a list of options	   that it wishes returned, use it to prioritize.  Otherwise,	   prioritize based on the default priority list. */	if (!oc)		oc = lookup_option (&dhcp_universe, packet -> options,				    DHO_DHCP_PARAMETER_REQUEST_LIST);	if (oc)		evaluate_option_cache (&prl, packet, (struct lease *)0,				       (struct client_state *)0,				       packet -> options, options,				       &global_scope, oc, MDL);#ifdef DEBUG_PACKET	dump_packet (packet);	dump_raw ((unsigned char *)packet -> raw, packet -> packet_length);#endif	log_info ("%s", msgbuf);	/* Figure out the address of the boot file server. */	raw.siaddr = from;	if ((oc =	     lookup_option (&server_universe, options, SV_NEXT_SERVER))) {		if (evaluate_option_cache (&d1, packet, (struct lease *)0,					   (struct client_state *)0,					   packet -> options, options,					   &global_scope, oc, MDL)) {			/* If there was more than one answer,			   take the first. */			if (d1.len >= 4 && d1.data)				memcpy (&raw.siaddr, d1.data, 4);			data_string_forget (&d1, MDL);		}	}	/* Set up the option buffer... */	outgoing.packet_length =		cons_options (packet, outgoing.raw, (struct lease *)0,			      (struct client_state *)0,			      0, packet -> options, options, &global_scope,			      0, nulltp, 0,			      prl.len ? &prl : (struct data_string *)0,			      (char *)0);	option_state_dereference (&options, MDL);	data_string_forget (&prl, MDL);	/* Make sure that the packet is at least as big as a BOOTP packet. */	if (outgoing.packet_length < BOOTP_MIN_LEN)		outgoing.packet_length = BOOTP_MIN_LEN;	raw.giaddr = packet -> raw -> giaddr;	raw.ciaddr = packet -> raw -> ciaddr;	memcpy (raw.chaddr, packet -> raw -> chaddr, sizeof raw.chaddr);	raw.hlen = packet -> raw -> hlen;	raw.htype = packet -> raw -> htype;	raw.xid = packet -> raw -> xid;	raw.secs = packet -> raw -> secs;	raw.flags = packet -> raw -> flags;	raw.hops = packet -> raw -> hops;	raw.op = BOOTREPLY;

⌨️ 快捷键说明

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