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

📄 lib.c

📁 关于Linux下DHCP支持IPv6的版本实现
💻 C
📖 第 1 页 / 共 3 页
字号:
    {        switch (ch)        {    	    case 'A' :	    case 'a' :		hex = 10;		break;		    	    case 'B' :	    case 'b' :		hex = 11;		break;		    	    case 'C' :	    case 'c' :		hex = 12;		break;		    	    case 'D' :	    case 'd' :		hex = 13;		break;		    	    case 'E' :	    case 'e' :		hex = 14;		break;		    	    case 'F' :	    case 'f' :		hex = 15;		break;	}    }        return hex;}void generate_trans_id (u_int32_t *trans_id){    time_t t;    srand (time (&t));    *trans_id = 0;    *trans_id = rand();    // Make the upper byte of trans id = 0    *trans_id &= 0x00ffffff;}void read_option (char *m, int index, int len, struct OPTIONS *opt){    int i, temp;    struct DUID *d;    struct DUID1 *d1;    struct DUID2 *d2;    struct DUID3 *d3;    struct IA *ia;    struct IA_ADDRESS *ia_addr;    struct PREFERENCE *pref_ptr;    struct STATUS_CODE *sc_ptr;    struct OPTIONS *next_opt;    u_int8_t *l_ptr;    union    {	char buffer[2];	u_int16_t type_of_duid;    } u_type_of_duid;        for (i = 1; i >= 0; i--)	opt -> u_opt_code.buffer[i] = m[index++];	    for (i = 1; i >= 0; i--)      opt -> u_opt_len.buffer[i] = m[index++];    switch (opt -> u_opt_code.opt_code)    {	case OPTION_CLIENTID :      case OPTION_SERVERID :	    d = (struct DUID *) malloc (sizeof (struct DUID));	    opt -> opt_data = d;	    	    for (i = 1; i >= 0; i--)		u_type_of_duid.buffer[i] = m[index++];	    switch (u_type_of_duid.type_of_duid)	    {		case 1 :		    d1 = (struct DUID1 *) malloc (sizeof (struct DUID1));		    d -> u_duid_type.duid_type = 1;		    		    for (i = 1; i >= 0; i--)			d1 -> u_haddr_type.buffer[i] = m[index++];		    for (i = 3; i >= 0; i--)			d1 -> u_time.buffer[i] = m[index++];		    // DUID Type = 2 octets		    // Hardware type field = 2 octets		    // Time field = 4 octets		    d1 -> haddr_len = opt -> u_opt_len.opt_len - 2 - 2 - 4;		    d1 -> link_layer_address = (u_int8_t *) malloc (sizeof (u_int8_t) * d1->haddr_len);		    for (i = d1 -> haddr_len; i >= 0; i--)	                d1 -> link_layer_address[i] = m[index++];		    d -> duid_type = d1;		    break;		    		case 2 :		    d2 = (struct DUID2 *) malloc (sizeof (struct DUID2));		    d -> u_duid_type.duid_type = 2;		    		    for (i = 1; i >= 0; i--)			d2 -> u_identifier_length.buffer[i] = m[index++];		    d2 -> identifier = (u_int8_t *) malloc (sizeof (u_int8_t) * d2 -> u_identifier_length.identifier_length);		    for (i = d2 -> u_identifier_length.identifier_length; i >= 0; i--)	                d2 -> identifier[i] = m[index++];		    		    // DUID Type = 2 octets		    // Identifier length field = 2 octets		    temp = opt -> u_opt_len.opt_len - 2 - 2 - d2 -> u_identifier_length.identifier_length;		    d2 -> domain_name = (u_char *) malloc (sizeof (char) * temp);		    for (i = temp; i >= 0; i--)	                d2 -> domain_name[i] = m[index++];		    d2 -> domain_name_len = temp;		    d -> duid_type = d2;		    break;		case 3 :		    d3 = (struct DUID3 *) malloc (sizeof (struct DUID3));		    d -> u_duid_type.duid_type = 3;		    		    for (i = 1; i >= 0; i--)			d3 -> u_haddr_type.buffer[i] = m[index++];		    // DUID Type = 2 octets		    // Hardware type field = 2 octets		    d3 -> haddr_len = opt -> u_opt_len.opt_len - 2 - 2;		    d3->link_layer_address = (u_int8_t *) malloc (sizeof (u_int8_t) * d3->haddr_len);		    for (i = d3 -> haddr_len; i >= 0; i--)	                d3 -> link_layer_address[i] = m[index++];		    d -> duid_type = d3;		    break;		default :#if DEBUG == 2		    printf ("Unrecognized DUID type\n");#endif		    index += opt -> u_opt_len.opt_len;		    break;	    }	    next_opt = (struct OPTIONS *) malloc (sizeof (struct OPTIONS));	    if (index == len)		d -> opt = 0;	    else	    {		read_option (m, index, len, next_opt);		d -> opt = next_opt;	    }	    break;	    	case OPTION_IA :	    ia = (struct IA *) malloc (sizeof (struct IA));	    opt -> opt_data = ia;	    	    for (i = 3; i >= 0; i--)		ia -> u_iaid.buffer[i] = m[index++];	    for (i = 3; i >= 0; i--)		ia -> u_t1.buffer[i] = m[index++];	    for (i = 3; i >= 0; i--)		ia -> u_t2.buffer[i] = m[index++];	    ia -> status = m[index++];	    next_opt = (struct OPTIONS *) malloc (sizeof (struct OPTIONS));	    read_option (m, index, len, next_opt);	    ia -> opt = next_opt;	    break;	    	case OPTION_IAADDR :	    ia_addr = (struct IA_ADDRESS *) malloc (sizeof (struct IA_ADDRESS));	    opt -> opt_data = ia_addr;	    temp = m[index++];	    if (temp / 128)		ia_addr -> t_bit = 1;	    else		ia_addr -> t_bit = 0;			    ia_addr -> addr_status = temp % 128;	    ia_addr -> prefix_length = m[index++];	    for (i = 15; i >= 0; i--)		ia_addr -> addr[i] = m[index++];	    for (i = 3; i >= 0; i--)		ia_addr -> u_pref_lifetime.buffer[i] = m[index++];	    for (i = 3; i >= 0; i--)		ia_addr -> u_valid_lifetime.buffer[i] = m[index++];			    ia_addr -> ia_addr_opt = 0;	    next_opt = (struct OPTIONS *) malloc (sizeof (struct OPTIONS));	    if (index == len)		ia_addr -> opt = 0;	    else	    {		read_option (m, index, len, next_opt);		ia_addr -> opt = next_opt;	    }	    break;	case OPTION_PREFERENCE :	    pref_ptr = (struct PREFERENCE *) malloc (sizeof (struct PREFERENCE));	    opt -> opt_data = pref_ptr;	    pref_ptr -> preference_value = m[index++];	    	    next_opt = (struct OPTIONS *) malloc (sizeof (struct OPTIONS));	    if (index == len)		pref_ptr -> opt = 0;	    else	    {		read_option (m, index, len, next_opt);		pref_ptr -> opt = next_opt;	    }	    break;	    	case OPTION_STATUS_CODE :	    sc_ptr = (struct STATUS_CODE *) malloc (sizeof (struct STATUS_CODE));	    opt -> opt_data = sc_ptr;	    	    for (i = 1; i >= 0; i--)		sc_ptr -> u_status_code.buffer[i] = m[index++];	    sc_ptr -> message = (char *) malloc (sizeof (char) * (opt -> u_opt_len.opt_len - 2));	    for (i = opt -> u_opt_len.opt_len - 2; i >= 0; i--)		sc_ptr -> message[i] = m[index++];	    next_opt = (struct OPTIONS *) malloc (sizeof (struct OPTIONS));	    if (index == len)		sc_ptr -> opt = 0;	    else	    {		read_option (m, index, len, next_opt);		sc_ptr -> opt = next_opt;	    }	    break;	    	default :#if DEBUG == 2	    printf ("Invalid option type\n");#endif	   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 *pref_ptr;    struct STATUS_CODE *sc_ptr;        options_ptr = dhcp_message->opt;    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;		safe_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;			safe_free (duid1_ptr -> link_layer_address);			safe_free (duid1_ptr);			break;					    case 2 :			duid2_ptr = (struct DUID2 *) duid_ptr->duid_type;			safe_free (duid2_ptr->identifier);			safe_free (duid2_ptr->domain_name);			safe_free (duid2_ptr);			break;		    case 3 :			duid3_ptr = (struct DUID3 *) duid_ptr->duid_type;			safe_free (duid3_ptr->link_layer_address);			safe_free (duid3_ptr);			break;		}		options_ptr = duid_ptr->opt;		safe_free (duid_ptr);		break;			    case OPTION_IA :		ia_ptr = (struct IA *) options_ptr->opt_data; 		safe_free (options_ptr);		options_ptr = ia_ptr->opt;		safe_free (ia_ptr);		break;			    case OPTION_IAADDR :		ia_addr_ptr = (struct IA_ADDRESS *) options_ptr->opt_data;		safe_free (options_ptr);		options_ptr = ia_addr_ptr->opt;		safe_free (ia_addr_ptr);		break;			    case OPTION_PREFERENCE :		pref_ptr = (struct PREFERENCE *) options_ptr -> opt_data;		safe_free (options_ptr);		options_ptr = pref_ptr -> opt;		safe_free (pref_ptr);		break;			    case OPTION_STATUS_CODE :		sc_ptr = (struct STATUS_CODE *) options_ptr -> opt_data;		safe_free (options_ptr);		options_ptr = sc_ptr -> opt;		safe_free (sc_ptr -> message);		safe_free (sc_ptr);		break;			    default :		options_ptr = 0;		break;	}    }        safe_free (dhcp_message);}/*     This function checks whether that particular option exists in the linked    list. It returns 1 on success and 0 on failure. */int check_for_option (int option, struct DHCP_MESSAGE *dhcp_msg_ptr){    struct OPTIONS * opt;    struct DUID * duid_ptr;    struct IA *ia_ptr;    struct IA_ADDRESS * iaaddr_ptr;    struct STATUS_CODE * status_ptr;    struct PREFERENCE * preference;        // Move to the first option node    opt= dhcp_msg_ptr->opt;        // Until there are no more options in the message    while (opt)    {	// If the required option is found then return 1	if (opt->u_opt_code.opt_code == option)	    return 1;		// Depending on the option code    	switch(opt->u_opt_code.opt_code)	{	    case OPTION_CLIENTID :	    case OPTION_SERVERID :		// Move to the next node		duid_ptr = (struct DUID *) opt -> opt_data;		opt = duid_ptr->opt;		break;			    case OPTION_IA : 		// Move to the next node		ia_ptr= (struct IA *) opt -> opt_data;		opt= ia_ptr->opt;		break;			    case OPTION_IAADDR :		// Move to the next node      	iaaddr_ptr=(struct IA_ADDRESS *) opt -> opt_data;		opt=iaaddr_ptr->opt;		break;			    case OPTION_STATUS_CODE :		// Move to the next node	      status_ptr=(struct STATUS_CODE *) opt -> opt_data;		opt=status_ptr->opt;		break;			    case OPTION_PREFERENCE :		// Move to the next node		preference = (struct PREFERENCE *) opt -> opt_data;		opt = preference -> opt;		break;		   default :		opt = 0;		break;	}	    }    return 0;}   int check_duid (int option, struct DHCP_MESSAGE *dhcp_msg_ptr, struct lease_details *lease_struct){    extern struct DUID * server_duid;    struct OPTIONS * opt;    struct DUID * duid_ptr;    struct DUID1 * server_duid1_ptr, * duid1_ptr;    struct DUID2 * server_duid2_ptr, * duid2_ptr;    struct DUID3 * server_duid3_ptr, * duid3_ptr;    struct IA *ia_ptr;    struct IA_ADDRESS * iaaddr_ptr;    struct STATUS_CODE * status_ptr;    struct PREFERENCE * preference;    u_int8_t * server_link_layer_address, * link_layer_address;    u_int8_t * server_identifier, * identifier;    char * server_domain_name, * domain_name;    // Move to the first option node    opt = dhcp_msg_ptr->opt;        // Until there are no more options in the message    while (opt)    {	switch(opt->u_opt_code.opt_code)	{	    case OPTION_CLIENTID :		if (option != OPTION_CLIENTID)		{		    // Move to the next node		    duid_ptr = (struct DUID *) opt -> opt_data;		    opt = duid_ptr->opt;		}		else if (check_for_duid_match (dhcp_msg_ptr, lease_struct))		    return 1;		else		    return 0;		break;			    case OPTION_SERVERID :		if (option != OPTION_SERVERID)		{		    // Move to the next node		    duid_ptr = (struct DUID *) opt -> opt_data;		    opt = duid_ptr->opt;

⌨️ 快捷键说明

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