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

📄 client.c

📁 关于Linux下DHCP支持IPv6的版本实现
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "stdhead.h"#include "solicit.h"#include "clilib.h"#include "parse.h"#include "request.h"#include "decline.h"#include "renew.h"#include "rebind.h"#include "release.h"// Indicates the state of the clientint g_state;// Stores the transaction idu_int32_t g_trans_id = 0;// Socket structure variablestruct sockaddr_in6 sa, ca;// File descriptor for the event log fileint event_log_fd;socklen_t sl;int sfd, cfd;struct DHCP_MESSAGE * reply_for_request = 0;struct DUID * server_duid_ptr;// Signal handler function for alarm signalvoid sig_alarm_init_delay (int signo){    printf ("\nAlarm occured. Time to transmit for the first time\n");}    // Signal handler function for Interrupt signalvoid quit (int signo){    exit (0);}void intialize_event_logging (){    if ((event_log_fd = open (DEFAULT_EVENT_LOG_FILE, O_CREAT | O_APPEND | O_RDWR, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) == -1)   {	printf ("\nFailed to open event log file %s. Check permissions.\n", DEFAULT_EVENT_LOG_FILE);	exit (0);    }}int intialize_client (char *interface_name){    int on = if_nametoindex (interface_name);    signal (SIGINT, quit);         g_state = INIT;    write_to_log ("Moving into INIT state", 1);       // Create sending socket   sfd = socket (PF_INET6, SOCK_DGRAM, 0);   if (sfd == -1)	return 0;    // Initialize sending socket using macro   INITIALIZE_SOCKADDR (sa);     // Set the destination port to 547    sa.sin6_port = htons (AGENT_PORT);   // Set destination address to ff02::1:2   inet_pton (AF_INET6, ALL_DHCP_AGENTS, &sa.sin6_addr);   // Allow multicast on the sending socket    if (setsockopt (sfd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &on, sizeof (on)) == -1)	return 0;         cfd = socket (PF_INET6, SOCK_DGRAM, 0);   if (cfd == -1)	return 0;    // Initialize the client socket    INITIALIZE_SOCKADDR (ca);       // Set the client socket to 546 port    ca.sin6_port = htons (CLIENT_PORT);    // Bind the client socket    bind (cfd, (struct sockaddr *) &ca, sizeof (ca));    // Allow multicast on eth0     if (setsockopt (cfd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &on, sizeof (on)) == -1)        return 0;        return 1;}struct DHCP_MESSAGE ** solicitize (char *interface_name, int * adv_msg_count){    struct DHCP_MESSAGE ** advertise;    struct DHCP_MESSAGE * dhcp_message_ptr;    char buff[MIN_MESSAGE_SIZE];    int n, init_delay, i;          // Create the solicit message   dhcp_message_ptr = create_solicit_message (interface_name);   write_to_log ("Solicit message constructed.", 1);   // Print the contents of the solicit message   print_linked_list_contents (dhcp_message_ptr);   // Convert the solicit message into a array   n = store_in_buffer (dhcp_message_ptr, buff);   // CALCULATE THE INITIAL DELAY   init_delay = calculate_initial_delay ();   printf ("\nThe initial delay is %d\n", init_delay);    // SET THE SIGNAL FOR INITIAL DELAY    signal (SIGALRM, sig_alarm_init_delay);    alarm (init_delay);    pause ();        // Send the solicit message to the server    sendto (sfd, buff, n, 0, (struct sockaddr *) &sa, sl);        // Set the client state to selecting    g_state = SELECTING;    write_to_log ("Solicit message has been sent for the first time.", 1);    write_to_log ("Moving into selecting state.", 1);            // Receive the advertise message    write_to_log ("Waiting for ADVERTISE message.", 1);    advertise = wait_until_response (sfd, cfd, SOL_IRT, SOL_MAX_RT, SOL_MRC, SOLICIT, ADVERTISE, buff, n, adv_msg_count);    // If no advertise message are received then exit    if (!advertise)    {	printf ("No server found.\n");	write_to_log ("No ADVERTISE message found. Bye Bye.", 1);	exit (1);    }    else    {      write_to_log ("I got ADVERTISEMENTS", 1);	// Print all advertise messages	printf ("\n\n Printing Advertise messages.\n");	for (i = 0; i < * adv_msg_count; i++)	{	    printf ("\n\n Advertise message number %d.\n", i+1);	    print_linked_list_contents (advertise[i]);	}    }    write_to_log ("\n\n\n--------------------------------------------------\n\n\n", 0);    return advertise;}struct DHCP_MESSAGE * requesting (char * interface_name, struct DHCP_MESSAGE ** server_advertise, int * adv_msg_count){    struct DHCP_MESSAGE * best_server_advertise, * client_request;    struct DHCP_MESSAGE ** server_reply;    char buff[MIN_MESSAGE_SIZE];    int n, msg_count;    // Select the best server advertise message    while (best_server_advertise = select_server (server_advertise, * adv_msg_count, interface_name))    {	write_to_log ("Best ADVERTISE message has been found.", 1);    	// Set the client state to Requesting	g_state = REQUESTING;	write_to_log ("Moving into the REQUESTING state", 1);	// Create and print the Request message	printf ("\n\n Printing Request message.\n");	client_request = create_request_message (best_server_advertise, interface_name);	write_to_log ("REQUEST message has been constructed.", 1);	print_linked_list_contents (client_request);	// Convert the Request message into an array	n = store_in_buffer (client_request, buff);	// Multicast the Request message	sendto (sfd, buff, n, 0, (struct sockaddr *) &sa, sl);	write_to_log ("REQUEST message has been sent.", 1);	// Wait for server reply	write_to_log ("Waiting for REPLY (for REQUEST) message from server.", 1);	server_reply = wait_until_response (sfd, cfd, REQ_IRT, REQ_MRT, REQ_MRC, REQUEST, REPLY, buff, n, &msg_count);		if (!server_reply)	{	    write_to_log ("No REPLY (for REQUEST) message from server. Searching for the next best ADVERTISE message ...", 1);	    server_reply = purge_message (server_advertise, best_server_advertise, adv_msg_count);	    continue;	}	else	{	    // Assuming that i have got back a valid REPLY message from the server	    print_linked_list_contents (* server_reply);	    write_to_log ("REPLY (for REQUEST) message received from server.", 1);	    break;	}    }    write_to_log ("\n\n\n---------------------------------------------------\n\n\n", 0);    if (server_reply)        return * server_reply;    else	return 0;}struct DHCP_MESSAGE * decline_server (char * interface_name, struct DHCP_MESSAGE * server_reply){    struct DHCP_MESSAGE ** server_decline_reply;    struct DHCP_MESSAGE * dhcp_message_ptr;    char buff[MIN_MESSAGE_SIZE];    int n, msg_count;    // send decline message    dhcp_message_ptr = create_decline_message (server_reply, interface_name);    n = store_in_buffer (dhcp_message_ptr, buff);    sendto (sfd, buff, n, 0, (struct sockaddr *) &sa, sl);    write_to_log ("DECLINE message has been sent.", 1);    write_to_log ("Waiting for REPLY (for DECLINE) message from server.", 1);    server_decline_reply = wait_until_response (sfd, cfd, DEC_IRT, DEC_MRT, DEC_MRC, DECLINE, REPLY, buff, n, &msg_count);        if (!server_decline_reply)        write_to_log ("No REPLY (for DECLINE) message from server. Abandoning attempts ...", 1);    else    {        if (check_message (*server_decline_reply, REPLY, DECLINE))        {	    print_linked_list_contents (*server_decline_reply);    	    write_to_log ("REPLY (for DECLINE) message received from server.", 1);        }    }    write_to_log ("\n\n\n------------------------------------------------------\n\n\n", 0);        if (server_decline_reply)        return * server_decline_reply;    else	return 0;}void bind_and_count (char * interface_name , struct DHCP_MESSAGE * server_reply, int * allow_for_renewal){    struct timeval timeout;    u_int32_t renewal_timer, rebind_timer, valid_lifetime_timer;            get_timers (server_reply, &renewal_timer, &rebind_timer, &valid_lifetime_timer);        printf ("The valid lifetime is %d\n", valid_lifetime_timer);    printf ("The renewal time is %d\n", renewal_timer);    printf ("The rebind time is %d\n", rebind_timer);    if (valid_lifetime_timer > renewal_timer)    {	   timeout.tv_sec = renewal_timer;   	   write_to_log ("Setting renewal timer ....", 1);	   printf ("Setting renewal timer ....\n");	   * allow_for_renewal = 1;    }    else    {        timeout.tv_sec = valid_lifetime_timer;        write_to_log ("Setting Valid lifetime timer ....", 1);	  printf ("Setting Valid lifetime timer ....\n");	  * allow_for_renewal = 0;    }    timeout.tv_usec = 0;    select (0, 0, 0, 0, &timeout);}struct DHCP_MESSAGE * renew_lease (char * interface_name, struct DHCP_MESSAGE * server_reply){	    struct DHCP_MESSAGE ** server_renew_reply;    struct DHCP_MESSAGE * dhcp_message_ptr;    char buff[MIN_MESSAGE_SIZE];    int n, msg_count;        dhcp_message_ptr = create_renew_message (server_reply, interface_name);    write_to_log ("Renew message constructed.", 1);    print_linked_list_contents (dhcp_message_ptr);    n = store_in_buffer (dhcp_message_ptr, buff);    write_to_log ("Sending Renew message ...", 1);    sendto (sfd, buff, n, 0, (struct sockaddr *) &sa, sl);    write_to_log ("Waiting for REPLY (for RENEW) message ...", 1);    server_renew_reply = wait_until_response (sfd, cfd, REN_IRT, REN_MRT, REN_MRC, RENEW, REPLY, buff, n, &msg_count);    write_to_log ("\n\n\n------------------------------------------------------\n\n\n", 0);    if (server_renew_reply)    {	write_to_log ("Reply (for Renew) message received from server.", 1);	return * server_renew_reply;    }    else    {	write_to_log ("No Reply (for Renew) message received from server.", 1);	return 0;    }}

⌨️ 快捷键说明

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