# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""
Tools for serializing and deserializing DHCP packets.

DhcpPacket is a class that represents a single DHCP packet and contains some
logic to create and parse binary strings containing on the wire DHCP packets.

While you could call the constructor explicitly, most users should use the
static factories to construct packets with reasonable default values in most of
the fields, even if those values are zeros.

For example:

packet = dhcp_packet.create_offer_packet(transaction_id,
                                         hwmac_addr,
                                         offer_ip,
                                         server_ip)
socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Sending to the broadcast address needs special permissions.
socket.sendto(response_packet.to_binary_string(),
              ("255.255.255.255", 68))

Note that if you make changes, make sure that the tests in the bottom of this
file still pass.
"""

import collections
import logging
import random
import socket
import struct


def CreatePacketPieceClass(super_class, field_format):
    class PacketPiece(super_class):
        @staticmethod
        def pack(value):
            return struct.pack(field_format, value)

        @staticmethod
        def unpack(byte_string):
            return struct.unpack(field_format, byte_string)[0]
    return PacketPiece

"""
Represents an option in a DHCP packet.  Options may or may not be present in any
given packet, depending on the configurations of the client and the server.
Using namedtuples as super classes gets us the comparison operators we want to
use these Options in dictionaries as keys.  Below, we'll subclass Option to
reflect that different kinds of options serialize to on the wire formats in
different ways.

|name|
A human readable name for this option.

|number|
Every DHCP option has a number that goes into the packet to indicate
which particular option is being encoded in the next few bytes.  This
property returns that number for each option.
"""
Option = collections.namedtuple("Option", ["name", "number"])

ByteOption = CreatePacketPieceClass(Option, "!B")

ShortOption = CreatePacketPieceClass(Option, "!H")

IntOption = CreatePacketPieceClass(Option, "!I")

class IpAddressOption(Option):
    @staticmethod
    def pack(value):
        return socket.inet_aton(value)

    @staticmethod
    def unpack(byte_string):
        return socket.inet_ntoa(byte_string)


class IpListOption(Option):
    @staticmethod
    def pack(value):
        return "".join([socket.inet_aton(addr) for addr in value])

    @staticmethod
    def unpack(byte_string):
        return [socket.inet_ntoa(byte_string[idx:idx+4])
                for idx in range(0, len(byte_string), 4)]


class RawOption(Option):
    @staticmethod
    def pack(value):
        return value

    @staticmethod
    def unpack(byte_string):
        return byte_string


class ByteListOption(Option):
    @staticmethod
    def pack(value):
        return "".join(chr(v) for v in value)

    @staticmethod
    def unpack(byte_string):
        return [ord(c) for c in byte_string]


class ClasslessStaticRoutesOption(Option):
    """
    This is a RFC 3442 compliant classless static route option parser and
    serializer.  The symbolic "value" packed and unpacked from this class
    is a list (prefix_size, destination, router) tuples.
    """

    @staticmethod
    def pack(value):
        route_list = value
        byte_string = ""
        for prefix_size, destination, router in route_list:
            byte_string += chr(prefix_size)
            # Encode only the significant octets of the destination
            # that fall within the prefix.
            destination_address_count = (prefix_size + 7) / 8
            destination_address = socket.inet_aton(destination)
            byte_string += destination_address[:destination_address_count]
            byte_string += socket.inet_aton(router)

        return byte_string

    @staticmethod
    def unpack(byte_string):
        route_list = []
        offset = 0
        while offset < len(byte_string):
            prefix_size = ord(byte_string[offset])
            destination_address_count = (prefix_size + 7) / 8
            entry_end = offset + 1 + destination_address_count + 4
            if entry_end > len(byte_string):
                raise Exception("Classless domain list is corrupted.")
            offset += 1
            destination_address_end = offset + destination_address_count
            destination_address = byte_string[offset:destination_address_end]
            # Pad the destination address bytes with zero byte octets to
            # fill out an IPv4 address.
            destination_address += '\x00' * (4 - destination_address_count)
            router_address = byte_string[destination_address_end:entry_end]
            route_list.append((prefix_size,
                               socket.inet_ntoa(destination_address),
                               socket.inet_ntoa(router_address)))
            offset = entry_end

        return route_list


class DomainListOption(Option):
    """
    This is a RFC 1035 compliant domain list option parser and serializer.
    There are some clever compression optimizations that it does not implement
    for serialization, but correctly parses.  This should be sufficient for
    testing.
    """
    # Various RFC's let you finish a domain name by pointing to an existing
    # domain name rather than repeating the same suffix.  All such pointers are
    # two bytes long, specify the offset in the byte string, and begin with
    # |POINTER_PREFIX| to distinguish them from normal characters.
    POINTER_PREFIX = ord("\xC0")

    @staticmethod
    def pack(value):
        domain_list = value
        byte_string = ""
        for domain in domain_list:
            for part in domain.split("."):
                byte_string += chr(len(part))
                byte_string += part
            byte_string += "\x00"
        return byte_string

    @staticmethod
    def unpack(byte_string):
        domain_list = []
        offset = 0
        try:
            while offset < len(byte_string):
                (new_offset, domain_parts) = DomainListOption._read_domain_name(
                        byte_string,
                        offset)
                domain_name = ".".join(domain_parts)
                domain_list.append(domain_name)
                if new_offset <= offset:
                    raise Exception("Parsing logic error is letting domain "
                                    "list parsing go on forever.")
                offset = new_offset
        except ValueError:
            # Badly formatted packets are not necessarily test errors.
            logging.warning("Found badly formatted DHCP domain search list")
            return None
        return domain_list

    @staticmethod
    def _read_domain_name(byte_string, offset):
        """
        Recursively parse a domain name from a domain name list.
        """
        parts = []
        while True:
            if offset >= len(byte_string):
                raise ValueError("Domain list ended without a NULL byte.")
            maybe_part_len = ord(byte_string[offset])
            offset += 1
            if maybe_part_len == 0:
                # Domains are terminated with either a 0 or a pointer to a
                # domain suffix within |byte_string|.
                return (offset, parts)
            elif ((maybe_part_len & DomainListOption.POINTER_PREFIX) ==
                  DomainListOption.POINTER_PREFIX):
                if offset >= len(byte_string):
                    raise ValueError("Missing second byte of domain suffix "
                                     "pointer.")
                maybe_part_len &= ~DomainListOption.POINTER_PREFIX
                pointer_offset = ((maybe_part_len << 8) +
                                  ord(byte_string[offset]))
                offset += 1
                (_, more_parts) = DomainListOption._read_domain_name(
                        byte_string,
                        pointer_offset)
                parts.extend(more_parts)
                return (offset, parts)
            else:
                # That byte was actually the length of the next part, not a
                # pointer back into the data.
                part_len = maybe_part_len
                if offset + part_len >= len(byte_string):
                    raise ValueError("Part of a domain goes beyond data "
                                     "length.")
                parts.append(byte_string[offset : offset + part_len])
                offset += part_len


"""
Represents a required field in a DHCP packet.  Similar to Option, we'll
subclass Field to reflect that different fields serialize to on the wire formats
in different ways.

|name|
A human readable name for this field.

|offset|
The |offset| for a field defines the starting byte of the field in the
binary packet string.  |offset| is used during parsing, along with
|size| to extract the byte string of a field.

|size|
Fields in DHCP packets have a fixed size that must be respected.  This
size property is used in parsing to indicate that |self._size| number of
bytes make up this field.
"""
Field = collections.namedtuple("Field", ["name", "offset", "size"])

ByteField = CreatePacketPieceClass(Field, "!B")

ShortField = CreatePacketPieceClass(Field, "!H")

IntField = CreatePacketPieceClass(Field, "!I")

HwAddrField = CreatePacketPieceClass(Field, "!16s")

ServerNameField = CreatePacketPieceClass(Field, "!64s")

BootFileField = CreatePacketPieceClass(Field, "!128s")

class IpAddressField(Field):
    @staticmethod
    def pack(value):
        return socket.inet_aton(value)

    @staticmethod
    def unpack(byte_string):
        return socket.inet_ntoa(byte_string)


# This is per RFC 2131.  The wording doesn't seem to say that the packets must
# be this big, but that has been the historic assumption in implementations.
DHCP_MIN_PACKET_SIZE = 300

IPV4_NULL_ADDRESS = "0.0.0.0"

# These are required in every DHCP packet.  Without these fields, the
# packet will not even pass DhcpPacket.is_valid
FIELD_OP = ByteField("op", 0, 1)
FIELD_HWTYPE = ByteField("htype", 1, 1)
FIELD_HWADDR_LEN = ByteField("hlen", 2, 1)
FIELD_RELAY_HOPS = ByteField("hops", 3, 1)
FIELD_TRANSACTION_ID = IntField("xid", 4, 4)
FIELD_TIME_SINCE_START = ShortField("secs", 8, 2)
FIELD_FLAGS = ShortField("flags", 10, 2)
FIELD_CLIENT_IP = IpAddressField("ciaddr", 12, 4)
FIELD_YOUR_IP = IpAddressField("yiaddr", 16, 4)
FIELD_SERVER_IP = IpAddressField("siaddr", 20, 4)
FIELD_GATEWAY_IP = IpAddressField("giaddr", 24, 4)
FIELD_CLIENT_HWADDR = HwAddrField("chaddr", 28, 16)
# The following two fields are considered "legacy BOOTP" fields but may
# sometimes be used by DHCP clients.
FIELD_LEGACY_SERVER_NAME = ServerNameField("servername", 44, 64);
FIELD_LEGACY_BOOT_FILE = BootFileField("bootfile", 108, 128);
FIELD_MAGIC_COOKIE = IntField("magic_cookie", 236, 4)

OPTION_TIME_OFFSET = IntOption("time_offset", 2)
OPTION_ROUTERS = IpListOption("routers", 3)
OPTION_SUBNET_MASK = IpAddressOption("subnet_mask", 1)
OPTION_TIME_SERVERS = IpListOption("time_servers", 4)
OPTION_NAME_SERVERS = IpListOption("name_servers", 5)
OPTION_DNS_SERVERS = IpListOption("dns_servers", 6)
OPTION_LOG_SERVERS = IpListOption("log_servers", 7)
OPTION_COOKIE_SERVERS = IpListOption("cookie_servers", 8)
OPTION_LPR_SERVERS = IpListOption("lpr_servers", 9)
OPTION_IMPRESS_SERVERS = IpListOption("impress_servers", 10)
OPTION_RESOURCE_LOC_SERVERS = IpListOption("resource_loc_servers", 11)
OPTION_HOST_NAME = RawOption("host_name", 12)
OPTION_BOOT_FILE_SIZE = ShortOption("boot_file_size", 13)
OPTION_MERIT_DUMP_FILE = RawOption("merit_dump_file", 14)
OPTION_DOMAIN_NAME = RawOption("domain_name", 15)
OPTION_SWAP_SERVER = IpAddressOption("swap_server", 16)
OPTION_ROOT_PATH = RawOption("root_path", 17)
OPTION_EXTENSIONS = RawOption("extensions", 18)
OPTION_VENDOR_ENCAPSULATED_OPTIONS = RawOption(
        "vendor_encapsulated_options", 43)
OPTION_REQUESTED_IP = IpAddressOption("requested_ip", 50)
OPTION_IP_LEASE_TIME = IntOption("ip_lease_time", 51)
OPTION_OPTION_OVERLOAD = ByteOption("option_overload", 52)
OPTION_DHCP_MESSAGE_TYPE = ByteOption("dhcp_message_type", 53)
OPTION_SERVER_ID = IpAddressOption("server_id", 54)
OPTION_PARAMETER_REQUEST_LIST = ByteListOption("parameter_request_list", 55)
OPTION_MESSAGE = RawOption("message", 56)
OPTION_MAX_DHCP_MESSAGE_SIZE = ShortOption("max_dhcp_message_size", 57)
OPTION_RENEWAL_T1_TIME_VALUE = IntOption("renewal_t1_time_value", 58)
OPTION_REBINDING_T2_TIME_VALUE = IntOption("rebinding_t2_time_value", 59)
OPTION_VENDOR_ID = RawOption("vendor_id", 60)
OPTION_CLIENT_ID = RawOption("client_id", 61)
OPTION_TFTP_SERVER_NAME = RawOption("tftp_server_name", 66)
OPTION_BOOTFILE_NAME = RawOption("bootfile_name", 67)
OPTION_DNS_DOMAIN_SEARCH_LIST = DomainListOption("domain_search_list", 119)
OPTION_CLASSLESS_STATIC_ROUTES = ClasslessStaticRoutesOption(
        "classless_static_routes", 121)
OPTION_WEB_PROXY_AUTO_DISCOVERY = RawOption("wpad", 252)

# Unlike every other option, which are tuples like:
# <number, length in bytes, data>, the pad and end options are just
# single bytes "\x00" and "\xff" (without length or data fields).
OPTION_PAD = 0
OPTION_END = 255

DHCP_COMMON_FIELDS = [
        FIELD_OP,
        FIELD_HWTYPE,
        FIELD_HWADDR_LEN,
        FIELD_RELAY_HOPS,
        FIELD_TRANSACTION_ID,
        FIELD_TIME_SINCE_START,
        FIELD_FLAGS,
        FIELD_CLIENT_IP,
        FIELD_YOUR_IP,
        FIELD_SERVER_IP,
        FIELD_GATEWAY_IP,
        FIELD_CLIENT_HWADDR,
        ]

DHCP_REQUIRED_FIELDS = DHCP_COMMON_FIELDS + [
        FIELD_MAGIC_COOKIE,
        ]

DHCP_ALL_FIELDS = DHCP_COMMON_FIELDS + [
        FIELD_LEGACY_SERVER_NAME,
        FIELD_LEGACY_BOOT_FILE,
        FIELD_MAGIC_COOKIE,
        ]

# The op field in an ipv4 packet is either 1 or 2 depending on
# whether the packet is from a server or from a client.
FIELD_VALUE_OP_CLIENT_REQUEST = 1
FIELD_VALUE_OP_SERVER_RESPONSE = 2
# 1 == 10mb ethernet hardware address type (aka MAC).
FIELD_VALUE_HWTYPE_10MB_ETH = 1
# MAC addresses are still 6 bytes long.
FIELD_VALUE_HWADDR_LEN_10MB_ETH = 6
FIELD_VALUE_MAGIC_COOKIE = 0x63825363

OPTIONS_START_OFFSET = 240
# From RFC2132, the valid DHCP message types are:
OPTION_VALUE_DHCP_MESSAGE_TYPE_DISCOVERY = 1
OPTION_VALUE_DHCP_MESSAGE_TYPE_OFFER     = 2
OPTION_VALUE_DHCP_MESSAGE_TYPE_REQUEST   = 3
OPTION_VALUE_DHCP_MESSAGE_TYPE_DECLINE   = 4
OPTION_VALUE_DHCP_MESSAGE_TYPE_ACK       = 5
OPTION_VALUE_DHCP_MESSAGE_TYPE_NAK       = 6
OPTION_VALUE_DHCP_MESSAGE_TYPE_RELEASE   = 7
OPTION_VALUE_DHCP_MESSAGE_TYPE_INFORM    = 8
OPTION_VALUE_DHCP_MESSAGE_TYPE_UNKNOWN   = -1

OPTION_VALUE_PARAMETER_REQUEST_LIST_DEFAULT = [
        OPTION_REQUESTED_IP.number,
        OPTION_IP_LEASE_TIME.number,
        OPTION_SERVER_ID.number,
        OPTION_SUBNET_MASK.number,
        OPTION_ROUTERS.number,
        OPTION_DNS_SERVERS.number,
        OPTION_HOST_NAME.number,
        ]

# These are possible options that may not be in every packet.
# Frequently, the client can include a bunch of options that indicate
# that it would like to receive information about time servers, routers,
# lpr servers, and much more, but the DHCP server can usually ignore
# those requests.
#
# Eventually, each option is encoded as:
#     <option.number, option.size, [array of option.size bytes]>
# Unlike fields, which make up a fixed packet format, options can be in
# any order, except where they cannot.  For instance, option 1 must
# follow option 3 if both are supplied.  For this reason, potential
# options are in this list, and added to the packet in this order every
# time.
#
# size < 0 indicates that this is variable length field of at least
# abs(length) bytes in size.
DHCP_PACKET_OPTIONS = [
        OPTION_TIME_OFFSET,
        OPTION_ROUTERS,
        OPTION_SUBNET_MASK,
        OPTION_TIME_SERVERS,
        OPTION_NAME_SERVERS,
        OPTION_DNS_SERVERS,
        OPTION_LOG_SERVERS,
        OPTION_COOKIE_SERVERS,
        OPTION_LPR_SERVERS,
        OPTION_IMPRESS_SERVERS,
        OPTION_RESOURCE_LOC_SERVERS,
        OPTION_HOST_NAME,
        OPTION_BOOT_FILE_SIZE,
        OPTION_MERIT_DUMP_FILE,
        OPTION_SWAP_SERVER,
        OPTION_DOMAIN_NAME,
        OPTION_ROOT_PATH,
        OPTION_EXTENSIONS,
        OPTION_VENDOR_ENCAPSULATED_OPTIONS,
        OPTION_REQUESTED_IP,
        OPTION_IP_LEASE_TIME,
        OPTION_OPTION_OVERLOAD,
        OPTION_DHCP_MESSAGE_TYPE,
        OPTION_SERVER_ID,
        OPTION_PARAMETER_REQUEST_LIST,
        OPTION_MESSAGE,
        OPTION_MAX_DHCP_MESSAGE_SIZE,
        OPTION_RENEWAL_T1_TIME_VALUE,
        OPTION_REBINDING_T2_TIME_VALUE,
        OPTION_VENDOR_ID,
        OPTION_CLIENT_ID,
        OPTION_TFTP_SERVER_NAME,
        OPTION_BOOTFILE_NAME,
        OPTION_DNS_DOMAIN_SEARCH_LIST,
        OPTION_CLASSLESS_STATIC_ROUTES,
        OPTION_WEB_PROXY_AUTO_DISCOVERY,
        ]

def get_dhcp_option_by_number(number):
    for option in DHCP_PACKET_OPTIONS:
        if option.number == number:
            return option
    return None

class DhcpPacket(object):
    @staticmethod
    def create_discovery_packet(hwmac_addr):
        """
        Create a discovery packet.

        Fill in fields of a DHCP packet as if it were being sent from
        |hwmac_addr|.  Requests subnet masks, broadcast addresses, router
        addresses, dns addresses, domain search lists, client host name, and NTP
        server addresses.  Note that the offer packet received in response to
        this packet will probably not contain all of that information.
        """
        # MAC addresses are actually only 6 bytes long, however, for whatever
        # reason, DHCP allocated 12 bytes to this field.  Ease the burden on
        # developers and hide this detail.
        while len(hwmac_addr) < 12:
            hwmac_addr += chr(OPTION_PAD)

        packet = DhcpPacket()
        packet.set_field(FIELD_OP, FIELD_VALUE_OP_CLIENT_REQUEST)
        packet.set_field(FIELD_HWTYPE, FIELD_VALUE_HWTYPE_10MB_ETH)
        packet.set_field(FIELD_HWADDR_LEN, FIELD_VALUE_HWADDR_LEN_10MB_ETH)
        packet.set_field(FIELD_RELAY_HOPS, 0)
        packet.set_field(FIELD_TRANSACTION_ID, random.getrandbits(32))
        packet.set_field(FIELD_TIME_SINCE_START, 0)
        packet.set_field(FIELD_FLAGS, 0)
        packet.set_field(FIELD_CLIENT_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_YOUR_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_SERVER_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_GATEWAY_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_CLIENT_HWADDR, hwmac_addr)
        packet.set_field(FIELD_MAGIC_COOKIE, FIELD_VALUE_MAGIC_COOKIE)
        packet.set_option(OPTION_DHCP_MESSAGE_TYPE,
                          OPTION_VALUE_DHCP_MESSAGE_TYPE_DISCOVERY)
        return packet

    @staticmethod
    def create_offer_packet(transaction_id,
                            hwmac_addr,
                            offer_ip,
                            server_ip):
        """
        Create an offer packet, given some fields that tie the packet to a
        particular offer.
        """
        packet = DhcpPacket()
        packet.set_field(FIELD_OP, FIELD_VALUE_OP_SERVER_RESPONSE)
        packet.set_field(FIELD_HWTYPE, FIELD_VALUE_HWTYPE_10MB_ETH)
        packet.set_field(FIELD_HWADDR_LEN, FIELD_VALUE_HWADDR_LEN_10MB_ETH)
        # This has something to do with relay agents
        packet.set_field(FIELD_RELAY_HOPS, 0)
        packet.set_field(FIELD_TRANSACTION_ID, transaction_id)
        packet.set_field(FIELD_TIME_SINCE_START, 0)
        packet.set_field(FIELD_FLAGS, 0)
        packet.set_field(FIELD_CLIENT_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_YOUR_IP, offer_ip)
        packet.set_field(FIELD_SERVER_IP, server_ip)
        packet.set_field(FIELD_GATEWAY_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_CLIENT_HWADDR, hwmac_addr)
        packet.set_field(FIELD_MAGIC_COOKIE, FIELD_VALUE_MAGIC_COOKIE)
        packet.set_option(OPTION_DHCP_MESSAGE_TYPE,
                          OPTION_VALUE_DHCP_MESSAGE_TYPE_OFFER)
        return packet

    @staticmethod
    def create_request_packet(transaction_id,
                              hwmac_addr):
        packet = DhcpPacket()
        packet.set_field(FIELD_OP, FIELD_VALUE_OP_CLIENT_REQUEST)
        packet.set_field(FIELD_HWTYPE, FIELD_VALUE_HWTYPE_10MB_ETH)
        packet.set_field(FIELD_HWADDR_LEN, FIELD_VALUE_HWADDR_LEN_10MB_ETH)
        # This has something to do with relay agents
        packet.set_field(FIELD_RELAY_HOPS, 0)
        packet.set_field(FIELD_TRANSACTION_ID, transaction_id)
        packet.set_field(FIELD_TIME_SINCE_START, 0)
        packet.set_field(FIELD_FLAGS, 0)
        packet.set_field(FIELD_CLIENT_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_YOUR_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_SERVER_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_GATEWAY_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_CLIENT_HWADDR, hwmac_addr)
        packet.set_field(FIELD_MAGIC_COOKIE, FIELD_VALUE_MAGIC_COOKIE)
        packet.set_option(OPTION_DHCP_MESSAGE_TYPE,
                          OPTION_VALUE_DHCP_MESSAGE_TYPE_REQUEST)
        return packet

    @staticmethod
    def create_acknowledgement_packet(transaction_id,
                                      hwmac_addr,
                                      granted_ip,
                                      server_ip):
        packet = DhcpPacket()
        packet.set_field(FIELD_OP, FIELD_VALUE_OP_SERVER_RESPONSE)
        packet.set_field(FIELD_HWTYPE, FIELD_VALUE_HWTYPE_10MB_ETH)
        packet.set_field(FIELD_HWADDR_LEN, FIELD_VALUE_HWADDR_LEN_10MB_ETH)
        # This has something to do with relay agents
        packet.set_field(FIELD_RELAY_HOPS, 0)
        packet.set_field(FIELD_TRANSACTION_ID, transaction_id)
        packet.set_field(FIELD_TIME_SINCE_START, 0)
        packet.set_field(FIELD_FLAGS, 0)
        packet.set_field(FIELD_CLIENT_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_YOUR_IP, granted_ip)
        packet.set_field(FIELD_SERVER_IP, server_ip)
        packet.set_field(FIELD_GATEWAY_IP, IPV4_NULL_ADDRESS)
        packet.set_field(FIELD_CLIENT_HWADDR, hwmac_addr)
        packet.set_field(FIELD_MAGIC_COOKIE, FIELD_VALUE_MAGIC_COOKIE)
        packet.set_option(OPTION_DHCP_MESSAGE_TYPE,
                          OPTION_VALUE_DHCP_MESSAGE_TYPE_ACK)
        return packet

    def __init__(self, byte_str=None):
        """
        Create a DhcpPacket, filling in fields from a byte string if given.

        Assumes that the packet starts at offset 0 in the binary string.  This
        includes the fields and options.  Fields are different from options in
        that we bother to decode these into more usable data types like
        integers rather than keeping them as raw byte strings.  Fields are also
        required to exist, unlike options which may not.

        Each option is encoded as a tuple <option number, length, data> where
        option number is a byte indicating the type of option, length indicates
        the number of bytes in the data for option, and data is a length array
        of bytes.  The only exceptions to this rule are the 0 and 255 options,
        which have 0 data length, and no length byte.  These tuples are then
        simply appended to each other.  This encoding is the same as the BOOTP
        vendor extention field encoding.
        """
        super(DhcpPacket, self).__init__()
        self._options = {}
        self._fields = {}
        if byte_str is None:
            return
        if len(byte_str) < OPTIONS_START_OFFSET + 1:
            logging.error("Invalid byte string for packet.")
            return
        for field in DHCP_ALL_FIELDS:
            self._fields[field] = field.unpack(byte_str[field.offset :
                                                        field.offset +
                                                        field.size])
        offset = OPTIONS_START_OFFSET
        domain_search_list_byte_string = ""
        while offset < len(byte_str) and ord(byte_str[offset]) != OPTION_END:
            data_type = ord(byte_str[offset])
            offset += 1
            if data_type == OPTION_PAD:
                continue
            data_length = ord(byte_str[offset])
            offset += 1
            data = byte_str[offset: offset + data_length]
            offset += data_length
            option = get_dhcp_option_by_number(data_type)
            if option is None:
                logging.warning("Unsupported DHCP option found.  "
                                "Option number: %d" % data_type)
                continue
            if option == OPTION_DNS_DOMAIN_SEARCH_LIST:
                # In a cruel twist of fate, the server is allowed to give
                # multiple options with this number.  The client is expected to
                # concatenate the byte strings together and use it as a single
                # value.
                domain_search_list_byte_string += data
                continue
            option_value = option.unpack(data)
            if option == OPTION_PARAMETER_REQUEST_LIST:
                logging.info("Requested options: %s" % str(option_value))
            self._options[option] = option_value
        if domain_search_list_byte_string:
            self._options[OPTION_DNS_DOMAIN_SEARCH_LIST] = option_value


    @property
    def client_hw_address(self):
        return self._fields.get(FIELD_CLIENT_HWADDR)

    @property
    def is_valid(self):
        """
        Checks that we have (at a minimum) values for all the required fields,
        and that the magic cookie is set correctly.
        """
        for field in DHCP_REQUIRED_FIELDS:
            if self._fields.get(field) is None:
                logging.warning("Missing field %s in packet." % field)
                return False
        if self._fields[FIELD_MAGIC_COOKIE] != FIELD_VALUE_MAGIC_COOKIE:
            return False
        return True

    @property
    def message_type(self):
        return self._options.get(OPTION_DHCP_MESSAGE_TYPE,
                                 OPTION_VALUE_DHCP_MESSAGE_TYPE_UNKNOWN)

    @property
    def transaction_id(self):
        return self._fields.get(FIELD_TRANSACTION_ID)

    def get_field(self, field):
        return self._fields.get(field)

    def get_option(self, option):
        return self._options.get(option)

    def set_field(self, field, field_value):
        self._fields[field] = field_value

    def set_option(self, option, option_value):
        self._options[option] = option_value

    def to_binary_string(self):
        if not self.is_valid:
            return None
        # A list of byte strings to be joined into a single string at the end.
        data = []
        offset = 0
        for field in DHCP_ALL_FIELDS:
            if field not in self._fields:
                continue
            field_data = field.pack(self._fields[field])
            while offset < field.offset:
                # This should only happen when we're padding the fields because
                # we're not filling in legacy BOOTP stuff.
                data.append("\x00")
                offset += 1
            data.append(field_data)
            offset += field.size
        # Last field processed is the magic cookie, so we're ready for options.
        # Have to process options
        for option in DHCP_PACKET_OPTIONS:
            option_value = self._options.get(option)
            if option_value is None:
                continue
            serialized_value = option.pack(option_value)
            data.append(struct.pack("BB",
                                    option.number,
                                    len(serialized_value)))
            offset += 2
            data.append(serialized_value)
            offset += len(serialized_value)
        data.append(chr(OPTION_END))
        offset += 1
        while offset < DHCP_MIN_PACKET_SIZE:
            data.append(chr(OPTION_PAD))
            offset += 1
        return "".join(data)

    def __str__(self):
        options = [k.name + "=" + str(v) for k, v in self._options.items()]
        fields = [k.name + "=" + str(v) for k, v in self._fields.items()]
        return "<DhcpPacket fields=%s, options=%s>" % (fields, options)
