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