summaryrefslogtreecommitdiffstats
path: root/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c
diff options
context:
space:
mode:
authorRajithaY <rajithax.yerrumsetty@intel.com>2017-04-25 03:31:15 -0700
committerRajitha Yerrumchetty <rajithax.yerrumsetty@intel.com>2017-05-22 06:48:08 +0000
commitbb756eebdac6fd24e8919e2c43f7d2c8c4091f59 (patch)
treeca11e03542edf2d8f631efeca5e1626d211107e3 /qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c
parenta14b48d18a9ed03ec191cf16b162206998a895ce (diff)
Adding qemu as a submodule of KVMFORNFV
This Patch includes the changes to add qemu as a submodule to kvmfornfv repo and make use of the updated latest qemu for the execution of all testcase Change-Id: I1280af507a857675c7f81d30c95255635667bdd7 Signed-off-by:RajithaY<rajithax.yerrumsetty@intel.com>
Diffstat (limited to 'qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c')
-rw-r--r--qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c955
1 files changed, 0 insertions, 955 deletions
diff --git a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c b/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c
deleted file mode 100644
index 7e2e88ccf..000000000
--- a/qemu/roms/SLOF/clients/net-snk/app/netlib/dhcp.c
+++ /dev/null
@@ -1,955 +0,0 @@
-/******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation
- * All rights reserved.
- * This program and the accompanying materials
- * are made available under the terms of the BSD License
- * which accompanies this distribution, and is available at
- * http://www.opensource.org/licenses/bsd-license.php
- *
- * Contributors:
- * IBM Corporation - initial implementation
- *****************************************************************************/
-
-
-/******************************* ALGORITHMS ******************************/
-
-/** \file dhcp.c <pre>
- * **************** State-transition diagram for DHCP client *************
- *
- * +---------+ Note: DHCP-server msg / DHCP-client msg
- * | INIT |
- * +---------+
- * |
- * | - / Discover
- * V
- * +---------+
- * | SELECT | Timeout
- * +---------+ |
- * | |
- * | Offer / Request |
- * | |
- * V V
- * +---------+ NACK / - ***********
- * | REQUEST | ----------------> * FAULT *
- * +---------+ ***********
- * |
- * | ACK / - ***********
- * +----------------------> * SUCCESS *
- * ***********
- *
- * ************************************************************************
- * </pre> */
-
-
-/********************** DEFINITIONS & DECLARATIONS ***********************/
-
-#include <dhcp.h>
-#include <ethernet.h>
-#include <ipv4.h>
-#include <udp.h>
-#include <dns.h>
-#include <netapps/args.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#include <sys/socket.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-/* DHCP Message Types */
-#define DHCPDISCOVER 1
-#define DHCPOFFER 2
-#define DHCPREQUEST 3
-#define DHCPDECLINE 4
-#define DHCPACK 5
-#define DHCPNACK 6
-#define DHCPRELEASE 7
-#define DHCPINFORM 8
-
-/* DHCP Option Codes */
-#define DHCP_MASK 1
-#define DHCP_ROUTER 3
-#define DHCP_DNS 6
-#define DHCP_REQUESTED_IP 50
-#define DHCP_OVERLOAD 52
-#define DHCP_MSG_TYPE 53
-#define DHCP_SERVER_ID 54
-#define DHCP_REQUEST_LIST 55
-#define DHCP_TFTP_SERVER 66
-#define DHCP_BOOTFILE 67
-#define DHCP_CLIENT_ARCH 93
-#define DHCP_ENDOPT 0xFF
-#define DHCP_PADOPT 0x00
-
-/* "file/sname" overload option values */
-#define DHCP_OVERLOAD_FILE 1
-#define DHCP_OVERLOAD_SNAME 2
-#define DHCP_OVERLOAD_BOTH 3
-
-/* DHCP states codes */
-#define DHCP_STATE_SELECT 1
-#define DHCP_STATE_REQUEST 2
-#define DHCP_STATE_SUCCESS 3
-#define DHCP_STATE_FAULT 4
-
-/* DHCP Client Architecture */
-#ifndef DHCPARCH
-#define USE_DHCPARCH 0
-#define DHCPARCH 0
-#else
-#define USE_DHCPARCH 1
-#endif
-
-static uint8_t dhcp_magic[] = {0x63, 0x82, 0x53, 0x63};
-/**< DHCP_magic is a cookie, that identifies DHCP options (see RFC 2132) */
-
-/** \struct dhcp_options_t
- * This structure is used to fill options in DHCP-msg during transmitting
- * or to retrieve options from DHCP-msg during receiving.
- * <p>
- * 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
- 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 */
- uint32_t dns_IP; /**< o. 6 DNS IP */
- uint32_t router_IP; /**< o. 3 Router IP */
- uint32_t subnet_mask; /**< o. 1 Subnet mask */
- uint8_t msg_type; /**< o.53 DHCP-message type */
- uint8_t overload; /**< o.52 Overload sname/file fields */
- int8_t tftp_server[256]; /**< o.66 TFTP server name */
- int8_t bootfile[256]; /**< o.67 Boot file name */
- uint16_t client_arch; /**< o.93 Client architecture type */
-} dhcp_options_t;
-
-/** Stores state of DHCP-client (refer to State-transition diagram) */
-static uint8_t dhcp_state;
-
-
-/***************************** PROTOTYPES ********************************/
-
-static int32_t dhcp_attempt(int fd);
-
-static int32_t dhcp_encode_options(uint8_t * opt_field, dhcp_options_t * opt_struct);
-
-static int32_t dhcp_decode_options(uint8_t opt_field[], uint32_t opt_len,
- 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 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 void dhcp_combine_option(uint8_t dst_options[], uint32_t * dst_len,
- uint32_t dst_offset, uint8_t * new_option);
-
-static void dhcp_send_discover(int fd);
-
-static void dhcp_send_request(int fd);
-
-/***************************** 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 char dhcp_filename[256];
-static char dhcp_tftp_name[256];
-static uint32_t dhcp_xid;
-
-static char * response_buffer;
-
-/***************************** IMPLEMENTATION ****************************/
-
-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(dhcp_filename, "");
- strcpy(dhcp_tftp_name, "");
-
- response_buffer = ret_buffer;
-
- if (dhcp_attempt(fd) == 0)
- return -1;
-
- if (fn_ip->own_ip) {
- dhcp_own_ip = fn_ip->own_ip;
- }
- if (fn_ip->server_ip) {
- dhcp_siaddr_ip = fn_ip->server_ip;
- }
- if(fn_ip->filename[0] != 0) {
- strcpy(dhcp_filename, (char *) fn_ip->filename);
- }
-
- // TFTP SERVER
- if (!strlen(dhcp_tftp_name)) {
- if (!dhcp_siaddr_ip) {
- // ERROR: TFTP name is not presented
- return -3;
- }
-
- // take TFTP-ip from siaddr field
- dhcp_tftp_ip = dhcp_siaddr_ip;
- }
- else {
- // TFTP server defined by its 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;
- }
- else {
- // ERROR: Can't obtain TFTP server IP
- return -4;
- }
- }
- }
- }
-
- // 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, dhcp_filename);
-
- return 0;
-}
-
-/**
- * DHCP: Tries o obtain DHCP parameters, refer to state-transition diagram
- */
-static int32_t dhcp_attempt(int fd)
-{
- int sec;
-
- // Send DISCOVER message and switch DHCP-client to SELECT state
- dhcp_send_discover(fd);
-
- dhcp_state = DHCP_STATE_SELECT;
-
- // setting up a timer with a timeout of two seconds
- for (sec = 0; sec < 2; sec++) {
- set_timer(TICKS_SEC);
- do {
- receive_ether(fd);
-
- // Wait until client will switch to Final state or Timeout occurs
- switch (dhcp_state) {
- case DHCP_STATE_SUCCESS :
- return 1;
- case DHCP_STATE_FAULT :
- return 0;
- }
- } while (get_timer() > 0);
- }
-
- // timeout
- return 0;
-}
-
-/**
- * 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
- * (destination)
- * @param opt_struct this structure stores info about the options which
- * will be added to DHCP-message (source)
- * @return TRUE - options packed;
- * FALSE - error condition occurs.
- * @see dhcp_options_t
- */
-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
-
- // magic
- memcpy(options, dhcp_magic, 4);
- options += 4;
-
- // fill message type
- switch (opt_struct -> msg_type) {
- case DHCPDISCOVER :
- case DHCPREQUEST :
- case DHCPDECLINE :
- case DHCPINFORM :
- case DHCPRELEASE :
- options[0] = DHCP_MSG_TYPE;
- options[1] = 1;
- options[2] = opt_struct -> msg_type;
- options += 3;
- break;
- default :
- return 0; // Unsupported DHCP-message
- }
-
- if (opt_struct -> overload) {
- options[0] = DHCP_OVERLOAD;
- options[1] = 0x01;
- options[2] = opt_struct -> overload;
- options +=3;
- }
-
- if (opt_struct -> flag[DHCP_REQUESTED_IP]) {
- options[0] = DHCP_REQUESTED_IP;
- options[1] = 0x04;
- * (uint32_t *) (options + 2) = htonl (opt_struct -> requested_IP);
- options +=6;
- }
-
- if (opt_struct -> flag[DHCP_SERVER_ID]) {
- options[0] = DHCP_SERVER_ID;
- options[1] = 0x04;
- * (uint32_t *) (options + 2) = htonl (opt_struct -> server_ID);
- options +=6;
- }
-
- sum = 0;
- for (i = 0; i < 256; i++)
- sum += opt_struct -> request_list[i];
-
- if (sum) {
- options[0] = DHCP_REQUEST_LIST;
- options[1] = sum;
- options += 2;
- for (i = 0; i < 256; i++) {
- if (opt_struct -> request_list[i]) {
- options[0] = i; options++;
- }
- }
- }
-
- if (opt_struct -> flag[DHCP_TFTP_SERVER]) {
- options[0] = DHCP_TFTP_SERVER;
- options[1] = strlen((char *) opt_struct -> tftp_server) + 1;
- memcpy(options + 2, opt_struct -> tftp_server, options[1]);
- options += options[1] + 2;
- }
-
- if (opt_struct -> flag[DHCP_BOOTFILE]) {
- options[0] = DHCP_BOOTFILE;
- options[1] = strlen((char *) opt_struct -> bootfile) + 1;
- memcpy(options + 2, opt_struct -> bootfile, options[1]);
- options += options[1] + 2;
- }
-
- if (opt_struct -> flag[DHCP_CLIENT_ARCH]) {
- options[0] = DHCP_CLIENT_ARCH;
- options[1] = 2;
- options[2] = (DHCPARCH >> 8);
- options[3] = DHCPARCH & 0xff;
- options += 4;
- }
-
- // end options
- options[0] = 0xFF;
- options++;
-
- return 1;
-}
-
-/**
- * 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
- * (source).
- * @param opt_len Length of "options" field.
- * @param opt_struct this structure stores info about the options which
- * was extracted from DHCP-message (destination).
- * @return TRUE - options extracted;
- * 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)
-{
- uint32_t offset = 0;
-
- memset(opt_struct, 0, sizeof(dhcp_options_t));
-
- // magic
- if (memcmp(opt_field, dhcp_magic, 4)) {
- return 0;
- }
-
- offset += 4;
- while (offset < opt_len) {
- opt_struct -> flag[opt_field[offset]] = 1;
- switch(opt_field[offset]) {
- case DHCP_OVERLOAD :
- opt_struct -> overload = opt_field[offset + 2];
- 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];
- 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];
- 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];
- 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];
- break;
-
- case DHCP_MSG_TYPE :
- if ((opt_field[offset + 2] > 0) && (opt_field[offset + 2] < 9))
- opt_struct -> msg_type = opt_field[offset + 2];
- else
- return 0;
- offset += 2 + opt_field[offset + 1];
- break;
-
- case DHCP_SERVER_ID :
- opt_struct -> server_ID = htonl(* (uint32_t *) (opt_field + offset + 2));
- offset += 2 + opt_field[offset + 1];
- break;
-
- case DHCP_TFTP_SERVER :
- memcpy(opt_struct -> tftp_server, opt_field + offset + 2, opt_field[offset + 1]);
- (opt_struct -> tftp_server)[opt_field[offset + 1]] = 0;
- offset += 2 + opt_field[offset + 1];
- break;
-
- case DHCP_BOOTFILE :
- memcpy(opt_struct -> bootfile, opt_field + offset + 2, opt_field[offset + 1]);
- (opt_struct -> bootfile)[opt_field[offset + 1]] = 0;
- offset += 2 + opt_field[offset + 1];
- break;
-
- case DHCP_CLIENT_ARCH :
- opt_struct -> client_arch = ((opt_field[offset + 2] << 8) & 0xFF00) | (opt_field[offset + 3] & 0xFF);
- offset += 4;
- break;
-
- case DHCP_PADOPT :
- offset++;
- break;
-
- case DHCP_ENDOPT : // End of options
- return 1;
-
- default :
- offset += 2 + opt_field[offset + 1]; // Unsupported opt. - do nothing
- }
- }
- if (offset == opt_len)
- return 1; // options finished without 0xFF
-
- return 0;
-}
-
-/**
- * DHCP: Appends information from source "options" into dest "options".
- * This function is used to support "file/sname" overloading.
- *
- * @param dst_options destanation "options" field
- * @param dst_len size of dst_options (modified by this function)
- * @param src_options source "options" field
- * @param src_len size of src_options
- * @return TRUE - options merged;
- * 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)
-{
- uint32_t dst_offset, src_offset = 0;
-
- // remove ENDOPT if presented
- if (dhcp_find_option(dst_options, * dst_len, DHCP_ENDOPT, &dst_offset))
- * dst_len = dst_offset;
-
- while (src_offset < src_len) {
- switch(src_options[src_offset]) {
- case DHCP_PADOPT:
- src_offset++;
- break;
- case DHCP_ENDOPT:
- return 1;
- default:
- if (dhcp_find_option(dst_options, * dst_len,
- src_options[src_offset],
- &dst_offset)) {
- dhcp_combine_option(dst_options, dst_len,
- dst_offset,
- (uint8_t *) src_options +
- src_offset);
- }
- else {
- dhcp_append_option(dst_options, dst_len, src_options + src_offset);
- }
- src_offset += 2 + src_options[src_offset + 1];
- }
- }
-
- if (src_offset == src_len)
- return 1;
- return 0;
-}
-
-/**
- * DHCP: Finds given occurrence of the option with the given code (op_code)
- * in "options" field of DHCP-message.
- *
- * @param options "options" field of DHCP-message
- * @param len length of the "options" field
- * @param op_code code of the option to find
- * @param op_offset SUCCESS - offset to an option occurrence;
- * FAULT - offset is set to zero.
- * @return TRUE - option was find;
- * 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)
-{
- uint32_t srch_offset = 0;
- * op_offset = 0;
-
- while (srch_offset < len) {
- if (options[srch_offset] == op_code) {
- * op_offset = srch_offset;
- return 1;
- }
- if (options[srch_offset] == DHCP_ENDOPT)
- return 0;
-
- if (options[srch_offset] == DHCP_PADOPT)
- srch_offset++;
- else
- srch_offset += 2 + options[srch_offset + 1];
- }
- return 0;
-}
-
-/**
- * DHCP: Appends new option from one list (src) into the tail
- * of another option list (dst)
- *
- * @param dst_options "options" field of DHCP-message
- * @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)
-{
- memcpy(dst_options + ( * dst_len), new_option, 2 + (* (new_option + 1)));
- * dst_len += 2 + *(new_option + 1);
-}
-
-/**
- * DHCP: This function is used when options with the same code are
- * presented in both merged lists. In this case information
- * about the option from one list (src) is combined (complemented)
- * with information about the option in another list (dst).
- *
- * @param dst_options "options" field of DHCP-message
- * @param dst_len length of the "options" field (modified)
- * @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)
-{
- uint8_t tmp_buffer[1024]; // use to provide safe memcpy
- uint32_t tail_len;
-
- // move all subsequent options (allocate size for additional info)
- tail_len = (* dst_len) - dst_offset - 2 - dst_options[dst_offset + 1];
-
- memcpy(tmp_buffer, dst_options + (* dst_len) - tail_len, tail_len);
- memcpy(dst_options + (* dst_len) - tail_len + (* (new_option + 1)),
- tmp_buffer, tail_len);
-
- // add new_content to option
- memcpy(dst_options + (* dst_len) - tail_len, new_option + 2,
- * (new_option + 1));
- dst_options[dst_offset + 1] += * (new_option + 1);
-
- // correct dst_len
- * dst_len += * (new_option + 1);
-}
-
-/**
- * DHCP: Sends DHCP-Discover message. Looks for DHCP servers.
- */
-static void dhcp_send_discover(int fd)
-{
- uint32_t packetsize = sizeof(struct iphdr) +
- sizeof(struct udphdr) + sizeof(struct btphdr);
- struct btphdr *btph;
- dhcp_options_t opt;
-
- memset(ether_packet, 0, packetsize);
-
- btph = (struct btphdr *) (&ether_packet[
- sizeof(struct iphdr) + sizeof(struct udphdr)]);
-
- 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));
-
- opt.msg_type = DHCPDISCOVER;
-
- opt.request_list[DHCP_MASK] = 1;
- opt.request_list[DHCP_DNS] = 1;
- opt.request_list[DHCP_ROUTER] = 1;
- opt.request_list[DHCP_TFTP_SERVER] = 1;
- opt.request_list[DHCP_BOOTFILE] = 1;
- opt.request_list[DHCP_CLIENT_ARCH] = USE_DHCPARCH;
-
- dhcp_encode_options(btph -> vend, &opt);
-
- fill_udphdr(&ether_packet[sizeof(struct iphdr)],
- sizeof(struct btphdr) + sizeof(struct udphdr),
- UDPPORT_BOOTPC, UDPPORT_BOOTPS);
- fill_iphdr(ether_packet, sizeof(struct btphdr) +
- sizeof(struct udphdr) + sizeof(struct iphdr),
- IPTYPE_UDP, dhcp_own_ip, 0xFFFFFFFF);
-
- send_ipv4(fd, ether_packet, packetsize);
-}
-
-/**
- * DHCP: Sends DHCP-Request message. Asks for acknowledgment to occupy IP.
- */
-static void dhcp_send_request(int fd)
-{
- uint32_t packetsize = sizeof(struct iphdr) +
- sizeof(struct udphdr) + sizeof(struct btphdr);
- struct btphdr *btph;
- dhcp_options_t opt;
-
- memset(ether_packet, 0, packetsize);
-
- btph = (struct btphdr *) (&ether_packet[
- sizeof(struct iphdr) + sizeof(struct udphdr)]);
-
- 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));
-
- opt.msg_type = DHCPREQUEST;
- memcpy(&(opt.requested_IP), &dhcp_own_ip, 4);
- opt.flag[DHCP_REQUESTED_IP] = 1;
- memcpy(&(opt.server_ID), &dhcp_server_ip, 4);
- opt.flag[DHCP_SERVER_ID] = 1;
-
- opt.request_list[DHCP_MASK] = 1;
- opt.request_list[DHCP_DNS] = 1;
- opt.request_list[DHCP_ROUTER] = 1;
- opt.request_list[DHCP_TFTP_SERVER] = 1;
- opt.request_list[DHCP_BOOTFILE] = 1;
- opt.request_list[DHCP_CLIENT_ARCH] = USE_DHCPARCH;
- opt.flag[DHCP_CLIENT_ARCH] = USE_DHCPARCH;
-
- dhcp_encode_options(btph -> vend, &opt);
-
- fill_udphdr(&ether_packet[sizeof(struct iphdr)],
- sizeof(struct btphdr) + sizeof(struct udphdr),
- UDPPORT_BOOTPC, UDPPORT_BOOTPS);
- fill_iphdr(ether_packet, sizeof(struct btphdr) +
- sizeof(struct udphdr) + sizeof(struct iphdr),
- IPTYPE_UDP, 0, 0xFFFFFFFF);
-
- send_ipv4(fd, ether_packet, packetsize);
-}
-
-
-/**
- * DHCP: Sends DHCP-Release message. Releases occupied IP.
- */
-void dhcp_send_release(int fd)
-{
- uint32_t packetsize = sizeof(struct iphdr) +
- sizeof(struct udphdr) + sizeof(struct btphdr);
- struct btphdr *btph;
- dhcp_options_t opt;
-
- btph = (struct btphdr *) (&ether_packet[
- sizeof(struct iphdr) + sizeof(struct udphdr)]);
-
- memset(ether_packet, 0, packetsize);
-
- 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);
-
- memset(&opt, 0, sizeof(dhcp_options_t));
-
- opt.msg_type = DHCPRELEASE;
- opt.server_ID = dhcp_server_ip;
- opt.flag[DHCP_SERVER_ID] = 1;
-
- dhcp_encode_options(btph -> vend, &opt);
-
- fill_udphdr(&ether_packet[sizeof(struct iphdr)],
- sizeof(struct btphdr) + sizeof(struct udphdr),
- UDPPORT_BOOTPC, UDPPORT_BOOTPS);
- fill_iphdr(ether_packet, sizeof(struct btphdr) +
- sizeof(struct udphdr) + sizeof(struct iphdr), IPTYPE_UDP,
- dhcp_own_ip, dhcp_server_ip);
-
- send_ipv4(fd, ether_packet, packetsize);
-}
-
-/**
- * DHCP: Handles DHCP-messages according to Receive-handle diagram.
- * Changes the state of DHCP-client.
- *
- * @param fd socket descriptor
- * @param packet BootP/DHCP-packet to be handled
- * @param packetsize length of the packet
- * @return ZERO - packet handled successfully;
- * NON ZERO - packet was not handled (e.g. bad format)
- * @see receive_ether
- * @see btphdr
- */
-
-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));
- btph = (struct btphdr *) packet;
- iph = (struct iphdr *) packet - sizeof(struct udphdr) -
- sizeof(struct iphdr);
-
- 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
- dhcp_own_ip = htonl(btph -> yiaddr);
- dhcp_siaddr_ip = htonl(btph -> siaddr);
- dhcp_server_ip = htonl(iph -> ip_src);
-
- if (strlen((char *) btph -> sname) && !dhcp_siaddr_ip) {
- strncpy((char *) dhcp_tftp_name, (char *) btph -> sname,
- sizeof(btph -> sname));
- dhcp_tftp_name[sizeof(btph -> sname)] = 0;
- }
-
- if (strlen((char *) btph -> file)) {
- strncpy((char *) dhcp_filename, (char *) btph -> file, sizeof(btph -> file));
- dhcp_filename[sizeof(btph -> file)] = 0;
- }
-
- dhcp_state = DHCP_STATE_SUCCESS;
- return 0;
- }
-
-
- // decode options
- if (!dhcp_decode_options(btph -> vend, packetsize -
- sizeof(struct btphdr) + sizeof(btph -> vend),
- &opt)) {
- return -1; // can't decode options
- }
-
- if (opt.overload) {
- int16_t decode_res = 0;
- uint8_t options[1024]; // buffer for merged options
- uint32_t opt_len;
-
- // move 1-st part of options from vend field into buffer
- opt_len = packetsize - sizeof(struct btphdr) +
- sizeof(btph -> vend) - 4;
- memcpy(options, btph -> vend, opt_len + 4);
-
- // add other parts
- switch (opt.overload) {
- case DHCP_OVERLOAD_FILE:
- decode_res = dhcp_merge_options(options + 4, &opt_len,
- btph -> file,
- sizeof(btph -> file));
- break;
- case DHCP_OVERLOAD_SNAME:
- decode_res = dhcp_merge_options(options + 4, &opt_len,
- btph -> sname,
- sizeof(btph -> sname));
- break;
- case DHCP_OVERLOAD_BOTH:
- decode_res = dhcp_merge_options(options + 4, &opt_len,
- btph -> file,
- sizeof(btph -> file));
- if (!decode_res)
- break;
- decode_res = dhcp_merge_options(options + 4, &opt_len,
- btph -> sname,
- sizeof(btph -> sname));
- break;
- }
-
- if (!decode_res)
- return -1; // bad options in sname/file fields
-
- // decode merged options
- if (!dhcp_decode_options(options, opt_len + 4, &opt)) {
- return -1; // can't decode options
- }
- }
-
- if (!opt.msg_type) {
- // It is BootP with Extensions - RFC 1497
- // retrieve conf. settings from BootP - reply
- dhcp_own_ip = htonl(btph -> yiaddr);
- dhcp_siaddr_ip = htonl(btph -> siaddr);
- if (strlen((char *) btph -> sname) && !dhcp_siaddr_ip) {
- strncpy((char *) dhcp_tftp_name, (char *) btph -> sname, sizeof(btph -> sname));
- dhcp_tftp_name[sizeof(btph -> sname)] = 0;
- }
-
- if (strlen((char *) btph -> file)) {
- strncpy((char *) dhcp_filename, (char *) btph -> file, sizeof(btph -> file));
- dhcp_filename[sizeof(btph -> file)] = 0;
- }
-
- // retrieve DHCP-server IP from IP-header
- dhcp_server_ip = iph -> htonl(ip_src);
-
- dhcp_state = DHCP_STATE_SUCCESS;
- }
- else {
- // It is DHCP - RFC 2131 & RFC 2132
- // opt contains parameters from server
- switch (dhcp_state) {
- case DHCP_STATE_SELECT :
- if (opt.msg_type == DHCPOFFER) {
- dhcp_own_ip = htonl(btph -> yiaddr);
- dhcp_server_ip = opt.server_ID;
- dhcp_send_request(fd);
- dhcp_state = DHCP_STATE_REQUEST;
- }
- return 0;
- case DHCP_STATE_REQUEST :
- switch (opt.msg_type) {
- case DHCPNACK :
- dhcp_own_ip = 0;
- dhcp_server_ip = 0;
- dhcp_state = DHCP_STATE_FAULT;
- break;
- case DHCPACK :
- dhcp_own_ip = htonl(btph -> yiaddr);
- dhcp_server_ip = opt.server_ID;
- dhcp_siaddr_ip = htonl(btph -> siaddr);
- if (opt.flag[DHCP_TFTP_SERVER]) {
- strcpy((char *) dhcp_tftp_name, (char *) opt.tftp_server);
- }
- else {
- strcpy((char *) dhcp_tftp_name, "");
- if ((opt.overload != DHCP_OVERLOAD_SNAME &&
- opt.overload != DHCP_OVERLOAD_BOTH) &&
- !dhcp_siaddr_ip) {
- strncpy((char *) dhcp_tftp_name,
- (char *) btph->sname,
- sizeof(btph -> sname));
- dhcp_tftp_name[sizeof(btph->sname)] = 0;
- }
- }
-
- if (opt.flag[DHCP_BOOTFILE]) {
- strcpy((char *) dhcp_filename, (char *) opt.bootfile);
- }
- else {
- strcpy((char *) dhcp_filename, "");
- if (opt.overload != DHCP_OVERLOAD_FILE &&
- opt.overload != DHCP_OVERLOAD_BOTH &&
- strlen((char *) btph -> file)) {
- strncpy((char *) dhcp_filename,
- (char *) btph->file,
- sizeof(btph->file));
- dhcp_filename[sizeof(btph -> file)] = 0;
- }
- }
-
- dhcp_state = DHCP_STATE_SUCCESS;
- break;
- default:
- break; // Unused DHCP-message - do nothing
- }
- break;
- default :
- return -1; // Illegal DHCP-client state
- }
- }
-
- if (dhcp_state == DHCP_STATE_SUCCESS) {
-
- // initialize network entity with real own_ip
- // to be able to answer for foreign requests
- set_ipv4_address(dhcp_own_ip);
-
- if(response_buffer) {
- if(packetsize <= 1720)
- memcpy(response_buffer, packet, packetsize);
- else
- memcpy(response_buffer, packet, 1720);
- }
-
- /* Subnet mask */
- if (opt.flag[DHCP_MASK]) {
- /* Router */
- if (opt.flag[DHCP_ROUTER]) {
- set_ipv4_router(opt.router_IP);
- set_ipv4_netmask(opt.subnet_mask);
- }
- }
-
- /* DNS-server */
- if (opt.flag[DHCP_DNS]) {
- dns_init(opt.dns_IP, 0, 4);
- }
- }
-
- return 0;
-}