📄 lib.c
字号:
} else { duid_ptr = (struct DUID *) opt -> opt_data; switch (server_duid -> u_duid_type.duid_type) { case 1 : if (duid_ptr -> u_duid_type.duid_type != 1) return 0; server_duid1_ptr = (struct DUID1 *) server_duid -> duid_type; duid1_ptr = (struct DUID1 *) duid_ptr -> duid_type; if (server_duid1_ptr -> u_haddr_type.haddr_type != duid1_ptr -> u_haddr_type.haddr_type) return 0; if (server_duid1_ptr -> u_time.time != duid1_ptr -> u_time.time) return 0; if (server_duid1_ptr -> haddr_len != duid1_ptr -> haddr_len) return 0; server_link_layer_address = server_duid1_ptr -> link_layer_address; link_layer_address = duid1_ptr -> link_layer_address; if (memcmp (server_link_layer_address, link_layer_address, duid1_ptr -> haddr_len)) return 0; break; case 2 : if (duid_ptr -> u_duid_type.duid_type != 2) return 0; server_duid2_ptr = (struct DUID2 *) server_duid -> duid_type; duid2_ptr = (struct DUID2 *) duid_ptr -> duid_type; if (server_duid2_ptr -> u_identifier_length.identifier_length != duid2_ptr -> u_identifier_length.identifier_length) return 0; server_identifier = server_duid2_ptr -> identifier; identifier = duid2_ptr -> identifier; if (memcmp (server_identifier, identifier, duid2_ptr -> u_identifier_length.identifier_length)) return 0; if (server_duid2_ptr -> domain_name_len != duid2_ptr -> domain_name_len) return 0; server_domain_name = server_duid2_ptr -> domain_name; domain_name = duid2_ptr -> domain_name; if (memcmp (server_domain_name, domain_name, duid2_ptr -> domain_name_len)) return 0; break; case 3 : if (duid_ptr -> u_duid_type.duid_type != 3) return 0; server_duid3_ptr = (struct DUID3 *) server_duid -> duid_type; duid3_ptr = (struct DUID3 *) duid_ptr -> duid_type; if (server_duid3_ptr -> u_haddr_type.haddr_type != duid3_ptr -> u_haddr_type.haddr_type) return 0; if (server_duid3_ptr -> haddr_len != duid3_ptr -> haddr_len) return 0; server_link_layer_address = server_duid3_ptr -> link_layer_address; link_layer_address = duid3_ptr -> link_layer_address; if (memcmp (server_link_layer_address, link_layer_address, duid3_ptr -> haddr_len)) return 0; break; } return 1; } 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;}/* This function checks the validity of the message being passed to it. It return 1 on success and 0 on failure.*/int check_message (struct DHCP_MESSAGE *dhcp_message_ptr, int recv_type){ extern struct lease_details *partial_lease, *lease; struct OPTIONS *options_ptr; extern int g_trans_id; // Check whether the received message is of the right type if (dhcp_message_ptr->u_msg_type.msg_type != recv_type) return 0; switch (dhcp_message_ptr->u_msg_type.msg_type) { // Check for validity of the solicit message case SOLICIT : if (!check_for_option (OPTION_CLIENTID, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_IA, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_IAADDR, dhcp_message_ptr)) return 0; break; case REQUEST : if (!check_for_option (OPTION_CLIENTID, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_SERVERID, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_IA, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_IAADDR, dhcp_message_ptr)) return 0; if (!check_duid (OPTION_SERVERID, dhcp_message_ptr, partial_lease)) return 0; if (!check_duid (OPTION_CLIENTID, dhcp_message_ptr, partial_lease)) return 0; if (!check_for_match (dhcp_message_ptr, partial_lease)) return 0; break; case RELEASE : case DECLINE : if (!check_for_option (OPTION_CLIENTID, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_SERVERID, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_IA, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_IAADDR, dhcp_message_ptr)) return 0; if (!check_duid (OPTION_SERVERID, dhcp_message_ptr, lease)) return 0; if (!check_duid (OPTION_CLIENTID, dhcp_message_ptr, lease)) return 0; if (!check_for_match (dhcp_message_ptr, lease)) return 0; break; case RENEW : if (!check_for_option (OPTION_CLIENTID, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_SERVERID, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_IA, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_IAADDR, dhcp_message_ptr)) return 0; break; case REBIND : if (!check_for_option (OPTION_CLIENTID, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_IA, dhcp_message_ptr)) return 0; if (!check_for_option (OPTION_IAADDR, dhcp_message_ptr)) return 0; break; } return 1;}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;}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_for_duplicate_packet (struct DHCP_MESSAGE *dhcp_message){ extern struct lease_details *partial_lease, *lease; switch (dhcp_message -> u_msg_type.msg_type) { case SOLICIT : if (!partial_lease) return 0; if (check_duid (OPTION_CLIENTID, dhcp_message, partial_lease)) if (check_duid (OPTION_SERVERID, dhcp_message, partial_lease)) if (check_for_match (dhcp_message, partial_lease)) return 1; break; case REQUEST : case RENEW : if (!lease) return 0; if (check_duid (OPTION_CLIENTID, dhcp_message, lease)) if (check_duid (OPTION_SERVERID, dhcp_message, lease)) if (check_for_match (dhcp_message, lease)) return 1; break; case REBIND : if (!lease) return 0; if (check_duid (OPTION_CLIENTID, dhcp_message, lease)) if (check_for_match (dhcp_message, lease)) return 1; break; case DECLINE : case RELEASE : if (!lease) return 0; if (check_duid (OPTION_CLIENTID, dhcp_message, lease)) if (check_duid (OPTION_SERVERID, dhcp_message, lease)) if (check_for_match (dhcp_message, lease)) return 0; // here, non existence of lease node indicates duplicate DECLINE packet return 1; } return 0;}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;}struct OPTIONS * send_server_id (struct OPTIONS * opt_ptr){ extern struct DUID *server_duid; struct DUID *duid_ptr; struct DUID1 *duid1_ptr; struct DUID2 *duid2_ptr; struct DUID3 *duid3_ptr; opt_ptr -> u_opt_code.opt_code = OPTION_SERVERID; opt_ptr -> opt_data = (struct DUID *) malloc (sizeof (struct DUID)); duid_ptr = (struct DUID *) opt_ptr -> opt_data; duid_ptr -> u_duid_type.duid_type = server_duid -> u_duid_type.duid_type; switch (duid_ptr -> u_duid_type.duid_type) { case 1 : duid_ptr -> duid_type = (struct DUID1 *) malloc (sizeof (struct DUID1)); duid1_ptr = (struct DUID1 *) duid_ptr -> duid_type; copy_duid1 ((struct DUID1 *) server_duid -> duid_type, duid1_ptr); // DUID type -> 2 octets // Time -> 4 octets // Hardware type -> 2 octets opt_ptr -> u_opt_len.opt_len = 2 + 4 + 2 + duid1_ptr -> haddr_len; break; case 2 : duid_ptr -> duid_type = (struct DUID2 *) malloc (sizeof (struct DUID2)); duid2_ptr = (struct DUID2 *) duid_ptr -> duid_type; copy_duid2 ((struct DUID2 *) server_duid -> duid_type, duid2_ptr); // DUID type -> 2 octets // Identifier length -> 2 octets opt_ptr -> u_opt_len.opt_len = 2 + 2 + duid2_ptr -> u_identifier_length.identifier_length + duid2_ptr -> domain_name_len; break; case 3 : duid_ptr -> duid_type = (struct DUID3 *) malloc (sizeof (struct DUID3)); duid3_ptr = (struct DUID3 *) duid_ptr -> duid_type; copy_duid3 ((struct DUID3 *) server_duid -> duid_type, duid3_ptr); // DUID type -> 2 octets // Hardware type -> 2 octets opt_ptr -> u_opt_len.opt_len = 2 + 2 + duid3_ptr -> haddr_len; break; } opt_ptr = duid_ptr -> opt = (struct OPTIONS *) malloc (sizeof (struct OPTIONS)); return opt_ptr;}struct DHCP_MESSAGE * create_message_with_status_code (struct DHCP_MESSAGE *message, int message_type, int status_code, char *status_message){ struct DHCP_MESSAGE *dhcp_message_ptr = (struct DHCP_MESSAGE *) malloc (sizeof (struct DHCP_MESSAGE)); struct OPTIONS *opt_ptr; struct STATUS_CODE *sc_ptr; int i; // MESSAGE TYPE dhcp_message_ptr->u_msg_type.msg_type = message_type; // Copy TRANSACTION ID from solicit message dhcp_message_ptr -> u_trans_id.trans_id = message -> u_trans_id.trans_id; // ASSIGN MEMORY FOR OPTIONS opt_ptr = dhcp_message_ptr->opt = (struct OPTIONS *) malloc (sizeof (struct OPTIONS)); sc_ptr = (struct STATUS_CODE *) malloc (sizeof (struct STATUS_CODE)); sc_ptr -> u_status_code.status_code = status_code; sc_ptr -> message = (char *) malloc (strlen (status_message) * sizeof (char)); for (i = 0; i < strlen (status_message); i++) sc_ptr -> message[i] = status_message[i]; sc_ptr -> opt = 0; opt_ptr -> u_opt_code.opt_code = OPTION_STATUS_CODE; // Status code = 2 octets opt_ptr -> u_opt_len.opt_len = strlen (status_message) + 2; opt_ptr -> opt_data = (struct STATUS_CODE *) sc_ptr; return dhcp_message_ptr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -