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

📄 clilib.c

📁 关于Linux下DHCP支持IPv6的版本实现
💻 C
📖 第 1 页 / 共 4 页
字号:
    fd_set readfds, tempfds;        return 0;        timeout.tv_sec = 2;    timeout.tv_usec = 0;    iaaddr_ptr = (struct IA_ADDRESS *) options_ptr -> opt_data;    FD_ZERO (&readfds);        INITIALIZE_SOCKADDR (sa);    inet_pton (AF_INET6, inet_ntop (AF_INET6, iaaddr_ptr -> addr, name, 64), &sa.sin6_addr);        icmp_fd = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);    size = 60 * 1024;    setsockopt (icmp_fd, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));    icmp6 = (struct icmp6_hdr *) buff;    icmp6 -> icmp6_type = ICMP6_ECHO_REQUEST;    icmp6 -> icmp6_code = 0;    srand (time(NULL));    icmp6 -> icmp6_id = rand ();    icmp6 -> icmp6_seq = 0;    icmp6 -> icmp6_cksum = 0;    gettimeofday ((struct timeval *) (icmp6 + 1), 0);    size = 8 + 56;    sendto (icmp_fd, buff, size, 0, (struct sockaddr * ) &sa, sizeof (sa));        FD_SET (icmp_fd, &readfds);    while (msg_count < 10)    {	timeout.tv_sec = 2;	timeout.tv_usec = 0;	tempfds = readfds;        select (icmp_fd + 1, &tempfds, 0, 0, &timeout);	if (FD_ISSET (icmp_fd, &tempfds))	{	    msg_count++;	    n = recvfrom (icmp_fd, reply, 1500, 0, 0, 0);	    ip6 = (struct ip6_hdr *) reply;	    hlen = sizeof (struct ip6_hdr);	    if (ip6 -> ip6_nxt != IPPROTO_ICMPV6)	    {		continue;	        return 0;	    }	    icmp6_reply = (struct icmp6_hdr *) (reply+hlen);	    if ((icmp6len = n - hlen) < 8)	    {		continue;	        return 0;	    }	    if (icmp6_reply -> icmp6_type == ICMP6_ECHO_REPLY)	    {	        if (icmp6_reply -> icmp6_id != icmp6 -> icmp6_id)		{		    continue;	    	    return 0;		}	        if (icmp6len < 16)		{		    continue;		    return 0;		}	    }	}        else	{	    msg_count++;	    continue;	    return 0;	}    }    return 1;}void set_ipv6_address (struct OPTIONS * options_ptr, char * interface_name){    struct IA_ADDRESS * iaaddr_ptr;    char command [150];    char addr[64];            if (!options_ptr)	return;	    iaaddr_ptr = (struct IA_ADDRESS *) options_ptr -> opt_data;    inet_ntop (AF_INET6, iaaddr_ptr -> addr, addr, 64);    strcpy (command, "/sbin/ifconfig ");    strcat (command, interface_name);    strcat (command, " add ");    strcat (command, addr);    strcat (command, "\0");        system (command);}void unset_ipv6_address (struct OPTIONS * options_ptr, char * interface_name){    struct IA_ADDRESS * iaaddr_ptr;    char command [150];    char addr[64];            if (!options_ptr)	return;	    iaaddr_ptr = (struct IA_ADDRESS *) options_ptr -> opt_data;    inet_ntop (AF_INET6, iaaddr_ptr -> addr, addr, 64);    strcpy (command, "/sbin/ifconfig ");    strcat (command, interface_name);    strcat (command, " del ");    strcat (command, addr);    strcat (command, "\0");        system (command);}// Create the option node and the option data node which are linked and returns// a pointer to the option nodestruct OPTIONS * copy_message_option (struct DHCP_MESSAGE * src, int option_type){    // Create an Options type node    struct OPTIONS * dest_options_ptr = (struct OPTIONS *) malloc (sizeof (struct OPTIONS));    struct OPTIONS * src_options_ptr = src -> opt;    struct DUID * src_duid_ptr, * dest_duid_ptr;    struct DUID1 * src_duid1_ptr, * dest_duid1_ptr;    struct DUID2 * src_duid2_ptr, * dest_duid2_ptr;    struct DUID3 * src_duid3_ptr, * dest_duid3_ptr;    struct IA * src_ia_ptr, * dest_ia_ptr;    struct IA_ADDRESS * src_iaaddr_ptr, * dest_iaaddr_ptr;    struct PREFERENCE * src_preference_ptr;    int i;            while (src_options_ptr)    {	if (src_options_ptr -> u_opt_code.opt_code == option_type)	{	    switch (option_type)	    {		case OPTION_CLIENTID :		case OPTION_SERVERID :		    // Assign the option type		    dest_options_ptr -> u_opt_code.opt_code = option_type;		    // Assign to the new option node len, the option len field of the advertise		    dest_options_ptr -> u_opt_len.opt_len = src_options_ptr -> u_opt_len.opt_len;		    // Allocate memory for the new option's duid		    dest_duid_ptr = (struct DUID *) malloc (sizeof (struct DUID));		    // Link the options node to the duid node		    dest_options_ptr -> opt_data = dest_duid_ptr;		    // Move on the duid node in the advertise message		    src_duid_ptr = src_options_ptr -> opt_data;		    // Assign the duid type field in the advertise message to the duid type field of the request message		    dest_duid_ptr -> u_duid_type.duid_type = src_duid_ptr -> u_duid_type.duid_type;		    // Assign zero to the next option pointer of the reply's duid node		    dest_duid_ptr -> opt = 0;		    switch (src_duid_ptr -> u_duid_type.duid_type)		    {			case 1 :			    // Allocate space for the DUID1 node type			    dest_duid1_ptr = (struct DUID1 *) malloc (sizeof (struct DUID1));			    // Link the duid node to the duid1 node			    dest_duid_ptr -> duid_type = dest_duid1_ptr;			    // Move on the advertise message's duid1 node			    src_duid1_ptr = (struct DUID1 *) src_duid_ptr -> duid_type;			    // Copy the hardware type from the advertise message to the reply message			    dest_duid1_ptr -> u_haddr_type.haddr_type = src_duid1_ptr -> u_haddr_type.haddr_type;			    // Copy the time field from advertise to the request message			    dest_duid1_ptr -> u_time.time = src_duid1_ptr -> u_time.time;			    // Copy the hardware address length 			    dest_duid1_ptr -> haddr_len = src_duid1_ptr -> haddr_len;			    // Allocate space for the link layer address			    dest_duid1_ptr -> link_layer_address = (u_int8_t *) malloc ((sizeof (u_int8_t)) * dest_duid1_ptr -> haddr_len);			    // Memory copy the link layer address from the advertise to the request			    memcpy (&dest_duid1_ptr -> link_layer_address, &src_duid1_ptr -> link_layer_address, dest_duid1_ptr -> haddr_len);			    break;			    			case 2 :			    dest_duid2_ptr = (struct DUID2 *) malloc (sizeof (struct DUID2));			    dest_duid_ptr -> duid_type = dest_duid2_ptr;			    src_duid2_ptr = (struct DUID2 *) src_duid_ptr -> duid_type;			    dest_duid2_ptr -> u_identifier_length.identifier_length = src_duid2_ptr -> u_identifier_length.identifier_length;			    dest_duid2_ptr -> identifier = (u_int8_t *) malloc ((sizeof (u_int8_t)) * dest_duid2_ptr -> u_identifier_length.identifier_length);			    memcpy (&dest_duid2_ptr -> identifier, &src_duid2_ptr -> identifier, dest_duid2_ptr -> u_identifier_length.identifier_length);			    dest_duid2_ptr -> domain_name_len = src_duid2_ptr -> domain_name_len;			    dest_duid2_ptr -> domain_name = (char *) malloc ((sizeof (char)) * dest_duid2_ptr -> domain_name_len);			    memcpy (&dest_duid2_ptr -> domain_name, &src_duid2_ptr -> domain_name, dest_duid2_ptr -> domain_name_len);			    break;			    			case 3 :			    dest_duid3_ptr = (struct DUID3 *) malloc (sizeof (struct DUID3));			    dest_duid_ptr -> duid_type = dest_duid3_ptr;			    src_duid3_ptr = (struct DUID3 *) src_duid_ptr -> duid_type;			    dest_duid3_ptr -> u_haddr_type.haddr_type = src_duid3_ptr -> u_haddr_type.haddr_type;			    dest_duid3_ptr -> haddr_len = src_duid3_ptr -> haddr_len;			    dest_duid3_ptr -> link_layer_address = (u_int8_t *) malloc ((sizeof (u_int8_t)) * dest_duid3_ptr -> haddr_len);			    memcpy (&dest_duid3_ptr -> link_layer_address, &src_duid3_ptr -> link_layer_address, dest_duid3_ptr -> haddr_len);			    break;		    }		    break;		    		case OPTION_IA :		    dest_options_ptr -> u_opt_code.opt_code = option_type;		    dest_options_ptr -> u_opt_len.opt_len = src_options_ptr -> u_opt_len.opt_len;		    dest_ia_ptr = (struct IA *) malloc (sizeof (struct IA));		    dest_options_ptr -> opt_data = dest_ia_ptr;		    src_ia_ptr = (struct IA *) src_options_ptr -> opt_data;		    dest_ia_ptr -> u_iaid.iaid = src_ia_ptr -> u_iaid.iaid;		    dest_ia_ptr -> u_t1.t1 = src_ia_ptr -> u_t1.t1;		    dest_ia_ptr -> u_t2.t2 = src_ia_ptr -> u_t2.t2;		    dest_ia_ptr -> status = src_ia_ptr -> status;		    dest_ia_ptr -> opt = 0;		    break;		    		case OPTION_IAADDR :		    dest_options_ptr -> u_opt_code.opt_code = option_type;		    dest_options_ptr -> u_opt_len.opt_len = src_options_ptr -> u_opt_len.opt_len;		    dest_iaaddr_ptr = (struct IA_ADDRESS *) malloc (sizeof (struct IA_ADDRESS));		    dest_options_ptr -> opt_data = dest_iaaddr_ptr;		    src_iaaddr_ptr = (struct IA_ADDRESS *) src_options_ptr -> opt_data;		    dest_iaaddr_ptr -> t_bit = src_iaaddr_ptr -> t_bit;		    dest_iaaddr_ptr -> addr_status = src_iaaddr_ptr -> addr_status;		    dest_iaaddr_ptr -> prefix_length = src_iaaddr_ptr -> prefix_length;		    for (i = 0; i <= 15; i++)			dest_iaaddr_ptr -> addr[i] = src_iaaddr_ptr -> addr[i];		    dest_iaaddr_ptr -> u_pref_lifetime.pref_lifetime = src_iaaddr_ptr -> u_pref_lifetime.pref_lifetime;		    dest_iaaddr_ptr -> u_valid_lifetime.valid_lifetime = src_iaaddr_ptr -> u_valid_lifetime.valid_lifetime;		    dest_iaaddr_ptr -> ia_addr_opt = 0;		    dest_iaaddr_ptr -> opt = 0;		    break;	    }	    return dest_options_ptr;	}	else	{	    switch (src_options_ptr -> u_opt_code.opt_code)	    {		case OPTION_CLIENTID :		case OPTION_SERVERID :		    src_duid_ptr = src_options_ptr -> opt_data;		    src_options_ptr = src_duid_ptr -> opt;		    break;				case OPTION_IA :		    src_ia_ptr = src_options_ptr -> opt_data;		    src_options_ptr = src_ia_ptr -> opt;		    break;				case OPTION_IAADDR :		    src_iaaddr_ptr = src_options_ptr -> opt_data;		    src_options_ptr = src_iaaddr_ptr -> opt;		    break;		    		case OPTION_PREFERENCE :		    src_preference_ptr = src_options_ptr -> opt_data;		    src_options_ptr = src_preference_ptr -> opt;		    break;	    }	}    }    return 0;}void get_timers (struct DHCP_MESSAGE * server_reply, u_int32_t * renew_timer, u_int32_t * rebind_timer, u_int32_t * valid_lifetime_timer){    struct OPTIONS * options_ptr;    struct IA * ia_ptr;    struct IA_ADDRESS * iaaddr_ptr;    options_ptr = get_options_ptr (server_reply, OPTION_IA);    if (!options_ptr)	return;    ia_ptr = (struct IA *) options_ptr -> opt_data;    * renew_timer = ia_ptr -> u_t1.t1;    * rebind_timer = ia_ptr -> u_t2.t2;    options_ptr = get_options_ptr (server_reply, OPTION_IAADDR);    if (!options_ptr)	return;    iaaddr_ptr = (struct IA_ADDRESS *) options_ptr -> opt_data;    * valid_lifetime_timer = iaaddr_ptr -> u_valid_lifetime.valid_lifetime;}int check_for_duid_match (struct OPTIONS * options_ptr){   extern struct DUID * server_duid_ptr;   struct DUID * duid_ptr;   struct DUID1 * duid1_ptr;   struct DUID2 * duid2_ptr;   struct DUID3 * duid3_ptr;      if (!options_ptr)	return 0;      duid_ptr = (struct DUID *) options_ptr -> opt_data;   if (server_duid_ptr -> u_duid_type.duid_type != duid_ptr -> u_duid_type.duid_type)	return 0;   switch (duid_ptr -> u_duid_type.duid_type)   {	case 1 :	   duid1_ptr = (struct DUID1 *) duid_ptr -> duid_type;	   if (!check_duid1 ((struct DUID1 *) server_duid_ptr -> duid_type, duid1_ptr))		return 0;	   break;	case 2 :	   duid2_ptr = (struct DUID2 *) duid_ptr -> duid_type;	   if (!check_duid2 ((struct DUID2 *) server_duid_ptr -> duid_type, duid2_ptr))		return 0;	   break;	case 3 :	   duid3_ptr = (struct DUID3 *) duid_ptr -> duid_type;	   if (!check_duid3 ((struct DUID3 *) server_duid_ptr -> duid_type, duid3_ptr))		return 0;	   break;   }   return 1;}   int check_reply_message (struct DHCP_MESSAGE * reply_message, int sent_type){    extern int g_trans_id;    int status;    struct OPTIONS *opt_ptr = get_options_ptr (reply_message, OPTION_IA);    struct IA *ia_ptr;        if (opt_ptr)      ia_ptr = (struct IA *) opt_ptr -> opt_data;        if (reply_message->u_msg_type.msg_type != REPLY)	return 0;	    if (reply_message->u_trans_id.trans_id != g_trans_id)       return 0;	       switch (sent_type)   {	case REQUEST :	   if ((status = check_for_status (reply_message)) != -1)		if (status != Success)		   return 0;	   if (!check_for_option (OPTION_SERVERID, reply_message))		return 0;	   if (!check_for_option (OPTION_IA, reply_message))		return 0;	   if (!check_for_option (OPTION_IAADDR, reply_message))		return 0;	   break;	case DECLINE :	case RELEASE :	   if (!check_for_duid_match (get_options_ptr (reply_message, OPTION_SERVERID)))		return 0;	   if ((status = check_for_status (reply_message)) != -1)		if (status != Success)		    return 0;	   if (!check_for_option (OPTION_SERVERID, reply_message))		return 0;	   break;	case RENEW :	case REBIND :	   if (check_for_duid_match (get_options_ptr (reply_message, OPTION_SERVERID)))		return 1;	   else		return 0;	   break;   }    return 1;}char ** get_all_interfaces (char * file_name, int * count){    char ** interface = 0 , ** p = 0;    char * buff = 0, * curr_ptr = 0, *token = 0;    read_config_file (&buff, DEFAULT_SOLICIT_CONFIG_FILE);    curr_ptr = buff;    *count = 0;        while (move_across_substring (&curr_ptr, "interface"))    {	skip_whitespace (&curr_ptr);	read_token (&token, &curr_ptr);	interface = (char **) realloc (interface, ++(*count) * sizeof (char *));	p = interface + (*count) -1;	*p = (char *) malloc (strlen (token) * sizeof (char));	strcpy (*p, token);    }    return interface;}int check_ia_status (struct DHCP_MESSAGE * message){    struct OPTIONS * options_ptr = get_options_ptr (message, OPTION_IA);    struct IA * ia_ptr;    if (!options_ptr)	return 0;    ia_ptr = (struct IA *) options_ptr -> opt_data;    if (ia_ptr -> status == RenwNoMatch || ia_ptr -> status == RebdNoMatch || ia_ptr -> status == AddrUnavail || ia_ptr -> status == NoBinding)	return ia_ptr -> status;    return 0;}void copy_duid1 (struct DUID1 *d1, struct DUID1 *duid){    int i;        duid -> u_haddr_type.haddr_type = d1 -> u_haddr_type.haddr_type;    duid -> haddr_len = d1 -> haddr_len;    duid -> u_time.time = d1 -> u_time.time;    duid -> link_layer_address = (u_int8_t *) malloc (d1 -> haddr_len * sizeof (u_int8_t));    for (i = 0; i < d1 -> haddr_len; i++)	duid -> link_layer_address[i] = d1 -> link_layer_address[i];}void copy_duid2 (struct DUID2 *d2, struct DUID2 *duid){    int i;        duid -> u_identifier_length.identifier_length = d2 -> u_identifier_length.identifier_length;    duid -> domain_name_len = d2 -> domain_name_len;    duid -> 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++)	duid -> identifier[i] = d2 -> identifier[i];    duid -> domain_name = (char *) malloc (d2 -> domain_name_len * sizeof (char));    for (i = 0; i < d2 -> domain_name_len; i++)	duid -> domain_name[i] = d2 -> domain_name[i];}void copy_duid3 (struct DUID3 *d3, struct DUID3 *duid){    int i;        duid -> u_haddr_type.haddr_type = d3 -> u_haddr_type.haddr_type;    duid -> haddr_len = d3 -> haddr_len;    duid -> link_layer_address = (u_int8_t *) malloc (d3 -> haddr_len * sizeof (u_int8_t));    for (i = 0; i < d3 -> haddr_len; i++)	duid -> link_layer_address[i] = d3 -> link_layer_address[i];}int check_duid1 (struct DUID1 *d1, struct DUID1 *duid){    int i;        if (duid -> u_haddr_type.haddr_type != d1 -> u_haddr_type.haddr_type)      return 0;    if (duid -> u_time.time != d1 -> u_time.time)      return 0;    if (duid -> haddr_len != d1 -> haddr_len)      return 0;    for (i = 0; i < d1 -> haddr_len; i++)      if (duid -> link_layer_address[i] != d1 -> link_layer_address[i])	   return 0;    return 1;}int check_duid2 (struct DUID2 *d2, struct DUID2 *duid){    int i;        if (duid -> u_identifier_length.identifier_length != d2 -> u_identifier_length.identifier_length)      return 0;    if (duid -> domain_name_len != d2 -> domain_name_len)      return 0;    for (i = 0; i < d2 -> u_identifier_length.identifier_length; i++)      if (duid -> identifier[i] != d2 -> identifier[i])	   return 0;    for (i = 0; i < d2 -> domain_name_len; i++)      if (duid -> domain_name[i] != d2 -> domain_name[i])	   return 0;    return 1;}int check_duid3 (struct DUID3 *d3, struct DUID3 *duid){    int i;        if (duid -> u_haddr_type.haddr_type != d3 -> u_haddr_type.haddr_type)      return 0;    if (duid -> haddr_len != d3 -> haddr_len)      return 0;    for (i = 0; i < d3 -> haddr_len; i++)      if (duid -> link_layer_address[i] != d3 -> link_layer_address[i])	   return 0;    return 1;}

⌨️ 快捷键说明

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