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

📄 clilib.c

📁 关于Linux下DHCP支持IPv6的版本实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	    }	    break;		case OPTION_PREFERENCE :	    preference_ptr = (struct PREFERENCE *) malloc (sizeof (struct PREFERENCE));	    opt -> opt_data = preference_ptr;	    preference_ptr -> preference_value = m[index++];	    next_opt = (struct OPTIONS *) malloc (sizeof (struct OPTIONS));	    if (index == len)	        preference_ptr -> opt = 0;	    else	    {	        read_option (m, index, len, next_opt);	        preference_ptr -> opt = next_opt;	    }	    break;		default :#if DEBUG == 3	    printf ("Invalid option type\n");#endif	    opt = 0;	    index = len; 	    return;    }}/*     This function deallocates the memory space consumed by the dhcp message.    It returns void.*/void free_message_mem (struct DHCP_MESSAGE *dhcp_message){    struct OPTIONS *options_ptr;    struct DUID *duid_ptr;    struct DUID1 *duid1_ptr;    struct DUID2 *duid2_ptr;    struct DUID3 *duid3_ptr;    struct IA *ia_ptr;    struct IA_ADDRESS *ia_addr_ptr;    struct PREFERENCE *preference;    struct STATUS_CODE *sc_ptr;    options_ptr = dhcp_message->opt;    free (dhcp_message);    while (options_ptr) // loop until the end of the linked list.    {	switch (options_ptr->u_opt_code.opt_code)  // determines the option code.        {	    case OPTION_CLIENTID :	    case OPTION_SERVERID :	    	duid_ptr = (struct DUID *) options_ptr->opt_data;		free (options_ptr);	    		switch (duid_ptr -> u_duid_type.duid_type) // determines the duid type.		{		    case 1 :			duid1_ptr = (struct DUID1 *) duid_ptr->duid_type;			free (duid1_ptr -> link_layer_address);			free (duid1_ptr);			break;					    case 2 :			duid2_ptr = (struct DUID2 *) duid_ptr->duid_type;			free (duid2_ptr->identifier);			free (duid2_ptr->domain_name);			free (duid2_ptr);			break;		    case 3 :			duid3_ptr = (struct DUID3 *) duid_ptr->duid_type;			free (duid3_ptr->link_layer_address);			free (duid3_ptr);			break;		}		options_ptr = duid_ptr->opt;		free (duid_ptr);		break;			    case OPTION_IA :		ia_ptr = (struct IA *) options_ptr->opt_data; 		free (options_ptr);		options_ptr = ia_ptr->opt;		free (ia_ptr);		break;			    case OPTION_IAADDR :		ia_addr_ptr = (struct IA_ADDRESS *) options_ptr->opt_data;		free (options_ptr);		options_ptr = ia_addr_ptr->opt;		free (ia_addr_ptr);		break;			    case OPTION_PREFERENCE :		preference = (struct PREFERENCE *) options_ptr -> opt_data;		free (options_ptr);		options_ptr = preference -> opt;		free (preference);		break;			    case OPTION_STATUS_CODE :		sc_ptr = (struct STATUS_CODE *) options_ptr -> opt_data;		free (options_ptr);		options_ptr = sc_ptr -> opt;		free (sc_ptr->message);		free (sc_ptr);		break;			    default :		options_ptr = 0;		break;	}    }}// This function returns the preference value of the message being sent as// parameter. If there is no PREFERENCE option then 0 is returnedu_int8_t get_preference_value (struct DHCP_MESSAGE *message){    struct OPTIONS * opt;    struct DUID *duid_ptr;    struct IA *ia_ptr;    struct IA_ADDRESS * iaaddr_ptr;    struct STATUS_CODE * status_ptr;    struct PREFERENCE * preference;        if (!message)	return 0;	        // Move to the first option of the message    opt = message->opt;        // Until no options are left    while (opt)    {	switch(opt->u_opt_code.opt_code)	{	    case OPTION_CLIENTID :	    case OPTION_SERVERID :		// Move onto the next node		duid_ptr = (struct DUID *) opt -> opt_data;		opt = duid_ptr -> opt;		break;			    case OPTION_IA : 		// Move onto the next node		ia_ptr= (struct IA *) opt -> opt_data;		opt = ia_ptr->opt;		break;			    case OPTION_IAADDR :		// Move onto the next node	        iaaddr_ptr=(struct IA_ADDRESS *) opt -> opt_data;		opt = iaaddr_ptr->opt;		break;			    case OPTION_STATUS_CODE :		// Move onto the next node	        status_ptr=(struct STATUS_CODE *) opt -> opt_data;		opt = status_ptr->opt;		break;			    case OPTION_PREFERENCE :		// Return the preference value		preference = (struct PREFERENCE *) opt -> opt_data;		return preference->preference_value;			    default :		opt = 0;		break;	}	    }    return 0;}// This function returns the preferred IPv6 address of the message being sent as// parameter. If there is no IAADDR option then 0 is returnedu_int8_t * get_pref_ipv6_address (struct DHCP_MESSAGE *message){    struct OPTIONS * opt;    struct DUID *duid_ptr;    struct IA *ia_ptr;    struct IA_ADDRESS * iaaddr_ptr;    struct STATUS_CODE * status_ptr;    struct PREFERENCE * preference;        if (!message)	return 0;	    // Move to the first option of the message    opt = message->opt;        // Until no options are left    while (opt)    {	switch(opt->u_opt_code.opt_code)	{	    case OPTION_CLIENTID :	    case OPTION_SERVERID :		// Move onto the next node		duid_ptr = (struct DUID *) opt -> opt_data;		opt = duid_ptr -> opt;		break;			    case OPTION_IA : 		// Move onto the next node		ia_ptr= (struct IA *) opt -> opt_data;		opt = ia_ptr->opt;		break;			    case OPTION_IAADDR :		// Return the preferred address	        iaaddr_ptr=(struct IA_ADDRESS *) opt -> opt_data;		return iaaddr_ptr -> addr;		//opt = iaaddr_ptr->opt;		break;			    case OPTION_STATUS_CODE :		// Move onto the next node	        status_ptr=(struct STATUS_CODE *) opt -> opt_data;		opt = status_ptr->opt;		break;			    case OPTION_PREFERENCE :		// Move onto the next node		preference = (struct PREFERENCE *) opt -> opt_data;		opt = preference->opt;		break;			    default :		opt = 0;		break;	}	    }    return 0;}// This function returns the prefereed lifetime of the message that has been sent// to it as parameter.It the message does not have a preferred lifetime then // the function returns 0.*/u_int32_t get_pref_lifetime (struct DHCP_MESSAGE *message){    struct OPTIONS * opt;    struct DUID *duid_ptr;    struct IA *ia_ptr;    struct IA_ADDRESS * iaaddr_ptr;    struct STATUS_CODE * status_ptr;    struct PREFERENCE * preference_ptr;        if (!message)	return 0;	    // Move to the first option of the message    opt = message->opt;        // Until no options are left    while (opt)    {	switch(opt->u_opt_code.opt_code)	{	    case OPTION_CLIENTID :	    case OPTION_SERVERID :		// Move onto the next node		duid_ptr = (struct DUID *) opt -> opt_data;		opt = duid_ptr -> opt;		break;			    case OPTION_IA : 		// Move onto the next node		ia_ptr= (struct IA *) opt -> opt_data;		opt = ia_ptr -> opt;		break;			    case OPTION_IAADDR :		// Return the preferred lifetime		iaaddr_ptr = (struct IA_ADDRESS *) opt->opt_data;		return iaaddr_ptr -> u_pref_lifetime.pref_lifetime;		break;			    case OPTION_PREFERENCE :		// Move onto the next node		preference_ptr = (struct PREFERENCE *) opt -> opt_data;		opt = preference_ptr -> opt;		break;			    default :		opt = 0;		break;	}    }    return 0;}		struct DHCP_MESSAGE * select_server (struct DHCP_MESSAGE ** server_reply, int msg_count, char * interface_name){    struct DHCP_MESSAGE **p;    // POinters to the list of messages    struct DHCP_MESSAGE *best = 0, *curr = 0;        // Pointer to Interface Details    struct interface * interface_details;        // Pointer to IPv6 addresses    u_int8_t *best_pref_ipv6_addr = 0, *curr_pref_ipv6_addr = 0;        // Variables to stores the best and current nodes Prefereed lifetimes    u_int32_t best_pref_lifetime = 0, curr_pref_lifetime = 0;        // Message index in the array of pointers to messages    int index = 0;        // Best and current node values of nodes    u_int8_t max_preference_value = 0, curr_preference_value;        // Get the Interface details for a particular interface    interface_details = get_interface_details (interface_name);        // Set current pointer to the first mesage    curr = *server_reply;        // Until all messages have been checked or best message has been found        while (index < msg_count)    {	// get the preference value for the current node        curr_preference_value = get_preference_value (curr);		// If the current preference value is equal to 255 return current pointer	// as the best message	if (curr_preference_value == MAX_PREFERENCE_VALUE)	    return curr;	    	// If the current preference value is better than the previously best	// preference value, assign the current message as the best message	// and the current preference value as the maximum preference value    	else if (curr_preference_value > max_preference_value)	{	    best = curr;	    max_preference_value = curr_preference_value;	}		// If the current preference value if equal to the previously best	// preference value then ccompare the two message and decide which is	// the best	else if (curr_preference_value == max_preference_value)	{	    if (!best)	    {		best = curr;		// Increment the message index		index++;		// Move to the next message		p = server_reply + index;		curr = *p;		continue;	    }			    // get the preferered IPv6 address for the best node	    best_pref_ipv6_addr = get_pref_ipv6_address (best);	    	    // If the best messages preferred IPv6 address is not equal to	    // the preferred IPv6 address in the interface configuartion	    if (interface_details->pref_ipv6_addr && memcmp (best_pref_ipv6_addr, interface_details->pref_ipv6_addr->s6_addr, 16))	    {		// Get the prefereed IPv6 address of the current node		curr_pref_ipv6_addr = get_pref_ipv6_address (curr);				// If the preferred IPv6 address of the current node is equal		// to the preferred IPv6 address of the particular interface,		// assign the current message as the best message		if (interface_details->pref_ipv6_addr && !memcmp (curr_pref_ipv6_addr, interface_details->pref_ipv6_addr->s6_addr, 16))		    best = curr;		else		{		    // Get the preferred lifetime for the best node		    best_pref_lifetime = get_pref_lifetime (best);		    // Get the prefereed lifetime for the current node		    curr_pref_lifetime = get_pref_lifetime (curr);		    // if the best nodes preferred lifetime is less than the		    // current nodes lifetime then assgin the best node as the		    // current node		    if (best_pref_lifetime < curr_pref_lifetime )			best = curr;		}	    }	}	// Increment the message index	index++;	// Move to the next message	p = server_reply + index;	curr = *p;    }    // Return the pointer to the best message    return best;}struct DHCP_MESSAGE ** purge_message (struct DHCP_MESSAGE ** server_reply, struct DHCP_MESSAGE * target, int * msg_count){    struct DHCP_MESSAGE * curr;    int i, index = 0;    curr = *server_reply;    while (index < *msg_count)    {	if (curr == target)	{	    free_message_mem (curr);	    for (i = index; i < (*msg_count) - 1; i++)		server_reply [i] = server_reply [i+1];	    (*msg_count)--;	    break;	}	index++;    }        server_reply = (struct DHCP_MESSAGE ** ) realloc (server_reply, sizeof (struct DHCP_MESSAGE *) * (*msg_count));    return server_reply;}struct OPTIONS * get_options_ptr (struct DHCP_MESSAGE * dhcp_msg_ptr, int option){    struct OPTIONS * options_ptr = dhcp_msg_ptr -> opt;    struct DUID * duid_ptr;    struct IA * ia_ptr;    struct IA_ADDRESS * iaaddr_ptr;    struct PREFERENCE * preference_ptr;    struct STATUS_CODE * status_ptr;    while (options_ptr)    {        if (options_ptr -> u_opt_code.opt_code == option)            return options_ptr;        switch (options_ptr -> u_opt_code.opt_code)        {            case OPTION_CLIENTID :            case OPTION_SERVERID :                duid_ptr = (struct DUID *) options_ptr -> opt_data;                options_ptr = duid_ptr -> opt;                break;            case OPTION_IA :                ia_ptr = (struct IA *) options_ptr -> opt_data;                options_ptr = ia_ptr -> opt;                break;            case OPTION_IAADDR :                iaaddr_ptr = (struct IA_ADDRESS *) options_ptr -> opt_data;                options_ptr = iaaddr_ptr -> opt;                break;            case OPTION_PREFERENCE :                preference_ptr = (struct PREFERENCE *) options_ptr -> opt_data;                options_ptr = preference_ptr -> opt;                break;            case OPTION_STATUS_CODE :                status_ptr = (struct STATUS_CODE *) options_ptr -> opt_data;                options_ptr = status_ptr -> opt;                break;			    default :		options_ptr = 0;		break;        }    }    return 0;}int check_address_in_use (struct OPTIONS * options_ptr){    int icmp_fd, size, n, hlen, icmp6len, msg_count = 0;    char buff[1500], reply[1500];    struct sockaddr_in6 sa;    char name[64];    struct icmp6_hdr * icmp6, * icmp6_reply;    struct ip6_hdr * ip6;    socklen_t len;    struct IA_ADDRESS * iaaddr_ptr;    struct timeval timeout;

⌨️ 快捷键说明

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