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