3 * DHCP client library with GLib integration
5 * Copyright (C) 2009-2012 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <netinet/udp.h>
24 #include <netinet/ip.h>
28 #include "unaligned.h"
31 #define CLIENT_PORT 68
32 #define SERVER_PORT 67
34 #define DHCPV6_CLIENT_PORT 546
35 #define DHCPV6_SERVER_PORT 547
36 #define MAX_DHCPV6_PKT_SIZE 1500
38 #define EXTEND_FOR_BUGGY_SERVERS 80
40 static const uint8_t MAC_BCAST_ADDR[ETH_ALEN] __attribute__((aligned(2))) = {
41 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
44 static const uint8_t MAC_ANY_ADDR[ETH_ALEN] __attribute__((aligned(2))) = {
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
49 #define DHCP_MAGIC 0x63825363
50 #define DHCP_OPTIONS_BUFSIZE 308
54 #define BROADCAST_FLAG 0x8000
73 uint8_t options[DHCP_OPTIONS_BUFSIZE + EXTEND_FOR_BUGGY_SERVERS];
74 } __attribute__((packed));
76 struct ip_udp_dhcp_packet {
79 struct dhcp_packet data;
80 } __attribute__((packed));
83 struct dhcpv6_packet {
85 uint8_t transaction_id[3];
87 } __attribute__((packed));
91 #define DHCP_PADDING 0x00
92 #define DHCP_SUBNET 0x01
93 #define DHCP_ROUTER 0x03
94 #define DHCP_TIME_SERVER 0x04
95 #define DHCP_NAME_SERVER 0x05
96 #define DHCP_DNS_SERVER 0x06
97 #define DHCP_HOST_NAME 0x0c
98 #define DHCP_DOMAIN_NAME 0x0f
99 #define DHCP_NTP_SERVER 0x2a
100 #define DHCP_REQUESTED_IP 0x32
101 #define DHCP_LEASE_TIME 0x33
102 #define DHCP_OPTION_OVERLOAD 0x34
103 #define DHCP_MESSAGE_TYPE 0x35
104 #define DHCP_SERVER_ID 0x36
105 #define DHCP_PARAM_REQ 0x37
106 #define DHCP_ERR_MESSAGE 0x38
107 #define DHCP_MAX_SIZE 0x39
108 #define DHCP_VENDOR 0x3c
109 #define DHCP_CLIENT_ID 0x3d
110 #define DHCP_END 0xff
115 #define OPTION_FIELD 0
117 #define SNAME_FIELD 2
119 /* DHCP_MESSAGE_TYPE values */
120 #define DHCPDISCOVER 1
122 #define DHCPREQUEST 3
123 #define DHCPDECLINE 4
126 #define DHCPRELEASE 7
128 #define DHCP_MINTYPE DHCPDISCOVER
129 #define DHCP_MAXTYPE DHCPINFORM
131 /* Message types for DHCPv6, RFC 3315 sec 5.3 */
132 #define DHCPV6_SOLICIT 1
133 #define DHCPV6_ADVERTISE 2
134 #define DHCPV6_REQUEST 3
135 #define DHCPV6_CONFIRM 4
136 #define DHCPV6_RENEW 5
137 #define DHCPV6_REBIND 6
138 #define DHCPV6_REPLY 7
139 #define DHCPV6_RELEASE 8
140 #define DHCPV6_DECLINE 9
141 #define DHCPV6_RECONFIGURE 10
142 #define DHCPV6_INFORMATION_REQ 11
145 * DUID time starts 2000-01-01.
147 #define DUID_TIME_EPOCH 946684800
156 OPTION_TYPE_MASK = 0x0f,
160 typedef struct dhcp_option {
161 GDHCPOptionType type;
165 /* Length of the option types in binary form */
166 static const uint8_t dhcp_option_lengths[] = {
174 /* already defined within netinet/in.h if using glibc or musl */
175 #ifndef HAVE_STRUCT_IN6_PKTINFO_IPI6_ADDR
177 struct in6_addr ipi6_addr; /* src/dst IPv6 address */
178 unsigned int ipi6_ifindex; /* send/recv interface index */
182 uint8_t *dhcp_get_option(struct dhcp_packet *packet, int code);
183 uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len,
184 int code, uint16_t *option_len, int *option_count);
185 uint8_t *dhcpv6_get_sub_option(unsigned char *option, uint16_t max_len,
186 uint16_t *code, uint16_t *option_len);
187 int dhcp_end_option(uint8_t *optionptr);
188 void dhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt);
189 void dhcpv6_add_binary_option(struct dhcpv6_packet *packet, uint16_t max_len,
190 uint16_t *pkt_len, uint8_t *addopt);
191 void dhcp_add_option_uint8(struct dhcp_packet *packet,
192 uint8_t code, uint8_t data);
193 void dhcp_add_option_uint16(struct dhcp_packet *packet,
194 uint8_t code, uint16_t data);
195 void dhcp_add_option_uint32(struct dhcp_packet *packet,
196 uint8_t code, uint32_t data);
197 GDHCPOptionType dhcp_get_code_type(uint8_t code);
198 GDHCPOptionType dhcpv6_get_code_type(uint16_t code);
200 uint16_t dhcp_checksum(void *addr, int count);
202 void dhcp_init_header(struct dhcp_packet *packet, char type);
203 void dhcpv6_init_header(struct dhcpv6_packet *packet, uint8_t type);
205 int dhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
206 uint32_t source_ip, int source_port,
207 uint32_t dest_ip, int dest_port,
208 const uint8_t *dest_arp, int ifindex,
210 int dhcpv6_send_packet(int index, struct dhcpv6_packet *dhcp_pkt, int len);
211 int dhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
212 uint32_t source_ip, int source_port,
213 uint32_t dest_ip, int dest_port,
214 const char *interface);
215 int dhcp_l3_socket(int port, const char *interface, int family);
216 int dhcp_recv_l3_packet(struct dhcp_packet *packet, int fd);
217 int dhcpv6_recv_l3_packet(struct dhcpv6_packet **packet, unsigned char *buf,
218 int buf_len, int fd);
219 int dhcp_l3_socket_send(int index, int port, int family);
221 char *get_interface_name(int index);
222 bool interface_is_up(int index);