9660231cc49debc96bf70f4d74538ea3165d4c47
[platform/upstream/connman.git] / gdhcp / common.h
1 /*
2  *
3  *  DHCP client library with GLib integration
4  *
5  *  Copyright (C) 2009-2012  Intel Corporation. All rights reserved.
6  *
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.
10  *
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.
15  *
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
19  *
20  */
21
22 #include <config.h>
23 #include <netinet/udp.h>
24 #include <netinet/ip.h>
25
26 #include <glib.h>
27
28 #include "unaligned.h"
29 #include "gdhcp.h"
30
31 #define CLIENT_PORT 68
32 #define SERVER_PORT 67
33
34 #define DHCPV6_CLIENT_PORT 546
35 #define DHCPV6_SERVER_PORT 547
36 #define MAX_DHCPV6_PKT_SIZE 1500
37
38 #define EXTEND_FOR_BUGGY_SERVERS 80
39
40 static const uint8_t MAC_BCAST_ADDR[ETH_ALEN] __attribute__((aligned(2))) = {
41         0xff, 0xff, 0xff, 0xff, 0xff, 0xff
42 };
43
44 static const uint8_t MAC_ANY_ADDR[ETH_ALEN] __attribute__((aligned(2))) = {
45         0x00, 0x00, 0x00, 0x00, 0x00, 0x00
46 };
47
48 /* DHCP packet */
49 #define DHCP_MAGIC              0x63825363
50 #define DHCP_OPTIONS_BUFSIZE    308
51 #define BOOTREQUEST             1
52 #define BOOTREPLY               2
53
54 #define BROADCAST_FLAG          0x8000
55
56 /* See RFC 2131 */
57 struct dhcp_packet {
58         uint8_t op;
59         uint8_t htype;
60         uint8_t hlen;
61         uint8_t hops;
62         uint32_t xid;
63         uint16_t secs;
64         uint16_t flags;
65         uint32_t ciaddr;
66         uint32_t yiaddr;
67         uint32_t siaddr_nip;
68         uint32_t gateway_nip;
69         uint8_t chaddr[16];
70         uint8_t sname[64];
71         uint8_t file[128];
72         uint32_t cookie;
73         uint8_t options[DHCP_OPTIONS_BUFSIZE + EXTEND_FOR_BUGGY_SERVERS];
74 } __attribute__((packed));
75
76 struct ip_udp_dhcp_packet {
77         struct iphdr ip;
78         struct udphdr udp;
79         struct dhcp_packet data;
80 } __attribute__((packed));
81
82 /* See RFC 3315 */
83 struct dhcpv6_packet {
84         uint8_t message;
85         uint8_t transaction_id[3];
86         uint8_t options[];
87 } __attribute__((packed));
88
89
90 /* See RFC 2132 */
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
111
112 #define OPT_CODE                0
113 #define OPT_LEN                 1
114 #define OPT_DATA                2
115 #define OPTION_FIELD            0
116 #define FILE_FIELD              1
117 #define SNAME_FIELD             2
118
119 /* DHCP_MESSAGE_TYPE values */
120 #define DHCPDISCOVER            1
121 #define DHCPOFFER               2
122 #define DHCPREQUEST             3
123 #define DHCPDECLINE             4
124 #define DHCPACK                 5
125 #define DHCPNAK                 6
126 #define DHCPRELEASE             7
127 #define DHCPINFORM              8
128 #define DHCP_MINTYPE DHCPDISCOVER
129 #define DHCP_MAXTYPE DHCPINFORM
130
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
143
144 /*
145  * DUID time starts 2000-01-01.
146  */
147 #define DUID_TIME_EPOCH 946684800
148
149 typedef enum {
150         OPTION_UNKNOWN,
151         OPTION_IP,
152         OPTION_STRING,
153         OPTION_U8,
154         OPTION_U16,
155         OPTION_U32,
156         OPTION_TYPE_MASK = 0x0f,
157         OPTION_LIST = 0x10,
158 } GDHCPOptionType;
159
160 typedef struct dhcp_option {
161         GDHCPOptionType type;
162         uint8_t code;
163 } DHCPOption;
164
165 /* Length of the option types in binary form */
166 static const uint8_t dhcp_option_lengths[] = {
167         [OPTION_IP]     = 4,
168         [OPTION_STRING] = 1,
169         [OPTION_U8]     = 1,
170         [OPTION_U16]    = 2,
171         [OPTION_U32]    = 4,
172 };
173
174 /* already defined within netinet/in.h if using glibc or musl */
175 #ifndef HAVE_STRUCT_IN6_PKTINFO_IPI6_ADDR
176 struct in6_pktinfo {
177         struct in6_addr ipi6_addr;  /* src/dst IPv6 address */
178         unsigned int ipi6_ifindex;  /* send/recv interface index */
179 };
180 #endif
181
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);
199
200 uint16_t dhcp_checksum(void *addr, int count);
201
202 void dhcp_init_header(struct dhcp_packet *packet, char type);
203 void dhcpv6_init_header(struct dhcpv6_packet *packet, uint8_t type);
204
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,
209                         bool bcast);
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);
220
221 char *get_interface_name(int index);
222 bool interface_is_up(int index);