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

📄 options.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	return status;}int fqdn_option_space_encapsulate (result, packet, lease, client_state,				   in_options, cfg_options, scope, universe)	struct data_string *result;	struct packet *packet;	struct lease *lease;	struct client_state *client_state;	struct option_state *in_options;	struct option_state *cfg_options;	struct binding_scope **scope;	struct universe *universe;{	pair ocp;	struct data_string results [FQDN_SUBOPTION_COUNT + 1];	unsigned i;	unsigned len;	struct buffer *bp = (struct buffer *)0;	struct option_chain_head *head;	/* If there's no FQDN universe, don't encapsulate. */	if (fqdn_universe.index >= cfg_options -> universe_count)		return 0;	head = ((struct option_chain_head *)		cfg_options -> universes [fqdn_universe.index]);	if (!head)		return 0;	/* Figure out the values of all the suboptions. */	memset (results, 0, sizeof results);	for (ocp = head -> first; ocp; ocp = ocp -> cdr) {		struct option_cache *oc = (struct option_cache *)(ocp -> car);		if (oc -> option -> code > FQDN_SUBOPTION_COUNT)			continue;		evaluate_option_cache (&results [oc -> option -> code],				       packet, lease, client_state, in_options,				       cfg_options, scope,  oc, MDL);	}	len = 4 + results [FQDN_FQDN].len;	/* Save the contents of the option in a buffer. */	if (!buffer_allocate (&bp, len, MDL)) {		log_error ("no memory for option buffer.");		return 0;	}	buffer_reference (&result -> buffer, bp, MDL);	result -> len = 3;	result -> data = &bp -> data [0];	memset (&bp -> data [0], 0, len);	if (results [FQDN_NO_CLIENT_UPDATE].len &&	    results [FQDN_NO_CLIENT_UPDATE].data [0])		bp -> data [0] |= 2;	if (results [FQDN_SERVER_UPDATE].len &&	    results [FQDN_SERVER_UPDATE].data [0])		bp -> data [0] |= 1;	if (results [FQDN_RCODE1].len)		bp -> data [1] = results [FQDN_RCODE1].data [0];	if (results [FQDN_RCODE2].len)		bp -> data [2] = results [FQDN_RCODE2].data [0];	if (results [FQDN_ENCODED].len &&	    results [FQDN_ENCODED].data [0]) {		unsigned char *out;		int i;		bp -> data [0] |= 4;		out = &bp -> data [3];		if (results [FQDN_FQDN].len) {			i = 0;			while (i < results [FQDN_FQDN].len) {				int j;				for (j = i; ('.' !=					     results [FQDN_FQDN].data [j]) &&					     j < results [FQDN_FQDN].len; j++)					;				*out++ = j - i;				memcpy (out, &results [FQDN_FQDN].data [i],					(unsigned)(j - i));				out += j - i;				i = j;				if (results [FQDN_FQDN].data [j] == '.')					i++;			}			if ((results [FQDN_FQDN].data			     [results [FQDN_FQDN].len - 1] == '.'))				*out++ = 0;			result -> len = out - result -> data;			result -> terminated = 0;		}	} else {		if (results [FQDN_FQDN].len) {			memcpy (&bp -> data [3], results [FQDN_FQDN].data,				results [FQDN_FQDN].len);			result -> len += results [FQDN_FQDN].len;			result -> terminated = 0;		}	}	for (i = 1; i <= FQDN_SUBOPTION_COUNT; i++) {		if (results [i].len)			data_string_forget (&results [i], MDL);	}	buffer_dereference (&bp, MDL);	return 1;}void option_space_foreach (struct packet *packet, struct lease *lease,			   struct client_state *client_state,			   struct option_state *in_options,			   struct option_state *cfg_options,			   struct binding_scope **scope,			   struct universe *u, void *stuff,			   void (*func) (struct option_cache *,					 struct packet *,					 struct lease *, struct client_state *,					 struct option_state *,					 struct option_state *,					 struct binding_scope **,					 struct universe *, void *)){	if (u -> foreach)		(*u -> foreach) (packet, lease, client_state, in_options,				 cfg_options, scope, u, stuff, func);}void suboption_foreach (struct packet *packet, struct lease *lease,			struct client_state *client_state,			struct option_state *in_options,			struct option_state *cfg_options,			struct binding_scope **scope,			struct universe *u, void *stuff,			void (*func) (struct option_cache *,				      struct packet *,				      struct lease *, struct client_state *,				      struct option_state *,				      struct option_state *,				      struct binding_scope **,				      struct universe *, void *),			struct option_cache *oc,			const char *vsname){	struct universe *universe = find_option_universe (oc -> option,							  vsname);	int i;	if (universe -> foreach)		(*universe -> foreach) (packet, lease, client_state,					in_options, cfg_options,					scope, universe, stuff, func);}void hashed_option_space_foreach (struct packet *packet, struct lease *lease,				  struct client_state *client_state,				  struct option_state *in_options,				  struct option_state *cfg_options,				  struct binding_scope **scope,				  struct universe *u, void *stuff,				  void (*func) (struct option_cache *,						struct packet *,						struct lease *,						struct client_state *,						struct option_state *,						struct option_state *,						struct binding_scope **,						struct universe *, void *)){	pair *hash;	int i;	struct option_cache *oc;	if (cfg_options -> universe_count <= u -> index)		return;	hash = cfg_options -> universes [u -> index];	if (!hash)		return;	for (i = 0; i < OPTION_HASH_SIZE; i++) {		pair p;		/* XXX save _all_ options! XXX */		for (p = hash [i]; p; p = p -> cdr) {			oc = (struct option_cache *)p -> car;			(*func) (oc, packet, lease, client_state,				 in_options, cfg_options, scope, u, stuff);		}	}}void save_linked_option (universe, options, oc)	struct universe *universe;	struct option_state *options;	struct option_cache *oc;{	pair *tail;	pair np = (pair )0;	struct option_chain_head *head;	if (universe -> index >= options -> universe_count)		return;	head = ((struct option_chain_head *)		options -> universes [universe -> index]);	if (!head) {		if (!option_chain_head_allocate (((struct option_chain_head **)						  &options -> universes						  [universe -> index]), MDL))			return;		head = ((struct option_chain_head *)			options -> universes [universe -> index]);	}	/* Find the tail of the list. */	for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) {		if (oc -> option ==		    ((struct option_cache *)((*tail) -> car)) -> option) {			option_cache_dereference ((struct option_cache **)						  (&(*tail) -> car), MDL);			option_cache_reference ((struct option_cache **)						(&(*tail) -> car), oc, MDL);			return;		}	}	*tail = cons (0, 0);	if (*tail) {		option_cache_reference ((struct option_cache **)					(&(*tail) -> car), oc, MDL);	}}int linked_option_space_encapsulate (result, packet, lease, client_state,				    in_options, cfg_options, scope, universe)	struct data_string *result;	struct packet *packet;	struct lease *lease;	struct client_state *client_state;	struct option_state *in_options;	struct option_state *cfg_options;	struct binding_scope **scope;	struct universe *universe;{	int status;	pair oc;	struct option_chain_head *head;	if (universe -> index >= cfg_options -> universe_count)		return 0;	head = ((struct option_chain_head *)		cfg_options -> universes [universe -> index]);	if (!head)		return 0;	status = 0;	for (oc = head -> first; oc; oc = oc -> cdr) {		if (store_option (result, universe, packet,				  lease, client_state, in_options, cfg_options,				  scope, (struct option_cache *)(oc -> car)))			status = 1;	}	return status;}void delete_linked_option (universe, options, code)	struct universe *universe;	struct option_state *options;	int code;{	pair *tail, tmp = (pair)0;	struct option_chain_head *head;	if (universe -> index >= options -> universe_count)		return;	head = ((struct option_chain_head *)		options -> universes [universe -> index]);	if (!head)		return;	for (tail = &head -> first; *tail; tail = &((*tail) -> cdr)) {		if (code ==		    ((struct option_cache *)(*tail) -> car) -> option -> code)		{			tmp = (*tail) -> cdr;			option_cache_dereference ((struct option_cache **)						  (&(*tail) -> car), MDL);			dfree (*tail, MDL);			(*tail) = tmp;			break;		}	}}struct option_cache *lookup_linked_option (universe, options, code)	struct universe *universe;	struct option_state *options;	unsigned code;{	pair oc;	struct option_chain_head *head;	if (universe -> index >= options -> universe_count)		return 0;	head = ((struct option_chain_head *)		options -> universes [universe -> index]);	if (!head)		return 0;	for (oc = head -> first; oc; oc = oc -> cdr) {		if (code ==		    ((struct option_cache *)(oc -> car)) -> option -> code) {			return (struct option_cache *)(oc -> car);		}	}	return (struct option_cache *)0;}int linked_option_state_dereference (universe, state, file, line)	struct universe *universe;	struct option_state *state;	const char *file;	int line;{	return (option_chain_head_dereference		((struct option_chain_head **)		 (&state -> universes [universe -> index]), MDL));}void linked_option_space_foreach (struct packet *packet, struct lease *lease,				  struct client_state *client_state,				  struct option_state *in_options,				  struct option_state *cfg_options,				  struct binding_scope **scope,				  struct universe *u, void *stuff,				  void (*func) (struct option_cache *,						struct packet *,						struct lease *,						struct client_state *,						struct option_state *,						struct option_state *,						struct binding_scope **,						struct universe *, void *)){	pair car;	struct option_chain_head *head;	if (u -> index >= cfg_options -> universe_count)		return;	head = ((struct option_chain_head *)		cfg_options -> universes [u -> index]);	if (!head)		return;	for (car = head -> first; car; car = car -> cdr) {		(*func) ((struct option_cache *)(car -> car),			 packet, lease, client_state,			 in_options, cfg_options, scope, u, stuff);	}}void do_packet (interface, packet, len, from_port, from, hfrom)	struct interface_info *interface;	struct dhcp_packet *packet;	unsigned len;	unsigned int from_port;	struct iaddr from;	struct hardware *hfrom;{	int i;	struct option_cache *op;	struct packet *decoded_packet;#if defined (DEBUG_MEMORY_LEAKAGE)	unsigned long previous_outstanding = dmalloc_outstanding;#endif#if defined (TRACING)	trace_inpacket_stash (interface, packet, len, from_port, from, hfrom);#endif	decoded_packet = (struct packet *)0;	if (!packet_allocate (&decoded_packet, MDL)) {		log_error ("do_packet: no memory for incoming packet!");		return;	}	decoded_packet -> raw = packet;	decoded_packet -> packet_length = len;	decoded_packet -> client_port = from_port;	decoded_packet -> client_addr = from;	interface_reference (&decoded_packet -> interface, interface, MDL);	decoded_packet -> haddr = hfrom;		if (packet -> hlen > sizeof packet -> chaddr) {		packet_dereference (&decoded_packet, MDL);		log_info ("Discarding packet with bogus hlen.");		return;	}	/* If there's an option buffer, try to parse it. */	if (decoded_packet -> packet_length >= DHCP_FIXED_NON_UDP + 4) {		if (!parse_options (decoded_packet)) {			if (decoded_packet -> options)				option_state_dereference					(&decoded_packet -> options, MDL);			packet_dereference (&decoded_packet, MDL);			return;		}		if (decoded_packet -> options_valid &&		    (op = lookup_option (&dhcp_universe,					 decoded_packet -> options, 					 DHO_DHCP_MESSAGE_TYPE))) {			struct data_string dp;			memset (&dp, 0, sizeof dp);			evaluate_option_cache (&dp, decoded_packet,					       (struct lease *)0,					       (struct client_state *)0,					       decoded_packet -> options,					       (struct option_state *)0,					       (struct binding_scope **)0,					       op, MDL);			if (dp.len > 0)				decoded_packet -> packet_type = dp.data [0];			else				decoded_packet -> packet_type = 0;			data_string_forget (&dp, MDL);		}	}			if (decoded_packet -> packet_type)		dhcp (decoded_packet);	else		bootp (decoded_packet);	/* If the caller kept the packet, they'll have upped the refcnt. */	packet_dereference (&decoded_packet, MDL);#if defined (DEBUG_MEMORY_LEAKAGE)	log_info ("generation %ld: %ld new, %ld outstanding, %ld long-term",		  dmalloc_generation,		  dmalloc_outstanding - previous_outstanding,		  dmalloc_outstanding, dmalloc_longterm);#endif#if defined (DEBUG_MEMORY_LEAKAGE)	dmalloc_dump_outstanding ();#endif#if defined (DEBUG_RC_HISTORY_EXHAUSTIVELY)	dump_rc_history (0);#endif}

⌨️ 快捷键说明

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