Imported Upstream version 1.29
[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 <netinet/udp.h>
23 #include <netinet/ip.h>
24
25 #include <glib.h>
26
27 #include "unaligned.h"
28 #include "gdhcp.h"
29
30 #define CLIENT_PORT 68
31 #define SERVER_PORT 67
32
33 #define DHCPV6_CLIENT_PORT 546
34 #define DHCPV6_SERVER_PORT 547
35 #define MAX_DHCPV6_PKT_SIZE 1500
36
37 #define EXTEND_FOR_BUGGY_SERVERS 80
38
39 static const uint8_t MAC_BCAST_ADDR[ETH_ALEN] __attribute__((aligned(2))) = {
40         0xff, 0xff, 0xff, 0xff, 0xff, 0xff
41 };
42
43 static const uint8_t MAC_ANY_ADDR[ETH_ALEN] __attribute__((aligned(2))) = {
44         0x00, 0x00, 0x00, 0x00, 0x00, 0x00
45 };
46
47 /* DHCP packet */
48 #define DHCP_MAGIC              0x63825363
49 #define DHCP_OPTIONS_BUFSIZE    308
50 #define BOOTREQUEST             1
51 #define BOOTREPLY               2
52
53 #define BROADCAST_FLAG          0x8000
54
55 /* See RFC 2131 */
56 struct dhcp_packet {
57         uint8_t op;
58         uint8_t htype;
59         uint8_t hlen;
60         uint8_t hops;
61         uint32_t xid;
62         uint16_t secs;
63         uint16_t flags;
64         uint32_t ciaddr;
65         uint32_t yiaddr;
66         uint32_t siaddr_nip;
67         uint32_t gateway_nip;
68         uint8_t chaddr[16];
69         uint8_t sname[64];
70         uint8_t file[128];
71         uint32_t cookie;
72         uint8_t options[DHCP_OPTIONS_BUFSIZE + EXTEND_FOR_BUGGY_SERVERS];
73 } __attribute__((packed));
74
75 struct ip_udp_dhcp_packet {
76         struct iphdr ip;
77         struct udphdr udp;
78         struct dhcp_packet data;
79 } __attribute__((packed));
80
81 /* See RFC 3315 */
82 struct dhcpv6_packet {
83         uint8_t message;
84         uint8_t transaction_id[3];
85         uint8_t options[];
86 } __attribute__((packed));
87
88
89 /* See RFC 2132 */
90 #define DHCP_PADDING            0x00
91 #define DHCP_SUBNET             0x01
92 #define DHCP_ROUTER             0x03
93 #define DHCP_TIME_SERVER        0x04
94 #define DHCP_NAME_SERVER        0x05
95 #define DHCP_DNS_SERVER         0x06
96 #define DHCP_HOST_NAME          0x0c
97 #define DHCP_DOMAIN_NAME        0x0f
98 #define DHCP_NTP_SERVER         0x2a
99 #define DHCP_REQUESTED_IP       0x32
100 #define DHCP_LEASE_TIME         0x33
101 #define DHCP_OPTION_OVERLOAD    0x34
102 #define DHCP_MESSAGE_TYPE       0x35
103 #define DHCP_SERVER_ID          0x36
104 #define DHCP_PARAM_REQ          0x37
105 #define DHCP_ERR_MESSAGE        0x38
106 #define DHCP_MAX_SIZE           0x39
107 #define DHCP_VENDOR             0x3c
108 #define DHCP_CLIENT_ID          0x3d
109 #define DHCP_END                0xff
110
111 #define OPT_CODE                0
112 #define OPT_LEN                 1
113 #define OPT_DATA                2
114 #define OPTION_FIELD            0
115 #define FILE_FIELD              1
116 #define SNAME_FIELD             2
117
118 /* DHCP_MESSAGE_TYPE values */
119 #define DHCPDISCOVER            1
120 #define DHCPOFFER               2
121 #define DHCPREQUEST             3
122 #define DHCPDECLINE             4
123 #define DHCPACK                 5
124 #define DHCPNAK                 6
125 #define DHCPRELEASE             7
126 #define DHCPINFORM              8
127 #define DHCP_MINTYPE DHCPDISCOVER
128 #define DHCP_MAXTYPE DHCPINFORM
129
130 /* Message types for DHCPv6, RFC 3315 sec 5.3 */
131 #define DHCPV6_SOLICIT          1
132 #define DHCPV6_ADVERTISE        2
133 #define DHCPV6_REQUEST          3
134 #define DHCPV6_CONFIRM          4
135 #define DHCPV6_RENEW            5
136 #define DHCPV6_REBIND           6
137 #define DHCPV6_REPLY            7
138 #define DHCPV6_RELEASE          8
139 #define DHCPV6_DECLINE          9
140 #define DHCPV6_RECONFIGURE      10
141 #define DHCPV6_INFORMATION_REQ  11
142
143 /*
144  * DUID time starts 2000-01-01.
145  */
146 #define DUID_TIME_EPOCH 946684800
147
148 typedef enum {
149         OPTION_UNKNOWN,
150         OPTION_IP,
151         OPTION_STRING,
152         OPTION_U8,
153         OPTION_U16,
154         OPTION_U32,
155         OPTION_TYPE_MASK = 0x0f,
156         OPTION_LIST = 0x10,
157 } GDHCPOptionType;
158
159 typedef struct dhcp_option {
160         GDHCPOptionType type;
161         uint8_t code;
162 } DHCPOption;
163
164 /* Length of the option types in binary form */
165 static const uint8_t dhcp_option_lengths[] = {
166         [OPTION_IP]     = 4,
167         [OPTION_STRING] = 1,
168         [OPTION_U8]     = 1,
169         [OPTION_U16]    = 2,
170         [OPTION_U32]    = 4,
171 };
172
173 /* already defined within netinet/in.h if using GNU compiler */
174 #ifndef __USE_GNU
175 struct in6_pktinfo {
176         struct in6_addr ipi6_addr;  /* src/dst IPv6 address */
177         unsigned int ipi6_ifindex;  /* send/recv interface index */
178 };
179 #endif
180
181 uint8_t *dhcp_get_option(struct dhcp_packet *packet, int code);
182 uint8_t *dhcpv6_get_option(struct dhcpv6_packet *packet, uint16_t pkt_len,
183                         int code, uint16_t *option_len, int *option_count);
184 uint8_t *dhcpv6_get_sub_option(unsigned char *option, uint16_t max_len,
185                         uint16_t *code, uint16_t *option_len);
186 int dhcp_end_option(uint8_t *optionptr);
187 void dhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt);
188 void dhcpv6_add_binary_option(struct dhcpv6_packet *packet, uint16_t max_len,
189                                 uint16_t *pkt_len, uint8_t *addopt);
190 void dhcp_add_option_uint8(struct dhcp_packet *packet,
191                                 uint8_t code, uint8_t data);
192 void dhcp_add_option_uint16(struct dhcp_packet *packet,
193                                 uint8_t code, uint16_t data);
194 void dhcp_add_option_uint32(struct dhcp_packet *packet,
195                                 uint8_t code, uint32_t data);
196 GDHCPOptionType dhcp_get_code_type(uint8_t code);
197 GDHCPOptionType dhcpv6_get_code_type(uint16_t code);
198
199 uint16_t dhcp_checksum(void *addr, int count);
200
201 void dhcp_init_header(struct dhcp_packet *packet, char type);
202 void dhcpv6_init_header(struct dhcpv6_packet *packet, uint8_t type);
203
204 int dhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
205                         uint32_t source_ip, int source_port,
206                         uint32_t dest_ip, int dest_port,
207                         const uint8_t *dest_arp, int ifindex,
208                         bool bcast);
209 int dhcpv6_send_packet(int index, struct dhcpv6_packet *dhcp_pkt, int len);
210 int dhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
211                         uint32_t source_ip, int source_port,
212                         uint32_t dest_ip, int dest_port);
213 int dhcp_l3_socket(int port, const char *interface, int family);
214 int dhcp_recv_l3_packet(struct dhcp_packet *packet, int fd);
215 int dhcpv6_recv_l3_packet(struct dhcpv6_packet **packet, unsigned char *buf,
216                         int buf_len, int fd);
217 int dhcp_l3_socket_send(int index, int port, int family);
218
219 char *get_interface_name(int index);
220 bool interface_is_up(int index);