1 /* 2 * dhcpcd - DHCP client daemon 3 * Copyright 2006-2008 Roy Marples <roy (at) 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 33 #include <stdint.h> 34 35 #include "config.h" 36 #include "dhcpcd.h" 37 #include "net.h" 38 39 /* Max MTU - defines dhcp option length */ 40 #define MTU_MAX 1500 41 #define MTU_MIN 576 42 43 /* UDP port numbers for DHCP */ 44 #define DHCP_SERVER_PORT 67 45 #define DHCP_CLIENT_PORT 68 46 47 #define MAGIC_COOKIE 0x63825363 48 #define BROADCAST_FLAG 0x8000 49 50 /* DHCP message OP code */ 51 #define DHCP_BOOTREQUEST 1 52 #define DHCP_BOOTREPLY 2 53 54 /* DHCP message type */ 55 #define DHCP_DISCOVER 1 56 #define DHCP_OFFER 2 57 #define DHCP_REQUEST 3 58 #define DHCP_DECLINE 4 59 #define DHCP_ACK 5 60 #define DHCP_NAK 6 61 #define DHCP_RELEASE 7 62 #define DHCP_INFORM 8 63 64 /* DHCP options */ 65 enum DHO 66 { 67 DHO_PAD = 0, 68 DHO_SUBNETMASK = 1, 69 DHO_ROUTER = 3, 70 DHO_DNSSERVER = 6, 71 DHO_HOSTNAME = 12, 72 DHO_DNSDOMAIN = 15, 73 DHO_MTU = 26, 74 DHO_BROADCAST = 28, 75 DHO_STATICROUTE = 33, 76 DHO_NISDOMAIN = 40, 77 DHO_NISSERVER = 41, 78 DHO_NTPSERVER = 42, 79 DHO_VENDOR = 43, 80 DHO_IPADDRESS = 50, 81 DHO_LEASETIME = 51, 82 DHO_OPTIONSOVERLOADED = 52, 83 DHO_MESSAGETYPE = 53, 84 DHO_SERVERID = 54, 85 DHO_PARAMETERREQUESTLIST = 55, 86 DHO_MESSAGE = 56, 87 DHO_MAXMESSAGESIZE = 57, 88 DHO_RENEWALTIME = 58, 89 DHO_REBINDTIME = 59, 90 DHO_VENDORCLASSID = 60, 91 DHO_CLIENTID = 61, 92 DHO_USERCLASS = 77, /* RFC 3004 */ 93 DHO_FQDN = 81, 94 DHO_DNSSEARCH = 119, /* RFC 3397 */ 95 DHO_CSR = 121, /* RFC 3442 */ 96 DHO_MSCSR = 249, /* MS code for RFC 3442 */ 97 DHO_END = 255 98 }; 99 100 /* FQDN values - lsnybble used in flags 101 * hsnybble to create order 102 * and to allow 0x00 to mean disable 103 */ 104 enum FQDN { 105 FQDN_DISABLE = 0x00, 106 FQDN_NONE = 0x18, 107 FQDN_PTR = 0x20, 108 FQDN_BOTH = 0x31 109 }; 110 111 /* Sizes for DHCP options */ 112 #define DHCP_CHADDR_LEN 16 113 #define SERVERNAME_LEN 64 114 #define BOOTFILE_LEN 128 115 #define DHCP_UDP_LEN (20 + 8) 116 #define DHCP_BASE_LEN (4 + 4 + 2 + 2 + 4 + 4 + 4 + 4 + 4) 117 #define DHCP_RESERVE_LEN (4 + 4 + 4 + 4 + 2) 118 #define DHCP_FIXED_LEN (DHCP_BASE_LEN + DHCP_CHADDR_LEN + \ 119 + SERVERNAME_LEN + BOOTFILE_LEN) 120 #define DHCP_OPTION_LEN (MTU_MAX - DHCP_FIXED_LEN - DHCP_UDP_LEN \ 121 - DHCP_RESERVE_LEN) 122 123 /* Some crappy DHCP servers require the BOOTP minimum length */ 124 #define BOOTP_MESSAGE_LENTH_MIN 300 125 126 struct dhcp_message { 127 uint8_t op; /* message type */ 128 uint8_t hwtype; /* hardware address type */ 129 uint8_t hwlen; /* hardware address length */ 130 uint8_t hwopcount; /* should be zero in client message */ 131 uint32_t xid; /* transaction id */ 132 uint16_t secs; /* elapsed time in sec. from boot */ 133 uint16_t flags; 134 uint32_t ciaddr; /* (previously allocated) client IP */ 135 uint32_t yiaddr; /* 'your' client IP address */ 136 uint32_t siaddr; /* should be zero in client's messages */ 137 uint32_t giaddr; /* should be zero in client's messages */ 138 uint8_t chaddr[DHCP_CHADDR_LEN]; /* client's hardware address */ 139 uint8_t servername[SERVERNAME_LEN]; /* server host name */ 140 uint8_t bootfile[BOOTFILE_LEN]; /* boot file name */ 141 uint32_t cookie; 142 uint8_t options[DHCP_OPTION_LEN]; /* message options - cookie */ 143 }; 144 145 struct dhcp_lease { 146 struct in_addr addr; 147 struct in_addr net; 148 uint32_t leasetime; 149 uint32_t renewaltime; 150 uint32_t rebindtime; 151 struct in_addr server; 152 time_t leasedfrom; 153 struct timeval boundtime; 154 uint8_t frominfo; 155 }; 156 157 #define add_option_mask(var, val) (var[val >> 3] |= 1 << (val & 7)) 158 #define del_option_mask(var, val) (var[val >> 3] &= ~(1 << (val & 7))) 159 #define has_option_mask(var, val) (var[val >> 3] & (1 << (val & 7))) 160 int make_option_mask(uint8_t *, char **, int); 161 void print_options(void); 162 char *get_option_string(const struct dhcp_message *, uint8_t); 163 int get_option_addr(struct in_addr *, const struct dhcp_message *, uint8_t); 164 int get_option_uint32(uint32_t *, const struct dhcp_message *, uint8_t); 165 int get_option_uint16(uint16_t *, const struct dhcp_message *, uint8_t); 166 int get_option_uint8(uint8_t *, const struct dhcp_message *, uint8_t); 167 struct rt *get_option_routes(const struct dhcp_message *); 168 ssize_t configure_env(char **, const char *, const struct dhcp_message *, 169 const struct options *); 170 171 ssize_t make_message(struct dhcp_message **, 172 const struct interface *, const struct dhcp_lease *, 173 uint32_t, uint8_t, const struct options *); 174 int valid_dhcp_packet(unsigned char *); 175 176 ssize_t write_lease(const struct interface *, const struct dhcp_message *); 177 struct dhcp_message *read_lease(const struct interface *iface); 178 #endif 179