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

📄 memory.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (lease -> flags & STATIC_LEASE)
		return 1;

	/* If the existing lease hasn't expired and has a different
	   unique identifier or, if it doesn't have a unique
	   identifier, a different hardware address, then the two
	   leases are in conflict.  If the existing lease has a uid
	   and the new one doesn't, but they both have the same
	   hardware address, and dynamic bootp is allowed on this
	   lease, then we allow that, in case a dynamic BOOTP lease is
	   requested *after* a DHCP lease has been assigned. */

	if (!(lease -> flags & ABANDONED_LEASE) &&
	    comp -> ends > cur_time &&
	    (((comp -> uid && lease -> uid) &&
	      (comp -> uid_len != lease -> uid_len ||
	       memcmp (comp -> uid, lease -> uid, comp -> uid_len))) ||
	     (!comp -> uid &&
	      ((comp -> hardware_addr.htype !=
		lease -> hardware_addr.htype) ||
	       (comp -> hardware_addr.hlen !=
		lease -> hardware_addr.hlen) ||
	       memcmp (comp -> hardware_addr.haddr,
		       lease -> hardware_addr.haddr,
		       comp -> hardware_addr.hlen))))) {
		warn ("Lease conflict at %s",
		      piaddr (comp -> ip_addr));
		return 0;
	} else {
		/* If there's a Unique ID, dissociate it from the hash
		   table and free it if necessary. */
		if (comp -> uid) {
			uid_hash_delete (comp);
			enter_uid = 1;
			if (comp -> uid != &comp -> uid_buf [0]) {
				free (comp -> uid);
				comp -> uid_max = 0;
				comp -> uid_len = 0;
			}
			comp -> uid = (unsigned char *)0;
		} else
			enter_uid = 1;

		if (comp -> hardware_addr.htype &&
		    ((comp -> hardware_addr.hlen !=
		      lease -> hardware_addr.hlen) ||
		     (comp -> hardware_addr.htype !=
		      lease -> hardware_addr.htype) ||
		     memcmp (comp -> hardware_addr.haddr,
			     lease -> hardware_addr.haddr,
			     comp -> hardware_addr.hlen))) {
			hw_hash_delete (comp);
			enter_hwaddr = 1;
		} else if (!comp -> hardware_addr.htype)
			enter_hwaddr = 1;

		/* Copy the data files, but not the linkages. */
		comp -> starts = lease -> starts;
		if (lease -> uid) {
			if (lease -> uid_len < sizeof (lease -> uid_buf)) {
				memcpy (comp -> uid_buf,
					lease -> uid, lease -> uid_len);
				comp -> uid = &comp -> uid_buf [0];
				comp -> uid_max = sizeof comp -> uid_buf;
			} else if (lease -> uid != &lease -> uid_buf [0]) {
				comp -> uid = lease -> uid;
				comp -> uid_max = lease -> uid_max;
				lease -> uid = (unsigned char *)0;
				lease -> uid_max = 0;
			} else {
				error ("corrupt lease uid."); /* XXX */
			}
		} else {
			comp -> uid = (unsigned char *)0;
			comp -> uid_max = 0;
		}
		comp -> uid_len = lease -> uid_len;
		comp -> host = lease -> host;
		comp -> hardware_addr = lease -> hardware_addr;
		comp -> flags = ((lease -> flags & ~PERSISTENT_FLAGS) |
				 (comp -> flags & ~EPHEMERAL_FLAGS));

		/* Record the lease in the uid hash if necessary. */
		if (enter_uid && lease -> uid) {
			uid_hash_add (comp);
		}

		/* Record it in the hardware address hash if necessary. */
		if (enter_hwaddr && lease -> hardware_addr.htype) {
			hw_hash_add (comp);
		}

		/* Remove the lease from its current place in the
		   timeout sequence. */
		if (comp -> prev) {
			comp -> prev -> next = comp -> next;
		} else {
			comp -> shared_network -> leases = comp -> next;
		}
		if (comp -> next) {
			comp -> next -> prev = comp -> prev;
		}
		if (comp -> shared_network -> last_lease == comp) {
			comp -> shared_network -> last_lease = comp -> prev;
		}

		/* Find the last insertion point... */
		if (comp == comp -> shared_network -> insertion_point ||
		    !comp -> shared_network -> insertion_point) {
			lp = comp -> shared_network -> leases;
		} else {
			lp = comp -> shared_network -> insertion_point;
		}

		if (!lp) {
			/* Nothing on the list yet?    Just make comp the
			   head of the list. */
			comp -> shared_network -> leases = comp;
			comp -> shared_network -> last_lease = comp;
		} else if (lp -> ends > lease -> ends) {
			/* Skip down the list until we run out of list
			   or find a place for comp. */
			while (lp -> next && lp -> ends > lease -> ends) {
				lp = lp -> next;
			}
			if (lp -> ends > lease -> ends) {
				/* If we ran out of list, put comp
				   at the end. */
				lp -> next = comp;
				comp -> prev = lp;
				comp -> next = (struct lease *)0;
				comp -> shared_network -> last_lease = comp;
			} else {
				/* If we didn't, put it between lp and
				   the previous item on the list. */
				if ((comp -> prev = lp -> prev))
					comp -> prev -> next = comp;
				comp -> next = lp;
				lp -> prev = comp;
			}
		} else {
			/* Skip up the list until we run out of list
			   or find a place for comp. */
			while (lp -> prev && lp -> ends < lease -> ends) {
				lp = lp -> prev;
			}
			if (lp -> ends < lease -> ends) {
				/* If we ran out of list, put comp
				   at the beginning. */
				lp -> prev = comp;
				comp -> next = lp;
				comp -> prev = (struct lease *)0;
				comp -> shared_network -> leases = comp;
			} else {
				/* If we didn't, put it between lp and
				   the next item on the list. */
				if ((comp -> next = lp -> next))
					comp -> next -> prev = comp;
				comp -> prev = lp;
				lp -> next = comp;
			}
		}
		comp -> shared_network -> insertion_point = comp;
		comp -> ends = lease -> ends;
	}

	/* Return zero if we didn't commit the lease to permanent storage;
	   nonzero if we did. */
	return commit && write_lease (comp) && commit_leases ();
}

/* Release the specified lease and re-hash it as appropriate. */

void release_lease (struct _lease *lease)
{
        struct _lease lt;

	lt = *lease;
	if (lt.ends > cur_time) {
		lt.ends = cur_time;
		supersede_lease (lease, &lt, 1);
	}
}

/* Abandon the specified lease (set its timeout to infinity and its
   particulars to zero, and re-hash it as appropriate. */

void abandon_lease (struct _lease *lease, char *message)
{
	struct _lease lt;

	lease -> flags |= ABANDONED_LEASE;
	lt = *lease;
	lt.ends = cur_time;
	warn ("Abandoning IP address %s: %s",
	      piaddr (lease -> ip_addr), message);
	lt.hardware_addr.htype = 0;
	lt.hardware_addr.hlen = 0;
	lt.uid = (unsigned char *)0;
	lt.uid_len = 0;
	supersede_lease (lease, &lt, 1);
}

/* Locate the lease associated with a given IP address... */

lease *find_lease_by_ip_addr (iaddr addr)
{
	lease *lease = (struct _lease *)hash_lookup (lease_ip_addr_hash,
                                                     addr.iabuf,
                                                     addr.len);
	return lease;
}

lease *find_lease_by_uid (unsigned char *uid, int len)
{
        lease *lease = (struct lease *)hash_lookup (lease_uid_hash,
                                                    uid, len);
	return lease;
}

lease *find_lease_by_hw_addr (unsigned char *hwaddr, int hwlen)
{
        struct _lease *lease =
            (struct _lease *)hash_lookup (lease_hw_addr_hash,
                                          hwaddr, hwlen);
	return lease;
}

/* Add the specified lease to the uid hash. */

void uid_hash_add (lease *lease)
{
        struct _lease *head = find_lease_by_uid (lease -> uid, lease -> uid_len);
	struct _lease *scan;

#ifdef DEBUG
	if (lease -> n_uid)
		abort ();
#endif

	/* If it's not in the hash, just add it. */
	if (!head)
		add_hash (lease_uid_hash, lease -> uid,
			  lease -> uid_len, (unsigned char *)lease);
	else {
		/* Otherwise, attach it to the end of the list. */
		for (scan = head; scan -> n_uid; scan = scan -> n_uid)
#ifdef DEBUG
			if (scan == lease)
				abort ()
#endif
					;
		scan -> n_uid = lease;
	}
}

/* Delete the specified lease from the uid hash. */

void uid_hash_delete (lease *lease)
{
        struct _lease *head =
            find_lease_by_uid (lease -> uid, lease -> uid_len);
	struct _lease *scan;

	/* If it's not in the hash, we have no work to do. */
	if (!head) {
		lease -> n_uid = (struct lease *)0;
		return;
	}

	/* If the lease we're freeing is at the head of the list,
	   remove the hash table entry and add a new one with the
	   next lease on the list (if there is one). */
	if (head == lease) {
		delete_hash_entry (lease_uid_hash,
				   lease -> uid, lease -> uid_len);
		if (lease -> n_uid)
			add_hash (lease_uid_hash,
				  lease -> n_uid -> uid,
				  lease -> n_uid -> uid_len,
				  (unsigned char *)(lease -> n_uid));
	} else {
		/* Otherwise, look for the lease in the list of leases
		   attached to the hash table entry, and remove it if
		   we find it. */
		for (scan = head; scan -> n_uid; scan = scan -> n_uid) {
			if (scan -> n_uid == lease) {
				scan -> n_uid = scan -> n_uid -> n_uid;
				break;
			}
		}
	}
	lease -> n_uid = (struct lease *)0;
}

/* Add the specified lease to the hardware address hash. */

void hw_hash_add (lease *lease)
{
        struct _lease *head =
		find_lease_by_hw_addr (lease -> hardware_addr.haddr,
				       lease -> hardware_addr.hlen);
	struct _lease *scan;

	/* If it's not in the hash, just add it. */
	if (!head)
		add_hash (lease_hw_addr_hash,
			  lease -> hardware_addr.haddr,
			  lease -> hardware_addr.hlen,
			  (unsigned char *)lease);
	else {
		/* Otherwise, attach it to the end of the list. */
		for (scan = head; scan -> n_hw; scan = scan -> n_hw)
			;
		scan -> n_hw = lease;
	}
}

/* Delete the specified lease from the hardware address hash. */

void hw_hash_delete (lease *lease)
{
        struct _lease *head =
		find_lease_by_hw_addr (lease -> hardware_addr.haddr,
				       lease -> hardware_addr.hlen);
        struct _lease *scan;

	/* If it's not in the hash, we have no work to do. */
	if (!head) {
		lease -> n_hw = (struct lease *)0;
		return;
	}

	/* If the lease we're freeing is at the head of the list,
	   remove the hash table entry and add a new one with the
	   next lease on the list (if there is one). */
	if (head == lease) {
		delete_hash_entry (lease_hw_addr_hash,
				   lease -> hardware_addr.haddr,
				   lease -> hardware_addr.hlen);
		if (lease -> n_hw)
			add_hash (lease_hw_addr_hash,
				  lease -> n_hw -> hardware_addr.haddr,
				  lease -> n_hw -> hardware_addr.hlen,
				  (unsigned char *)(lease -> n_hw));
	} else {
		/* Otherwise, look for the lease in the list of leases
		   attached to the hash table entry, and remove it if
		   we find it. */
		for (scan = head; scan -> n_hw; scan = scan -> n_hw) {
			if (scan -> n_hw == lease) {
				scan -> n_hw = scan -> n_hw -> n_hw;
				break;
			}
		}
	}
	lease -> n_hw = (struct lease *)0;
}


struct class *add_class (type, name)
	int type;
	char *name;
{
	struct class *class = new_class ("add_class");
	char *tname = (char *)malloc (strlen (name) + 1);

	if (!vendor_class_hash)
		vendor_class_hash = new_hash ();
	if (!user_class_hash)
		user_class_hash = new_hash ();

	if (!tname || !class || !vendor_class_hash || !user_class_hash)
		return (struct class *)0;

	memset (class, 0, sizeof *class);
	strcpy (tname, name);
	class -> name = tname;

	if (type)
		add_hash (user_class_hash,
			  (unsigned char *)tname, strlen (tname),
			  (unsigned char *)class);
	else
		add_hash (vendor_class_hash,
			  (unsigned char *)tname, strlen (tname),
			  (unsigned char *)class);
	return class;
}

struct class *find_class (type, name, len)
	int type;
	unsigned char *name;
	int len;
{
	struct class *class =
		(struct class *)hash_lookup (type
					     ? user_class_hash
					     : vendor_class_hash, name, len);
	return class;
}

struct group *clone_group (group, caller)
	struct group *group;
	char *caller;
{
	struct group *g = new_group (caller);
	if (!g)
		error ("%s: can't allocate new group", caller);
	*g = *group;
	return g;
}

/* Write all interesting leases to permanent storage. */

void write_leases ()
{
	lease *l;
	shared_network *s;

	for (s = shared_networks; s; s = (shared_network *)s -> next) {
		for (l = s -> leases; l; l = l -> next) {
			if (l -> hardware_addr.hlen ||
			    l -> uid_len ||
			    (l -> flags & ABANDONED_LEASE))
				if (!write_lease (l))
					error ("Can't rewrite lease database");
		}
	}
	if (!commit_leases ())
		error ("Can't commit leases to new database: %m");
}

void dump_subnets ()
{
	struct _lease *l;
	shared_network *s;
        subnet *n;

	note ("Subnets:");
	for (n = subnets; n; n = n -> next_subnet) {
		debug ("  Subnet %s", piaddr (n -> net));
		debug ("     netmask %s",
		       piaddr (n -> netmask));
	}
	note ("Shared networks:");
	for (s = shared_networks; s; s = (shared_network *)s -> next) {
		note ("  %s", s -> name);
		for (l = s -> leases; l; l = l -> next) {
			print_lease (l);
		}
		if (s -> last_lease) {
			debug ("    Last Lease:");
			print_lease (s -> last_lease);
		}
	}
}

⌨️ 快捷键说明

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