/*
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * dhcpcd_test.cpp - unit tests for dhcpcd
 */

#include <stdint.h>
#include <stdlib.h>
#include <string>

#include <gtest/gtest.h>

// For convenience.
#define ARRAYSIZE(x) sizeof((x)) / sizeof((x)[0])

// Regrettably, copy these defines and the dhcp_message structure in from
// dhcp.h.  This header file is not easily included, since subsequent
// includes use C++ reserved keywords (like "new") as structure member names.
extern "C" {

#define DHO_PAD                 0
#define DHO_DNSDOMAIN           15

/* Max MTU - defines dhcp option length */
#define MTU_MAX             1500

/* Sizes for DHCP options */
#define DHCP_CHADDR_LEN         16
#define SERVERNAME_LEN          64
#define BOOTFILE_LEN            128
#define DHCP_UDP_LEN            (14 + 20 + 8)
#define DHCP_FIXED_LEN          (DHCP_UDP_LEN + 226)
#define DHCP_OPTION_LEN         (MTU_MAX - DHCP_FIXED_LEN)

/* Some crappy DHCP servers require the BOOTP minimum length */
#define BOOTP_MESSAGE_LENTH_MIN 300

struct dhcp_message {
        uint8_t op;           /* message type */
        uint8_t hwtype;       /* hardware address type */
        uint8_t hwlen;        /* hardware address length */
        uint8_t hwopcount;    /* should be zero in client message */
        uint32_t xid;            /* transaction id */
        uint16_t secs;           /* elapsed time in sec. from boot */
        uint16_t flags;
        uint32_t ciaddr;         /* (previously allocated) client IP */
        uint32_t yiaddr;         /* 'your' client IP address */
        uint32_t siaddr;         /* should be zero in client's messages */
        uint32_t giaddr;         /* should be zero in client's messages */
        uint8_t chaddr[DHCP_CHADDR_LEN];  /* client's hardware address */
        uint8_t servername[SERVERNAME_LEN];    /* server host name */
        uint8_t bootfile[BOOTFILE_LEN];    /* boot file name */
        uint32_t cookie;
        uint8_t options[DHCP_OPTION_LEN]; /* message options - cookie */
} _packed;

char * get_option_string(const struct dhcp_message *dhcp, uint8_t option);

}


static const char kOptionString[] = "hostname";

class DhcpcdGetOptionTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    memset(dhcpmsgs, 0, ARRAYSIZE(dhcpmsgs) * sizeof(struct dhcp_message));
    // Technically redundant.
    memset(&(dhcpmsgs[0].options), DHO_PAD, sizeof(dhcpmsgs[0].options));

    type_index = 0;
    length_index = 0;
    value_index = 0;
  }

  void PopulateTLV() {
    // May very well write off the end of the first struct dhcp_message,
    // by design.
    length_index = type_index + 1;
    value_index = length_index + 1;
    dhcpmsgs[0].options[type_index] = DHO_DNSDOMAIN;
    dhcpmsgs[0].options[length_index] = strlen(kOptionString);
    memcpy(&(dhcpmsgs[0].options[value_index]),
           kOptionString, strlen(kOptionString));
  }

  struct dhcp_message dhcpmsgs[2];
  size_t type_index;
  size_t length_index;
  size_t value_index;
};

TEST_F(DhcpcdGetOptionTest, OptionNotPresent) {
  // An entire option block of padding (all zeros).
  EXPECT_EQ(NULL, ::get_option_string(&(dhcpmsgs[0]), DHO_DNSDOMAIN));
}

TEST_F(DhcpcdGetOptionTest, TypeIsOffTheEnd) {
  type_index = sizeof(dhcpmsgs[0].options);
  PopulateTLV();
  EXPECT_EQ(NULL, ::get_option_string(&(dhcpmsgs[0]), DHO_DNSDOMAIN));
}

TEST_F(DhcpcdGetOptionTest, LengthIsOffTheEnd) {
  type_index = sizeof(dhcpmsgs[0].options) - 1;
  PopulateTLV();
  EXPECT_EQ(NULL, ::get_option_string(&(dhcpmsgs[0]), DHO_DNSDOMAIN));
}

TEST_F(DhcpcdGetOptionTest, ValueIsOffTheEnd) {
  type_index = sizeof(dhcpmsgs[0].options) - 2;
  PopulateTLV();
  EXPECT_EQ(NULL, ::get_option_string(&(dhcpmsgs[0]), DHO_DNSDOMAIN));
}

TEST_F(DhcpcdGetOptionTest, InsufficientSpaceForValue) {
  type_index = sizeof(dhcpmsgs[0].options) - 6;
  PopulateTLV();
  char* value = ::get_option_string(&(dhcpmsgs[0]), DHO_DNSDOMAIN);
  EXPECT_TRUE(NULL != value);
  EXPECT_EQ("host", ::std::string(value));
  free(value);
}

TEST_F(DhcpcdGetOptionTest, InsufficientSpaceForContinuedValue) {
  type_index = sizeof(dhcpmsgs[0].options) - 16;
  PopulateTLV();
  type_index = sizeof(dhcpmsgs[0].options) - 6;
  PopulateTLV();
  char* value = ::get_option_string(&(dhcpmsgs[0]), DHO_DNSDOMAIN);
  EXPECT_TRUE(NULL != value);
  EXPECT_EQ("hostnamehost", ::std::string(value));
  free(value);
}
