📄 lib.c
字号:
{ 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 + -