1d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* 2d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * dhcpcd - DHCP client daemon 3d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * Copyright (c) 2006-2015 Roy Marples <roy@marples.name> 4d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * All rights reserved 5d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 6d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * Redistribution and use in source and binary forms, with or without 7d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * modification, are permitted provided that the following conditions 8d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * are met: 9d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * 1. Redistributions of source code must retain the above copyright 10d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * notice, this list of conditions and the following disclaimer. 11d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * 2. Redistributions in binary form must reproduce the above copyright 12d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * notice, this list of conditions and the following disclaimer in the 13d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * documentation and/or other materials provided with the distribution. 14d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * 15d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * SUCH DAMAGE. 26d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan */ 27d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 28d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#ifndef DHCP_H 29d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_H 30d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 31d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#include <arpa/inet.h> 32d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#include <netinet/in.h> 33d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 34d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#include <limits.h> 35d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#include <stdint.h> 36d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 37d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#include "arp.h" 38d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#include "auth.h" 39d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#include "dhcp-common.h" 40d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 41d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* UDP port numbers for DHCP */ 42d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_SERVER_PORT 67 43d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_CLIENT_PORT 68 44d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 45d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define MAGIC_COOKIE 0x63825363 46d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define BROADCAST_FLAG 0x8000 47d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 48d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* DHCP message OP code */ 49d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_BOOTREQUEST 1 50d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_BOOTREPLY 2 51d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 52d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* DHCP message type */ 53d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_DISCOVER 1 54d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_OFFER 2 55d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_REQUEST 3 56d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_DECLINE 4 57d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_ACK 5 58d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_NAK 6 59d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_RELEASE 7 60d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_INFORM 8 61d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_FORCERENEW 9 62d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 63d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* Constants taken from RFC 2131. */ 64d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define T1 0.5 65d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define T2 0.875 66d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_BASE 4 67d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_MAX 64 68d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_RAND_MIN -1 69d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_RAND_MAX 1 70d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 71d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#ifdef RFC2131_STRICT 72d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* Be strictly conformant for section 4.1.1 */ 73d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan# define DHCP_MIN_DELAY 1 74d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan# define DHCP_MAX_DELAY 10 75d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#else 76d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* or mirror the more modern IPv6RS and DHCPv6 delays */ 77d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan# define DHCP_MIN_DELAY 0 78d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan# define DHCP_MAX_DELAY 1 79d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#endif 80d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 81d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* DHCP options */ 82d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanenum DHO { 83d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_PAD = 0, 84d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_SUBNETMASK = 1, 85d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_ROUTER = 3, 86d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_DNSSERVER = 6, 87d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_HOSTNAME = 12, 88d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_DNSDOMAIN = 15, 89d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_MTU = 26, 90d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_BROADCAST = 28, 91d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_STATICROUTE = 33, 92d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_NISDOMAIN = 40, 93d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_NISSERVER = 41, 94d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_NTPSERVER = 42, 95d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_VENDOR = 43, 96d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_IPADDRESS = 50, 97d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_LEASETIME = 51, 98d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_OPTIONSOVERLOADED = 52, 99d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_MESSAGETYPE = 53, 100d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_SERVERID = 54, 101d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_PARAMETERREQUESTLIST = 55, 102d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_MESSAGE = 56, 103d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_MAXMESSAGESIZE = 57, 104d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_RENEWALTIME = 58, 105d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_REBINDTIME = 59, 106d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_VENDORCLASSID = 60, 107d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_CLIENTID = 61, 108d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_USERCLASS = 77, /* RFC 3004 */ 109d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_RAPIDCOMMIT = 80, /* RFC 4039 */ 110d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_FQDN = 81, 111d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_AUTHENTICATION = 90, /* RFC 3118 */ 112d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_AUTOCONFIGURE = 116, /* RFC 2563 */ 113d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_DNSSEARCH = 119, /* RFC 3397 */ 114d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_CSR = 121, /* RFC 3442 */ 115d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_VIVCO = 124, /* RFC 3925 */ 116d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_VIVSO = 125, /* RFC 3925 */ 117d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_FORCERENEW_NONCE = 145, /* RFC 6704 */ 118d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_SIXRD = 212, /* RFC 5969 */ 119d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_MSCSR = 249, /* MS code for RFC 3442 */ 120d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHO_END = 255 121d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan}; 122d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 123d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* FQDN values - lsnybble used in flags 124d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * hsnybble to create order 125d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * and to allow 0x00 to mean disable 126d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan */ 127d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanenum FQDN { 128d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan FQDN_DISABLE = 0x00, 129d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan FQDN_NONE = 0x18, 130d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan FQDN_PTR = 0x20, 131d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan FQDN_BOTH = 0x31 132d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan}; 133d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 134d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* Sizes for DHCP options */ 135d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_CHADDR_LEN 16 136d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define SERVERNAME_LEN 64 137d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define BOOTFILE_LEN 128 138d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_UDP_LEN (14 + 20 + 8) 139d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_FIXED_LEN (DHCP_UDP_LEN + 226) 140d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define DHCP_OPTION_LEN (MTU_MAX - DHCP_FIXED_LEN) 141d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 142d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* Some crappy DHCP servers require the BOOTP minimum length */ 143d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define BOOTP_MESSAGE_LENTH_MIN 300 144d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 1459177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tan/* Flags for the OPTIONSOVERLOADED field. */ 1469177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tan#define OPTION_OVERLOADED_BOOT_FILE 1 1479177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tan#define OPTION_OVERLOADED_SERVER_NAME 2 1489177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tan 149d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan/* Don't import common.h as that defines __unused which causes problems 150d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan * on some Linux systems which define it as part of a structure */ 151d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#if __GNUC__ > 2 || defined(__INTEL_COMPILER) 152d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan# ifndef __packed 153d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan# define __packed __attribute__((__packed__)) 154d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan# endif 155d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#else 156d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan# ifndef __packed 157d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan# define __packed 158d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan# endif 159d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#endif 160d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 161d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanstruct dhcp_message { 162d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint8_t op; /* message type */ 163d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint8_t hwtype; /* hardware address type */ 164d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint8_t hwlen; /* hardware address length */ 165d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint8_t hwopcount; /* should be zero in client message */ 166d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint32_t xid; /* transaction id */ 167d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint16_t secs; /* elapsed time in sec. from boot */ 168d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint16_t flags; 169d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint32_t ciaddr; /* (previously allocated) client IP */ 170d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint32_t yiaddr; /* 'your' client IP address */ 171d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint32_t siaddr; /* should be zero in client's messages */ 172d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint32_t giaddr; /* should be zero in client's messages */ 173d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint8_t chaddr[DHCP_CHADDR_LEN]; /* client's hardware address */ 174d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint8_t servername[SERVERNAME_LEN]; /* server host name */ 175d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint8_t bootfile[BOOTFILE_LEN]; /* boot file name */ 176d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint32_t cookie; 177d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint8_t options[DHCP_OPTION_LEN]; /* message options - cookie */ 178d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan} __packed; 179d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 1809177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tanstruct dhcp_option_iterator { 1819177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tan const struct dhcp_message *message; 1829177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tan const uint8_t *ptr; 1839177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tan const uint8_t *end; 1849177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tan uint8_t extra_option_locations; 1859177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tan uint8_t extra_option_locations_set; 1869177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tan}; 1879177c6fae9fb7aecf0a0d378050788ba609a5a41Samuel Tan 188d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanstruct dhcp_lease { 189d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct in_addr addr; 190d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct in_addr net; 191d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct in_addr brd; 192d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint32_t leasetime; 193d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint32_t renewaltime; 194d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint32_t rebindtime; 195d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct in_addr server; 196d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint8_t frominfo; 197d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint32_t cookie; 198d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan}; 199d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 200f20514bf582d08567217a3b06171bab5a11458eaSamuel Tan/* Extra data about servers stored in the lease file after the dhcp_message */ 201f20514bf582d08567217a3b06171bab5a11458eaSamuel Tanstruct dhcp_server_info { 202f20514bf582d08567217a3b06171bab5a11458eaSamuel Tan uint8_t gw_hwlen; 203f20514bf582d08567217a3b06171bab5a11458eaSamuel Tan unsigned char gw_hwaddr[HWADDR_LEN]; 204f20514bf582d08567217a3b06171bab5a11458eaSamuel Tan}; 205f20514bf582d08567217a3b06171bab5a11458eaSamuel Tan 206d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanenum DHS { 207d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHS_INIT, 208d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHS_DISCOVER, 209d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHS_REQUEST, 210d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHS_BOUND, 211d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHS_RENEW, 212d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHS_REBIND, 213d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHS_REBOOT, 214d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHS_INFORM, 215d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHS_RENEW_REQUESTED, 216d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHS_IPV4LL_BOUND, 217d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan DHS_PROBE 218d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan}; 219d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 220d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanstruct dhcp_state { 221d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan enum DHS state; 222d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct dhcp_message *sent; 223d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct dhcp_message *offer; 224d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct dhcp_message *new; 225d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct dhcp_message *old; 226d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct dhcp_lease lease; 227d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan const char *reason; 228d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan time_t interval; 229d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan time_t nakoff; 230d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint32_t xid; 231d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan int socket; 232d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 233d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan int raw_fd; 234d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan int arp_fd; 235d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan size_t buffer_size, buffer_len, buffer_pos; 236d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan unsigned char *buffer; 237d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 238d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct in_addr addr; 239d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct in_addr net; 240d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct in_addr dst; 241d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint8_t added; 242d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 243a3595821594453ea89ef8e6790927694b0a1adf1Samuel Tan char leasefile[PATH_MAX]; 244d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan time_t start_uptime; 245d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 246d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan unsigned char *clientid; 247d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 248d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct authstate auth; 249d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct arp_statehead arp_states; 250d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 251d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan size_t arping_index; 252d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 253d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan struct arp_state *arp_ipv4ll; 254d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan unsigned int conflicts; 2555158c9dfe576a285663b4ba16828fd6e9b35779cSamuel Tan int nak_receive_count; 2565158c9dfe576a285663b4ba16828fd6e9b35779cSamuel Tan int failed_address_offer_count; 2575158c9dfe576a285663b4ba16828fd6e9b35779cSamuel Tan struct in_addr failed; 258d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan time_t defend; 259d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan char randomstate[128]; 260f20514bf582d08567217a3b06171bab5a11458eaSamuel Tan struct dhcp_server_info server_info; 261d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan}; 262d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 263d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define D_STATE(ifp) \ 264d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan ((struct dhcp_state *)(ifp)->if_data[IF_DATA_DHCP]) 265d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define D_CSTATE(ifp) \ 266d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan ((const struct dhcp_state *)(ifp)->if_data[IF_DATA_DHCP]) 267d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define D_STATE_RUNNING(ifp) \ 268d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan (D_CSTATE((ifp)) && D_CSTATE((ifp))->new && D_CSTATE((ifp))->reason) 269d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 270d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#include "dhcpcd.h" 271d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#include "if-options.h" 272d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 273d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#ifdef INET 274d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanchar *decode_rfc3361(const uint8_t *, size_t); 275d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanssize_t decode_rfc3442(char *, size_t, const uint8_t *p, size_t); 276d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanssize_t decode_rfc5969(char *, size_t, const uint8_t *p, size_t); 277d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 278d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanvoid dhcp_printoptions(const struct dhcpcd_ctx *, 279d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan const struct dhcp_opt *, size_t); 280d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanint get_option_addr(struct dhcpcd_ctx *,struct in_addr *, 281d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan const struct dhcp_message *, uint8_t); 282d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define IS_BOOTP(i, m) ((m) && \ 283d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan !IN_LINKLOCAL(htonl((m)->yiaddr)) && \ 284d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan get_option_uint8((i)->ctx, NULL, (m), DHO_MESSAGETYPE) == -1) 285d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanstruct rt_head *get_option_routes(struct interface *, 286d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan const struct dhcp_message *); 287d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanssize_t dhcp_env(char **, const char *, const struct dhcp_message *, 288d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan const struct interface *); 289d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 290d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanuint32_t dhcp_xid(const struct interface *); 291d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanstruct dhcp_message *dhcp_message_new(const struct in_addr *addr, 292d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan const struct in_addr *mask); 293d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanint dhcp_message_add_addr(struct dhcp_message *, uint8_t, struct in_addr); 294d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanssize_t make_message(struct dhcp_message **, const struct interface *, 295d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan uint8_t); 296d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanint valid_dhcp_packet(unsigned char *); 297d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 298d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanvoid dhcp_handleifa(int, struct interface *, 299d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan const struct in_addr *, const struct in_addr *, const struct in_addr *, 300d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan int); 301d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 302d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanvoid dhcp_drop(struct interface *, const char *); 303d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanvoid dhcp_start(struct interface *); 304d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanvoid dhcp_stop(struct interface *); 305d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanvoid dhcp_discover(void *); 306d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanvoid dhcp_inform(struct interface *); 307d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanvoid dhcp_bind(struct interface *, struct arp_state *); 308d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanvoid dhcp_reboot_newopts(struct interface *, unsigned long long); 309d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanvoid dhcp_close(struct interface *); 310d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanvoid dhcp_free(struct interface *); 311d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tanint dhcp_dump(struct interface *); 312d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#else 313d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define dhcp_drop(a, b) {} 314d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define dhcp_start(a) {} 315d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define dhcp_reboot(a, b) (b = b) 316d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define dhcp_reboot_newopts(a, b) (b = b) 317d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define dhcp_close(a) {} 318d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define dhcp_free(a) {} 319d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#define dhcp_dump(a) (-1) 320d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#endif 321d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan 322d7ed851d6fc26c5e7db96971dbe6b44342b97727Samuel Tan#endif 323