X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=qemu%2Froms%2FSLOF%2Fclients%2Fnet-snk%2Fapp%2Fnetlib%2Fdhcp.c;h=7e2e88ccfaca996699f1521e0343a7f76201d071;hb=a14b48d18a9ed03ec191cf16b162206998a895ce;hp=5f26f3afb189c922009552c700a0bfb5728446ad;hpb=e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb;p=kvmfornfv.git diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c index 5f26f3afb..7e2e88ccf 100644 --- a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c +++ b/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c @@ -11,7 +11,7 @@ *****************************************************************************/ -/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ALGORITHMS <<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ +/******************************* ALGORITHMS ******************************/ /** \file dhcp.c
  * **************** State-transition diagram for DHCP client  *************
@@ -41,13 +41,14 @@
  * 
*/ -/*>>>>>>>>>>>>>>>>>>>>> DEFINITIONS & DECLARATIONS <<<<<<<<<<<<<<<<<<<<<<*/ +/********************** DEFINITIONS & DECLARATIONS ***********************/ #include #include #include #include #include +#include #include #include @@ -110,11 +111,11 @@ static uint8_t dhcp_magic[] = {0x63, 0x82, 0x53, 0x63}; * If flag[i] == TRUE then field for i-th option retains valid value and * information from this field may retrived (in case of receiving) or will * be transmitted (in case of transmitting). - * + * */ typedef struct { uint8_t flag[256]; /**< Show if corresponding opt. is valid */ - uint8_t request_list[256]; /**< o.55 If i-th member is TRUE, then i-th + uint8_t request_list[256]; /**< o.55 If i-th member is TRUE, then i-th option will be requested from server */ uint32_t server_ID; /**< o.54 Identifies DHCP-server */ uint32_t requested_IP; /**< o.50 Must be filled in DHCP-Request */ @@ -132,65 +133,57 @@ typedef struct { static uint8_t dhcp_state; -/*>>>>>>>>>>>>>>>>>>>>>>>>>>>> PROTOTYPES <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/ - -static int32_t -dhcp_attempt(int fd); +/***************************** PROTOTYPES ********************************/ -static int32_t -dhcp_encode_options(uint8_t * opt_field, dhcp_options_t * opt_struct); +static int32_t dhcp_attempt(int fd); -static int32_t -dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len, - dhcp_options_t * opt_struct); +static int32_t dhcp_encode_options(uint8_t * opt_field, dhcp_options_t * opt_struct); -static int8_t -dhcp_merge_options(uint8_t dst_options[], uint32_t * dst_len, - uint8_t src_options[], uint32_t src_len); +static int32_t dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len, + dhcp_options_t * opt_struct); -static int8_t -dhcp_find_option(uint8_t options[], uint32_t len, - uint8_t op_code, uint32_t * op_offset); - -static void -dhcp_append_option(uint8_t dst_options[], uint32_t * dst_len, - uint8_t * new_option); +static int8_t dhcp_merge_options(uint8_t dst_options[], uint32_t * dst_len, + uint8_t src_options[], uint32_t src_len); -static void -dhcp_combine_option(uint8_t dst_options[], uint32_t * dst_len, - uint32_t dst_offset, uint8_t * new_option); +static int8_t dhcp_find_option(uint8_t options[], uint32_t len, + uint8_t op_code, uint32_t * op_offset); -static void -dhcp_send_discover(int fd); +static void dhcp_append_option(uint8_t dst_options[], uint32_t * dst_len, + uint8_t * new_option); -static void -dhcp_send_request(int fd); +static void dhcp_combine_option(uint8_t dst_options[], uint32_t * dst_len, + uint32_t dst_offset, uint8_t * new_option); -static uint8_t -strtoip(int8_t * str, uint32_t * ip); +static void dhcp_send_discover(int fd); +static void dhcp_send_request(int fd); -/*>>>>>>>>>>>>>>>>>>>>>>>>>>>> LOCAL VARIABLES <<<<<<<<<<<<<<<<<<<<<<<<<<*/ +/***************************** LOCAL VARIABLES ***************************/ static uint8_t ether_packet[ETH_MTU_SIZE]; static uint32_t dhcp_own_ip = 0; static uint32_t dhcp_server_ip = 0; static uint32_t dhcp_siaddr_ip = 0; -static int8_t dhcp_filename[256]; -static int8_t dhcp_tftp_name[256]; +static char dhcp_filename[256]; +static char dhcp_tftp_name[256]; +static uint32_t dhcp_xid; static char * response_buffer; -/*>>>>>>>>>>>>>>>>>>>>>>>>>>>> IMPLEMENTATION <<<<<<<<<<<<<<<<<<<<<<<<<<<*/ +/***************************** IMPLEMENTATION ****************************/ -int32_t -dhcpv4(char *ret_buffer, filename_ip_t * fn_ip) { +void dhcpv4_generate_transaction_id(void) +{ + dhcp_xid = (rand() << 16) ^ rand(); +} +int32_t dhcpv4(char *ret_buffer, filename_ip_t *fn_ip) +{ uint32_t dhcp_tftp_ip = 0; int fd = fn_ip->fd; - strcpy((char *) dhcp_filename, ""); - strcpy((char *) dhcp_tftp_name, ""); + strcpy(dhcp_filename, ""); + strcpy(dhcp_tftp_name, ""); response_buffer = ret_buffer; @@ -204,11 +197,11 @@ dhcpv4(char *ret_buffer, filename_ip_t * fn_ip) { dhcp_siaddr_ip = fn_ip->server_ip; } if(fn_ip->filename[0] != 0) { - strcpy((char *) dhcp_filename, (char *) fn_ip->filename); + strcpy(dhcp_filename, (char *) fn_ip->filename); } // TFTP SERVER - if (!strlen((char *) dhcp_tftp_name)) { + if (!strlen(dhcp_tftp_name)) { if (!dhcp_siaddr_ip) { // ERROR: TFTP name is not presented return -3; @@ -219,9 +212,9 @@ dhcpv4(char *ret_buffer, filename_ip_t * fn_ip) { } else { // TFTP server defined by its name - if (!strtoip(dhcp_tftp_name, &(dhcp_tftp_ip))) { - if (!dns_get_ip(fd, dhcp_tftp_name, (uint8_t *)&(dhcp_tftp_ip), 4)) { - // DNS error - can't obtain TFTP-server name + if (!strtoip(dhcp_tftp_name, (char *)&dhcp_tftp_ip)) { + if (!dns_get_ip(fd, dhcp_tftp_name, (uint8_t *)&dhcp_tftp_ip, 4)) { + // DNS error - can't obtain TFTP-server name // Use TFTP-ip from siaddr field, if presented if (dhcp_siaddr_ip) { dhcp_tftp_ip = dhcp_siaddr_ip; @@ -237,7 +230,7 @@ dhcpv4(char *ret_buffer, filename_ip_t * fn_ip) { // Store configuration info into filename_ip strucutre fn_ip -> own_ip = dhcp_own_ip; fn_ip -> server_ip = dhcp_tftp_ip; - strcpy((char *) fn_ip -> filename, (char *) dhcp_filename); + strcpy((char *) fn_ip -> filename, dhcp_filename); return 0; } @@ -245,8 +238,8 @@ dhcpv4(char *ret_buffer, filename_ip_t * fn_ip) { /** * DHCP: Tries o obtain DHCP parameters, refer to state-transition diagram */ -static int32_t -dhcp_attempt(int fd) { +static int32_t dhcp_attempt(int fd) +{ int sec; // Send DISCOVER message and switch DHCP-client to SELECT state @@ -270,7 +263,7 @@ dhcp_attempt(int fd) { } while (get_timer() > 0); } - // timeout + // timeout return 0; } @@ -278,7 +271,7 @@ dhcp_attempt(int fd) { * DHCP: Supplements DHCP-message with options stored in structure. * For more information about option coding see dhcp_options_t. * - * @param opt_field Points to the "vend" field of DHCP-message + * @param opt_field Points to the "vend" field of DHCP-message * (destination) * @param opt_struct this structure stores info about the options which * will be added to DHCP-message (source) @@ -286,8 +279,8 @@ dhcp_attempt(int fd) { * FALSE - error condition occurs. * @see dhcp_options_t */ -static int32_t -dhcp_encode_options(uint8_t * opt_field, dhcp_options_t * opt_struct) { +static int32_t dhcp_encode_options(uint8_t * opt_field, dhcp_options_t * opt_struct) +{ uint8_t * options = opt_field; uint16_t i, sum; // used to define is any options set @@ -380,7 +373,7 @@ dhcp_encode_options(uint8_t * opt_field, dhcp_options_t * opt_struct) { * DHCP: Extracts encoded options from DHCP-message into the structure. * For more information about option coding see dhcp_options_t. * - * @param opt_field Points to the "options" field of DHCP-message + * @param opt_field Points to the "options" field of DHCP-message * (source). * @param opt_len Length of "options" field. * @param opt_struct this structure stores info about the options which @@ -389,10 +382,10 @@ dhcp_encode_options(uint8_t * opt_field, dhcp_options_t * opt_struct) { * FALSE - error condition occurs. * @see dhcp_options_t */ -static int32_t -dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len, - dhcp_options_t * opt_struct) { - int32_t offset = 0; +static int32_t dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len, + dhcp_options_t * opt_struct) +{ + uint32_t offset = 0; memset(opt_struct, 0, sizeof(dhcp_options_t)); @@ -407,30 +400,30 @@ dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len, switch(opt_field[offset]) { case DHCP_OVERLOAD : opt_struct -> overload = opt_field[offset + 2]; - offset += 2 + opt_field[offset + 1]; + offset += 2 + opt_field[offset + 1]; break; case DHCP_REQUESTED_IP : opt_struct -> requested_IP = htonl(* (uint32_t *) (opt_field + offset + 2)); - offset += 2 + opt_field[offset + 1]; + offset += 2 + opt_field[offset + 1]; break; case DHCP_MASK : opt_struct -> flag[DHCP_MASK] = 1; opt_struct -> subnet_mask = htonl(* (uint32_t *) (opt_field + offset + 2)); - offset += 2 + opt_field[offset + 1]; + offset += 2 + opt_field[offset + 1]; break; case DHCP_DNS : opt_struct -> flag[DHCP_DNS] = 1; opt_struct -> dns_IP = htonl(* (uint32_t *) (opt_field + offset + 2)); - offset += 2 + opt_field[offset + 1]; + offset += 2 + opt_field[offset + 1]; break; case DHCP_ROUTER : opt_struct -> flag[DHCP_ROUTER] = 1; opt_struct -> router_IP = htonl(* (uint32_t *) (opt_field + offset + 2)); - offset += 2 + opt_field[offset + 1]; + offset += 2 + opt_field[offset + 1]; break; case DHCP_MSG_TYPE : @@ -492,11 +485,12 @@ dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len, * FALSE - error condition occurs. */ static int8_t dhcp_merge_options(uint8_t dst_options[], uint32_t * dst_len, - uint8_t src_options[], uint32_t src_len) { - int32_t dst_offset, src_offset = 0; + uint8_t src_options[], uint32_t src_len) +{ + uint32_t dst_offset, src_offset = 0; // remove ENDOPT if presented - if (dhcp_find_option(dst_options, * dst_len, DHCP_ENDOPT, (uint32_t *) &dst_offset)) + if (dhcp_find_option(dst_options, * dst_len, DHCP_ENDOPT, &dst_offset)) * dst_len = dst_offset; while (src_offset < src_len) { @@ -509,7 +503,7 @@ static int8_t dhcp_merge_options(uint8_t dst_options[], uint32_t * dst_len, default: if (dhcp_find_option(dst_options, * dst_len, src_options[src_offset], - (uint32_t *) &dst_offset)) { + &dst_offset)) { dhcp_combine_option(dst_options, dst_len, dst_offset, (uint8_t *) src_options + @@ -522,7 +516,7 @@ static int8_t dhcp_merge_options(uint8_t dst_options[], uint32_t * dst_len, } } - if (src_offset == src_len) + if (src_offset == src_len) return 1; return 0; } @@ -540,7 +534,8 @@ static int8_t dhcp_merge_options(uint8_t dst_options[], uint32_t * dst_len, * FALSE - option wasn't find. */ static int8_t dhcp_find_option(uint8_t options[], uint32_t len, - uint8_t op_code, uint32_t * op_offset) { + uint8_t op_code, uint32_t * op_offset) +{ uint32_t srch_offset = 0; * op_offset = 0; @@ -568,9 +563,9 @@ static int8_t dhcp_find_option(uint8_t options[], uint32_t len, * @param dst_len length of the "options" field (modified) * @param new_option points to an option in another list (src) */ -static void -dhcp_append_option(uint8_t dst_options[], uint32_t * dst_len, - uint8_t * new_option) { +static void dhcp_append_option(uint8_t dst_options[], uint32_t * dst_len, + uint8_t * new_option) +{ memcpy(dst_options + ( * dst_len), new_option, 2 + (* (new_option + 1))); * dst_len += 2 + *(new_option + 1); } @@ -586,10 +581,9 @@ dhcp_append_option(uint8_t dst_options[], uint32_t * dst_len, * @param dst_offset offset of the option from beginning of the list * @param new_option points to an option in another list (src) */ -static void -dhcp_combine_option(uint8_t dst_options[], uint32_t * dst_len, - uint32_t dst_offset, uint8_t * new_option) { - +static void dhcp_combine_option(uint8_t dst_options[], uint32_t * dst_len, + uint32_t dst_offset, uint8_t * new_option) +{ uint8_t tmp_buffer[1024]; // use to provide safe memcpy uint32_t tail_len; @@ -612,8 +606,8 @@ dhcp_combine_option(uint8_t dst_options[], uint32_t * dst_len, /** * DHCP: Sends DHCP-Discover message. Looks for DHCP servers. */ -static void -dhcp_send_discover(int fd) { +static void dhcp_send_discover(int fd) +{ uint32_t packetsize = sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct btphdr); struct btphdr *btph; @@ -627,6 +621,7 @@ dhcp_send_discover(int fd) { btph -> op = 1; btph -> htype = 1; btph -> hlen = 6; + btph -> xid = dhcp_xid; memcpy(btph -> chaddr, get_mac_address(), 6); memset(&opt, 0, sizeof(dhcp_options_t)); @@ -655,8 +650,8 @@ dhcp_send_discover(int fd) { /** * DHCP: Sends DHCP-Request message. Asks for acknowledgment to occupy IP. */ -static void -dhcp_send_request(int fd) { +static void dhcp_send_request(int fd) +{ uint32_t packetsize = sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct btphdr); struct btphdr *btph; @@ -670,6 +665,7 @@ dhcp_send_request(int fd) { btph -> op = 1; btph -> htype = 1; btph -> hlen = 6; + btph -> xid = dhcp_xid; memcpy(btph -> chaddr, get_mac_address(), 6); memset(&opt, 0, sizeof(dhcp_options_t)); @@ -704,7 +700,8 @@ dhcp_send_request(int fd) { /** * DHCP: Sends DHCP-Release message. Releases occupied IP. */ -void dhcp_send_release(int fd) { +void dhcp_send_release(int fd) +{ uint32_t packetsize = sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct btphdr); struct btphdr *btph; @@ -718,6 +715,7 @@ void dhcp_send_release(int fd) { btph -> op = 1; btph -> htype = 1; btph -> hlen = 6; + btph -> xid = dhcp_xid; strcpy((char *) btph -> file, ""); memcpy(btph -> chaddr, get_mac_address(), 6); btph -> ciaddr = htonl(dhcp_own_ip); @@ -730,7 +728,7 @@ void dhcp_send_release(int fd) { dhcp_encode_options(btph -> vend, &opt); - fill_udphdr(ðer_packet[sizeof(struct iphdr)], + fill_udphdr(ðer_packet[sizeof(struct iphdr)], sizeof(struct btphdr) + sizeof(struct udphdr), UDPPORT_BOOTPC, UDPPORT_BOOTPS); fill_iphdr(ether_packet, sizeof(struct btphdr) + @@ -753,18 +751,21 @@ void dhcp_send_release(int fd) { * @see btphdr */ -int8_t -handle_dhcp(int fd, uint8_t * packet, int32_t packetsize) { +int8_t handle_dhcp(int fd, uint8_t * packet, int32_t packetsize) +{ struct btphdr * btph; struct iphdr * iph; dhcp_options_t opt; - memset(&opt, 0, sizeof(dhcp_options_t)); + memset(&opt, 0, sizeof(dhcp_options_t)); btph = (struct btphdr *) packet; iph = (struct iphdr *) packet - sizeof(struct udphdr) - sizeof(struct iphdr); - if (btph -> op != 2) - return -1; // it is not Boot Reply + + if (btph->op != 2) + return -1; /* It is not a Bootp/DHCP reply */ + if (btph->xid != dhcp_xid) + return -1; /* The transaction ID does not match */ if (memcmp(btph -> vend, dhcp_magic, 4)) { // It is BootP - RFC 951 @@ -788,7 +789,7 @@ handle_dhcp(int fd, uint8_t * packet, int32_t packetsize) { } - // decode options + // decode options if (!dhcp_decode_options(btph -> vend, packetsize - sizeof(struct btphdr) + sizeof(btph -> vend), &opt)) { @@ -902,7 +903,7 @@ handle_dhcp(int fd, uint8_t * packet, int32_t packetsize) { else { strcpy((char *) dhcp_filename, ""); if (opt.overload != DHCP_OVERLOAD_FILE && - opt.overload != DHCP_OVERLOAD_BOTH && + opt.overload != DHCP_OVERLOAD_BOTH && strlen((char *) btph -> file)) { strncpy((char *) dhcp_filename, (char *) btph->file, @@ -952,47 +953,3 @@ handle_dhcp(int fd, uint8_t * packet, int32_t packetsize) { return 0; } - -/** - * DHCP: Converts "255.255.255.255" -> 32-bit long IP - * - * @param str string to be converted - * @param ip in case of SUCCESS - 32-bit long IP - in case of FAULT - zero - * @return TRUE - IP converted successfully; - * FALSE - error condition occurs (e.g. bad format) - */ -static uint8_t -strtoip(int8_t * str, uint32_t * ip) { - int8_t ** ptr = &str; - int16_t i = 0, res, len; - char octet[256]; - - * ip = 0; - - while (**ptr != 0) { - if (i > 3 || !isdigit(**ptr)) - return 0; - if (strstr((char *) * ptr, ".") != NULL) { - len = (int16_t) ((int8_t *) strstr((char *) * ptr, ".") - - (int8_t *) (* ptr)); - strncpy(octet, (char *) * ptr, len); octet[len] = 0; - * ptr += len; - } - else { - strcpy(octet, (char *) * ptr); - * ptr += strlen(octet); - } - res = strtol(octet, NULL, 10); - if ((res > 255) || (res < 0)) - return 0; - * ip = ((* ip) << 8) + res; - i++; - if (** ptr == '.') - (*ptr)++; - } - - if (i != 4) - return 0; - return 1; -}