1/* 2 * dhcpcd - DHCP client daemon 3 * Copyright (c) 2006-2012 Roy Marples <roy@marples.name> 4 * All rights reserved 5 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#ifndef DHCP_H 29#define DHCP_H 30 31#include <arpa/inet.h> 32#include <netinet/in.h> 33 34#include <stdint.h> 35 36#include "common.h" 37 38/* Max MTU - defines dhcp option length */ 39#define MTU_MAX 1500 40#define MTU_MIN 576 41 42/* UDP port numbers for DHCP */ 43#define DHCP_SERVER_PORT 67 44#define DHCP_CLIENT_PORT 68 45 46#define MAGIC_COOKIE 0x63825363 47#define BROADCAST_FLAG 0x8000 48 49/* DHCP message OP code */ 50#define DHCP_BOOTREQUEST 1 51#define DHCP_BOOTREPLY 2 52 53/* DHCP message type */ 54#define DHCP_DISCOVER 1 55#define DHCP_OFFER 2 56#define DHCP_REQUEST 3 57#define DHCP_DECLINE 4 58#define DHCP_ACK 5 59#define DHCP_NAK 6 60#define DHCP_RELEASE 7 61#define DHCP_INFORM 8 62 63/* Constants taken from RFC 2131. */ 64#define T1 0.5 65#define T2 0.875 66#define DHCP_BASE 4 67#define DHCP_MAX 64 68#define DHCP_RAND_MIN -1 69#define DHCP_RAND_MAX 1 70#define DHCP_ARP_FAIL 10 71 72/* number of usecs in a second. */ 73#define USECS_SECOND 1000000 74/* As we use timevals, we should use the usec part for 75 * greater randomisation. */ 76#define DHCP_RAND_MIN_U DHCP_RAND_MIN * USECS_SECOND 77#define DHCP_RAND_MAX_U DHCP_RAND_MAX * USECS_SECOND 78#define PROBE_MIN_U PROBE_MIN * USECS_SECOND 79#define PROBE_MAX_U PROBE_MAX * USECS_SECOND 80 81/* DHCP options */ 82enum DHO { 83 DHO_PAD = 0, 84 DHO_SUBNETMASK = 1, 85 DHO_ROUTER = 3, 86 DHO_DNSSERVER = 6, 87 DHO_HOSTNAME = 12, 88 DHO_DNSDOMAIN = 15, 89 DHO_MTU = 26, 90 DHO_BROADCAST = 28, 91 DHO_STATICROUTE = 33, 92 DHO_NISDOMAIN = 40, 93 DHO_NISSERVER = 41, 94 DHO_NTPSERVER = 42, 95 DHO_VENDOR = 43, 96 DHO_IPADDRESS = 50, 97 DHO_LEASETIME = 51, 98 DHO_OPTIONSOVERLOADED = 52, 99 DHO_MESSAGETYPE = 53, 100 DHO_SERVERID = 54, 101 DHO_PARAMETERREQUESTLIST = 55, 102 DHO_MESSAGE = 56, 103 DHO_MAXMESSAGESIZE = 57, 104 DHO_RENEWALTIME = 58, 105 DHO_REBINDTIME = 59, 106 DHO_VENDORCLASSID = 60, 107 DHO_CLIENTID = 61, 108 DHO_USERCLASS = 77, /* RFC 3004 */ 109 DHO_FQDN = 81, 110 DHO_DNSSEARCH = 119, /* RFC 3397 */ 111 DHO_CSR = 121, /* RFC 3442 */ 112 DHO_SIXRD = 212, /* RFC 5969 */ 113 DHO_MSCSR = 249, /* MS code for RFC 3442 */ 114 DHO_END = 255 115}; 116 117/* FQDN values - lsnybble used in flags 118 * hsnybble to create order 119 * and to allow 0x00 to mean disable 120 */ 121enum FQDN { 122 FQDN_DISABLE = 0x00, 123 FQDN_NONE = 0x18, 124 FQDN_PTR = 0x20, 125 FQDN_BOTH = 0x31 126}; 127 128/* Sizes for DHCP options */ 129#define DHCP_CHADDR_LEN 16 130#define SERVERNAME_LEN 64 131#define BOOTFILE_LEN 128 132#define DHCP_UDP_LEN (14 + 20 + 8) 133#define DHCP_FIXED_LEN (DHCP_UDP_LEN + 226) 134#define DHCP_OPTION_LEN (MTU_MAX - DHCP_FIXED_LEN) 135 136/* Some crappy DHCP servers require the BOOTP minimum length */ 137#define BOOTP_MESSAGE_LENTH_MIN 300 138 139struct dhcp_message { 140 uint8_t op; /* message type */ 141 uint8_t hwtype; /* hardware address type */ 142 uint8_t hwlen; /* hardware address length */ 143 uint8_t hwopcount; /* should be zero in client message */ 144 uint32_t xid; /* transaction id */ 145 uint16_t secs; /* elapsed time in sec. from boot */ 146 uint16_t flags; 147 uint32_t ciaddr; /* (previously allocated) client IP */ 148 uint32_t yiaddr; /* 'your' client IP address */ 149 uint32_t siaddr; /* should be zero in client's messages */ 150 uint32_t giaddr; /* should be zero in client's messages */ 151 uint8_t chaddr[DHCP_CHADDR_LEN]; /* client's hardware address */ 152 uint8_t servername[SERVERNAME_LEN]; /* server host name */ 153 uint8_t bootfile[BOOTFILE_LEN]; /* boot file name */ 154 uint32_t cookie; 155 uint8_t options[DHCP_OPTION_LEN]; /* message options - cookie */ 156} _packed; 157 158struct dhcp_lease { 159 struct in_addr addr; 160 struct in_addr net; 161 struct in_addr brd; 162 uint32_t leasetime; 163 uint32_t renewaltime; 164 uint32_t rebindtime; 165 struct in_addr server; 166 time_t leasedfrom; 167 struct timeval boundtime; 168 uint8_t frominfo; 169 uint32_t cookie; 170}; 171 172#include "dhcpcd.h" 173#include "if-options.h" 174#include "net.h" 175 176#define add_option_mask(var, val) (var[val >> 3] |= 1 << (val & 7)) 177#define del_option_mask(var, val) (var[val >> 3] &= ~(1 << (val & 7))) 178#define has_option_mask(var, val) (var[val >> 3] & (1 << (val & 7))) 179int make_option_mask(uint8_t *, const char *, int); 180void print_options(void); 181char *get_option_string(const struct dhcp_message *, uint8_t); 182int get_option_addr(struct in_addr *, const struct dhcp_message *, uint8_t); 183int get_option_uint32(uint32_t *, const struct dhcp_message *, uint8_t); 184int get_option_uint16(uint16_t *, const struct dhcp_message *, uint8_t); 185int get_option_uint8(uint8_t *, const struct dhcp_message *, uint8_t); 186#define is_bootp(m) (m && \ 187 !IN_LINKLOCAL(htonl((m)->yiaddr)) && \ 188 get_option_uint8(NULL, m, DHO_MESSAGETYPE) == -1) 189struct rt *get_option_routes(const struct dhcp_message *, const char *, 190 unsigned long long *); 191ssize_t decode_rfc3397(char *, ssize_t, int, const uint8_t *); 192ssize_t configure_env(char **, const char *, const struct dhcp_message *, 193 const struct if_options *); 194 195int dhcp_message_add_addr(struct dhcp_message *, uint8_t, struct in_addr); 196ssize_t make_message(struct dhcp_message **, const struct interface *, 197 uint8_t); 198int valid_dhcp_packet(unsigned char *); 199 200ssize_t write_lease(const struct interface *, const struct dhcp_message *); 201struct dhcp_message *read_lease(const struct interface *); 202void get_lease(struct dhcp_lease *, const struct dhcp_message *); 203 204#endif 205