📄 leases.c
字号:
#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 (¤t_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 + -