Handle potential NULL pointer with DHCP options
[framework/connectivity/connman.git] / gdhcp / common.h
1 /*
2  *
3  *  DHCP client library with GLib integration
4  *
5  *  Copyright (C) 2009-2010  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 "gdhcp.h"
28
29 #define dhcp_get_unaligned(ptr)                 \
30 ({                                              \
31         struct __attribute__((packed)) {        \
32                 typeof(*(ptr)) __v;             \
33         } *__p = (void *) (ptr);                \
34         __p->__v;                               \
35 })
36
37 #define dhcp_put_unaligned(val, ptr)            \
38 do {                                            \
39         struct __attribute__((packed)) {        \
40                 typeof(*(ptr)) __v;             \
41         } *__p = (void *) (ptr);                \
42         __p->__v = (val);                       \
43 } while (0)
44
45 #define CLIENT_PORT 68
46 #define SERVER_PORT 67
47
48 #define EXTEND_FOR_BUGGY_SERVERS 80
49
50 static const uint8_t MAC_BCAST_ADDR[6] __attribute__((aligned(2))) = {
51         0xff, 0xff, 0xff, 0xff, 0xff, 0xff
52 };
53
54 /* DHCP packet */
55 #define DHCP_MAGIC              0x63825363
56 #define DHCP_OPTIONS_BUFSIZE    308
57 #define BOOTREQUEST             1
58 #define BOOTREPLY               2
59
60 #define BROADCAST_FLAG          0x8000
61
62 /* See RFC 2131 */
63 struct dhcp_packet {
64         uint8_t op;
65         uint8_t htype;
66         uint8_t hlen;
67         uint8_t hops;
68         uint32_t xid;
69         uint16_t secs;
70         uint16_t flags;
71         uint32_t ciaddr;
72         uint32_t yiaddr;
73         uint32_t siaddr_nip;
74         uint32_t gateway_nip;
75         uint8_t chaddr[16];
76         uint8_t sname[64];
77         uint8_t file[128];
78         uint32_t cookie;
79         uint8_t options[DHCP_OPTIONS_BUFSIZE + EXTEND_FOR_BUGGY_SERVERS];
80 } __attribute__((packed));
81
82 struct ip_udp_dhcp_packet {
83         struct iphdr ip;
84         struct udphdr udp;
85         struct dhcp_packet data;
86 } __attribute__((packed));
87
88 /* See RFC 2132 */
89 #define DHCP_PADDING            0x00
90 #define DHCP_SUBNET             0x01
91 #define DHCP_ROUTER             0x03
92 #define DHCP_TIME_SERVER        0x04
93 #define DHCP_NAME_SERVER        0x05
94 #define DHCP_DNS_SERVER         0x06
95 #define DHCP_HOST_NAME          0x0c
96 #define DHCP_DOMAIN_NAME        0x0f
97 #define DHCP_NTP_SERVER         0x2a
98 #define DHCP_REQUESTED_IP       0x32
99 #define DHCP_LEASE_TIME         0x33
100 #define DHCP_OPTION_OVERLOAD    0x34
101 #define DHCP_MESSAGE_TYPE       0x35
102 #define DHCP_SERVER_ID          0x36
103 #define DHCP_PARAM_REQ          0x37
104 #define DHCP_ERR_MESSAGE        0x38
105 #define DHCP_MAX_SIZE           0x39
106 #define DHCP_VENDOR             0x3c
107 #define DHCP_CLIENT_ID          0x3d
108 #define DHCP_END                0xff
109
110 #define OPT_CODE                0
111 #define OPT_LEN                 1
112 #define OPT_DATA                2
113 #define OPTION_FIELD            0
114 #define FILE_FIELD              1
115 #define SNAME_FIELD             2
116
117 /* DHCP_MESSAGE_TYPE values */
118 #define DHCPDISCOVER            1
119 #define DHCPOFFER               2
120 #define DHCPREQUEST             3
121 #define DHCPDECLINE             4
122 #define DHCPACK                 5
123 #define DHCPNAK                 6
124 #define DHCPRELEASE             7
125 #define DHCPINFORM              8
126 #define DHCP_MINTYPE DHCPDISCOVER
127 #define DHCP_MAXTYPE DHCPINFORM
128
129 typedef enum {
130         OPTION_UNKNOWN,
131         OPTION_IP,
132         OPTION_STRING,
133         OPTION_U8,
134         OPTION_U16,
135         OPTION_U32,
136         OPTION_TYPE_MASK = 0x0f,
137         OPTION_LIST = 0x10,
138 } GDHCPOptionType;
139
140 typedef struct dhcp_option {
141         GDHCPOptionType type;
142         uint8_t code;
143 } DHCPOption;
144
145 /* Length of the option types in binary form */
146 static const uint8_t dhcp_option_lengths[] = {
147         [OPTION_IP]     = 4,
148         [OPTION_STRING] = 1,
149         [OPTION_U8]     = 1,
150         [OPTION_U16]    = 2,
151         [OPTION_U32]    = 4,
152 };
153
154 uint8_t *dhcp_get_option(struct dhcp_packet *packet, int code);
155 int dhcp_end_option(uint8_t *optionptr);
156 void dhcp_add_binary_option(struct dhcp_packet *packet, uint8_t *addopt);
157 void dhcp_add_simple_option(struct dhcp_packet *packet,
158                                 uint8_t code, uint32_t data);
159 GDHCPOptionType dhcp_get_code_type(uint8_t code);
160
161 uint16_t dhcp_checksum(void *addr, int count);
162
163 void dhcp_init_header(struct dhcp_packet *packet, char type);
164
165 int dhcp_send_raw_packet(struct dhcp_packet *dhcp_pkt,
166                         uint32_t source_ip, int source_port,
167                         uint32_t dest_ip, int dest_port,
168                         const uint8_t *dest_arp, int ifindex);
169 int dhcp_send_kernel_packet(struct dhcp_packet *dhcp_pkt,
170                         uint32_t source_ip, int source_port,
171                         uint32_t dest_ip, int dest_port);
172 int dhcp_l3_socket(int port, const char *interface);
173 int dhcp_recv_l3_packet(struct dhcp_packet *packet, int fd);