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

📄 leases.c

📁 关于Linux下DHCP支持IPv6的版本实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "stdhead.h"#include "leases.h"#include "lib.h"struct lease_details * delete_lease_node (struct lease_details *p, struct lease_details *lease_struct){    extern struct lease_details *lease, *partial_lease;    struct lease_details *r, *q;    if (p == lease_struct)    {	q = p;	p = p -> next;	if (lease_struct == lease)	    lease = p;	else if (lease_struct == partial_lease)	    partial_lease = p;    }    else    {	r = lease_struct;	while (r != p)	{	    q = r;	    r = r -> next;	}	q -> next = p -> next;	q = p;	p = p -> next;    }        safe_free (q -> client_duid -> duid_type);    safe_free (q -> client_duid);    safe_free (q);    return p;}struct lease_details * read_leases_file (char *file_name){    struct lease_details *leases_head = 0, *p = 0, *q = 0;    struct DUID *d;    struct DUID1 *d1;    struct DUID2 *d2;    struct DUID3 *d3;    int fd, i;    u_int32_t temp;    u_int16_t temp1;    u_int8_t temp2;    char ch;        if ((fd = open (file_name, O_RDONLY)) == -1)    {#if DEBUG == 2	printf ("Could not open leases file %s\n", file_name);#endif	return NULL;    }        while (read (fd, &temp, sizeof (u_int32_t)) > 0)    {	q = (struct lease_details *) malloc (sizeof (struct lease_details));	if (!leases_head)	{	    leases_head = p = q;	    q -> next = 0;	}	else	{	    p -> next = q;	    p = q;	}		q -> u_iaid.iaid = temp;	read (fd, &q -> u_trans_id.trans_id, sizeof (u_int32_t));	read (fd, &q -> u_t1.t1, sizeof (u_int32_t));	read (fd, &q -> u_t2.t2, sizeof (u_int32_t));	read (fd, &q -> u_pref_lifetime.pref_lifetime, sizeof (u_int32_t));	read (fd, &q -> u_valid_lifetime.valid_lifetime, sizeof (u_int32_t));	read (fd, &q -> max_renew_count, sizeof (int));	read (fd, &q -> renew_count, sizeof (int));	read (fd, &q -> assigned_ipv6_addr, sizeof (struct in6_addr));	read (fd, &q -> prefix_length, sizeof (u_int8_t));		read (fd, &temp1, sizeof (u_int16_t));	d = (struct DUID *) malloc (sizeof (struct DUID));	q -> client_duid = d;	d -> u_duid_type.duid_type = temp1;	d -> opt = 0;		if (temp1 == 1)	{	    d1 = (struct DUID1 *) malloc (sizeof (struct DUID1));	    d -> duid_type = d1;	    	    read (fd, &temp1, sizeof (u_int16_t));	    d1 -> u_haddr_type.haddr_type = temp1;	    read (fd, &temp, sizeof (u_int32_t));	    d1 -> u_time.time = temp;	    read (fd, &temp1, sizeof (u_int16_t));	    d1 -> haddr_len = temp1;	    d1 -> link_layer_address = (u_int8_t *) malloc (d1 -> haddr_len * sizeof (u_int8_t));	    	    for (i = 0; i < d1 -> haddr_len; i++)	    {		read (fd, &temp2, sizeof (u_int8_t));		d1 -> link_layer_address[i] = temp2;	    }	}	else if (temp1 == 2)	{	    d2 = (struct DUID2 *) malloc (sizeof (struct DUID2));	    d -> duid_type = d2;    	    read (fd, &temp1, sizeof (u_int16_t));	    d2 -> u_identifier_length.identifier_length = temp1;	    d2 -> identifier = (u_int8_t *) malloc (d2 -> u_identifier_length.identifier_length * sizeof (u_int8_t));	    for (i = 0; i < d2 -> u_identifier_length.identifier_length; i++)	    {		read (fd, &temp2, sizeof (u_int8_t));		d2 -> identifier[i] = temp2;	    }	    read (fd, &i, sizeof (int));	    d2 -> domain_name_len = i;	    d2 -> domain_name = (char *) malloc (d2 -> domain_name_len * sizeof (char));	    for (i = 0; i < d2 -> domain_name_len; i++)	    {		read (fd, &ch, sizeof (char));		d2 -> domain_name[i] = ch;	    }	}	else if (temp1 == 3)	{	    d3 = (struct DUID3 *) malloc (sizeof (struct DUID3));	    d -> duid_type = d3;	    	    read (fd, &temp1, sizeof (u_int16_t));	    d3 -> u_haddr_type.haddr_type = temp1;	    read (fd, &temp1, sizeof (u_int16_t));	    d3 -> haddr_len = temp1;	    d3 -> link_layer_address = (u_int8_t *) malloc (d3 -> haddr_len * sizeof (u_int8_t));	    	    for (i = 0; i < d3 -> haddr_len; i++)	    {		read (fd, &temp2, sizeof (u_int8_t));		d3 -> link_layer_address[i] = temp2;	    }	}		read (fd, &q -> start_time, sizeof (time_t));    }        return leases_head;}void write_leases_file (char *file_name, struct lease_details *lease_struct){    struct lease_details *q = lease_struct;    struct DUID *d;    struct DUID1 *d1;    struct DUID2 *d2;    struct DUID3 *d3;    int fd, i;    char ch;        if ((fd = open (file_name, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)    {#if DEBUG == 2	printf ("Could not open leases file %s for writing\n", file_name);#endif    }        while (q)    {	write (fd, &q -> u_iaid.iaid, sizeof (u_int32_t));	write (fd, &q -> u_trans_id.trans_id, sizeof (u_int32_t));	write (fd, &q -> u_t1.t1, sizeof (u_int32_t));	write (fd, &q -> u_t2.t2, sizeof (u_int32_t));	write (fd, &q -> u_pref_lifetime.pref_lifetime, sizeof (u_int32_t));	write (fd, &q -> u_valid_lifetime.valid_lifetime, sizeof (u_int32_t));	write (fd, &q -> max_renew_count, sizeof (int));	write (fd, &q -> renew_count, sizeof (int));	write (fd, &q -> assigned_ipv6_addr, sizeof (struct in6_addr));	write (fd, &q -> prefix_length, sizeof (u_int8_t));		d = q -> client_duid;	write (fd, &d -> u_duid_type.duid_type, sizeof (u_int16_t));		switch (d -> u_duid_type.duid_type)	{	    case 1 :		d1 = (struct DUID1 *) d -> duid_type;		write (fd, &d1 -> u_haddr_type.haddr_type, sizeof (u_int16_t));		write (fd, &d1 -> u_time.time, sizeof (u_int32_t));		write (fd, &d1 -> haddr_len, sizeof (u_int16_t));		for (i = 0; i < d1 -> haddr_len; i++)		    write (fd, &d1 -> link_layer_address[i], sizeof (u_int8_t));		break;			    case 2 :		d2 = (struct DUID2 *) d -> duid_type;    		write (fd, &d2 -> u_identifier_length.identifier_length, sizeof (u_int16_t));		for (i = 0; i < d2 -> u_identifier_length.identifier_length; i++)		    write (fd, &d2 -> identifier[i], sizeof (u_int8_t));		write (fd, &d2 -> domain_name_len, sizeof (int));		for (i = 0; i < d2 -> domain_name_len; i++)		    write (fd, &d2 -> domain_name[i], sizeof (char));		break;			    case 3 :		d3 = (struct DUID3 *) d -> duid_type;		write (fd, &d3 -> u_haddr_type.haddr_type, sizeof (u_int16_t));		write (fd, &d3 -> haddr_len, sizeof (u_int16_t));		for (i = 0; i < d3 -> haddr_len; i++)		    write (fd, &d3 -> link_layer_address[i], sizeof (u_int8_t));		break;	}		write (fd, &q -> start_time, sizeof (time_t));	q = q -> next;    }}void check_leases_for_expiry (void){    extern struct lease_details *lease;    time_t current_time;    struct lease_details *p;        time (&current_time);    p = lease;        while (p)    {	if ((p -> start_time + p -> u_valid_lifetime.valid_lifetime) < current_time)	{	    // Lease has expired	    p = delete_lease_node (p, lease);	}	else	    p = p -> next;    }}void get_next_address (struct in6_addr * addr){    int i;    for (i = 15; i >= 0; i--)    {	if (addr->s6_addr[i] == (uint8_t)(-1))	    addr->s6_addr[i] = 0;	else	{	    addr->s6_addr[i]++;	    break ;	}    }}int get_pref_address (struct addr_details * available_addr, struct lease_details * partial_lease, 			struct lease_details * lease, struct config_head * head,			struct sockaddr_in6 client_address, struct OPTIONS *opt_ptr){    struct IA_ADDRESS *iaaddr_ptr = (struct IA_ADDRESS *) opt_ptr -> opt_data;    struct config_user *user_node = 0;    struct config_range *range_node = 0;    struct in6_addr check_addr;    int p_flag = 0, l_flag = 0;        // No address available in configuration file itself!    if (head -> first_node_type == NO_NODE)	return 0;	    // Check for user nodes first    if (head -> first_node_type == USER_NODE)	user_node = head -> next;    else if (head -> first_node_type == RANGE_NODE)	range_node = head -> next;	    while (user_node)    {	// Link local address of client is equal to that listed in the conf file	// Ignore preferred ipv6 address in this case	if (!memcmp (user_node -> link_local_addr, &client_address.sin6_addr, sizeof (struct in6_addr)))	{	    p_flag = l_flag = 0;	    p_flag = check_if_addr_in_lease_structure (*user_node -> ipv6_addr, partial_lease);	    l_flag = check_if_addr_in_lease_structure (*user_node -> ipv6_addr, lease);		    if (!(p_flag || l_flag))	    {		// Address available		memcpy (&available_addr -> ipv6_addr, user_node -> ipv6_addr, sizeof (struct in6_addr));		available_addr -> t1 = head -> t1;		available_addr -> t2 = head -> t2;		available_addr -> pref_life = user_node -> pref_life;		available_addr -> valid_life = user_node -> valid_life;		available_addr -> max_renew_count = user_node -> max_renew_count;		available_addr -> pref_val = user_node -> pref_val;		return 1;	    }	}		if (user_node -> next_node_type == USER_NODE)	    user_node = user_node -> next;	else if (user_node -> next_node_type == RANGE_NODE)	{	    range_node = user_node -> next;	    user_node = 0;	}	else if (user_node -> next_node_type == NO_NODE)	    user_node = 0;    }        // Check in the range nodes    while (range_node)    {	memcpy (&check_addr, range_node -> st_addr, sizeof (struct in6_addr));	while (memcmp (&check_addr, range_node -> end_addr, sizeof (struct in6_addr)))	{	   if (!memcmp (check_addr.s6_addr, iaaddr_ptr -> addr, 16))	   {	    p_flag = l_flag = 0;	    p_flag = check_if_addr_in_lease_structure (check_addr, partial_lease);	    l_flag = check_if_addr_in_lease_structure (check_addr, lease);		    if (!(p_flag || l_flag))	    {		// Address available	      memcpy (&available_addr -> ipv6_addr, &check_addr, sizeof (struct in6_addr));		available_addr -> t1 = head -> t1;	      available_addr -> t2 = head -> t2;		available_addr -> pref_life = range_node -> pref_life;    		available_addr -> valid_life = range_node -> valid_life;	      available_addr -> max_renew_count = range_node -> max_renew_count;		available_addr -> pref_val = range_node -> pref_val;	      return 1;	    }	   }	    get_next_address (&check_addr);	}	if (range_node -> next_node_type == RANGE_NODE)	    range_node = range_node -> next;	else if (range_node -> next_node_type == NO_NODE)	    range_node = 0;    }        return 0;}int get_available_address (struct addr_details * available_addr, struct lease_details * partial_lease, 			struct lease_details * lease, struct config_head * head,			struct sockaddr_in6 client_address){    struct config_user *user_node = 0;    struct config_range *range_node = 0;    struct in6_addr check_addr;    int p_flag = 0, l_flag = 0;        // No address available in configuration file itself!    if (head -> first_node_type == NO_NODE)	return 0;	    // Check for user nodes first    if (head -> first_node_type == USER_NODE)	user_node = head -> next;    else if (head -> first_node_type == RANGE_NODE)	range_node = head -> next;       // Traverse through all user nodes    while (user_node)    {	if (user_node -> next_node_type == USER_NODE)	    user_node = user_node -> next;	else if (user_node -> next_node_type == RANGE_NODE)	{	    range_node = user_node -> next;	    user_node = 0;	}	else if (user_node -> next_node_type == NO_NODE)	    user_node = 0;    }        // Check in the range nodes    while (range_node)    {	memcpy (&check_addr, range_node -> st_addr, sizeof (struct in6_addr));	while (memcmp (&check_addr, range_node -> end_addr, sizeof (struct in6_addr)))	{	    p_flag = l_flag = 0;	    p_flag = check_if_addr_in_lease_structure (check_addr, partial_lease);	    l_flag = check_if_addr_in_lease_structure (check_addr, lease);		    if (!(p_flag || l_flag))	    {		// Address available	      memcpy (&available_addr -> ipv6_addr, &check_addr, sizeof (struct in6_addr));		available_addr -> t1 = head -> t1;	      available_addr -> t2 = head -> t2;		available_addr -> pref_life = range_node -> pref_life;    		available_addr -> valid_life = range_node -> valid_life;	      available_addr -> max_renew_count = range_node -> max_renew_count;		available_addr -> pref_val = range_node -> pref_val;	      return 1;	    }	    	    get_next_address (&check_addr);	}	if (range_node -> next_node_type == RANGE_NODE)	    range_node = range_node -> next;	else if (range_node -> next_node_type == NO_NODE)	    range_node = 0;    }        return 0;}int check_if_addr_in_lease_structure (struct in6_addr addr, struct lease_details * lease_struct){    struct lease_details *p = lease_struct;    // No nodes present    if (!lease_struct)	return 0;	    while (p)    {	if (!memcmp (&p -> assigned_ipv6_addr, &addr, sizeof (struct in6_addr)))	    return 1;	else	    p = p -> next;    }        return 0;}void add_node_to_partial_lease_structure (struct DHCP_MESSAGE *advertise, 					struct addr_details *available_addr){    extern struct lease_details *partial_lease;    struct OPTIONS *options_ptr;    struct lease_details *p, *q, *r;    struct DUID *d;    struct DUID1 *d1;    struct DUID2 *d2;    struct DUID3 *d3;    struct IA *ia;    struct IA_ADDRESS *iaaddr;            p = (struct lease_details *) malloc (sizeof (struct lease_details));    p -> next = 0;    if (!partial_lease)	partial_lease = p;    else    {	r = partial_lease;	while (r)

⌨️ 快捷键说明

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