1 /** @file
2  *
3  * @brief DHCPv4 handler.
4  *
5  * This is not to be included by the application.
6  */
7 
8 /*
9  * Copyright (c) 2017 ARM Ltd.
10  * Copyright (c) 2018 Intel Corporation
11  *
12  * SPDX-License-Identifier: Apache-2.0
13  */
14 
15 #ifndef __INTERNAL_DHCPV4_H
16 #define __INTERNAL_DHCPV4_H
17 
18 struct dhcp_msg {
19 	uint8_t op;		/* Message type, 1:BOOTREQUEST, 2:BOOTREPLY */
20 	uint8_t htype;		/* Hardware Address Type */
21 	uint8_t hlen;		/* Hardware Address length */
22 	uint8_t hops;		/* used by relay agents when booting via relay
23 				 * agent, client sets zero
24 				 */
25 	uint32_t xid;		/* Transaction ID, random number */
26 	uint16_t secs;		/* Seconds elapsed since client began address
27 				 * acquisition or renewal process
28 				 */
29 	uint16_t flags;		/* Broadcast or Unicast */
30 	uint8_t ciaddr[4];		/* Client IP Address */
31 	uint8_t yiaddr[4];		/* your (client) IP address */
32 	uint8_t siaddr[4];		/* IP address of next server to use in bootstrap
33 				 * returned in DHCPOFFER, DHCPACK by server
34 				 */
35 	uint8_t giaddr[4];		/* Relat agent IP address */
36 	uint8_t chaddr[16];	/* Client hardware address */
37 } __packed;
38 
39 #define SIZE_OF_SNAME		64
40 #define SIZE_OF_FILE		128
41 #define SIZE_OF_MAGIC_COOKIE	4
42 
43 #define DHCPV4_MSG_BROADCAST	0x8000
44 #define DHCPV4_MSG_UNICAST	0x0000
45 
46 #define DHCPV4_MSG_BOOT_REQUEST	1
47 #define DHCPV4_MSG_BOOT_REPLY	2
48 
49 #define HARDWARE_ETHERNET_TYPE	1
50 
51 #define DHCPV4_SERVER_PORT	67
52 #define DHCPV4_CLIENT_PORT	68
53 
54 #define DHCPV4_OPTIONS_SUBNET_MASK	1
55 #define DHCPV4_OPTIONS_ROUTER		3
56 #define DHCPV4_OPTIONS_DNS_SERVER	6
57 #define DHCPV4_OPTIONS_LOG_SERVER	7
58 #define DHCPV4_OPTIONS_HOST_NAME	12
59 #define DHCPV4_OPTIONS_NTP_SERVER	42
60 #define DHCPV4_OPTIONS_VENDOR_SPECIFIC	43
61 #define DHCPV4_OPTIONS_REQ_IPADDR	50
62 #define DHCPV4_OPTIONS_LEASE_TIME	51
63 #define DHCPV4_OPTIONS_MSG_TYPE		53
64 #define DHCPV4_OPTIONS_SERVER_ID	54
65 #define DHCPV4_OPTIONS_REQ_LIST		55
66 #define DHCPV4_OPTIONS_RENEWAL		58
67 #define DHCPV4_OPTIONS_REBINDING	59
68 #define DHCPV4_OPTIONS_VENDOR_CLASS_ID	60
69 #define DHCPV4_OPTIONS_CLIENT_ID	61
70 #define DHCPV4_OPTIONS_END		255
71 
72 /* Useful size macros */
73 #define DHCPV4_OLV_MSG_HOST_NAME	2
74 #define DHCPV4_OLV_MSG_VENDOR_CLASS_ID	2
75 #define DHCPV4_OLV_MSG_REQ_IPADDR	6
76 #define DHCPV4_OLV_MSG_TYPE_SIZE	3
77 #define DHCPV4_OLV_MSG_SERVER_ID	6
78 #define DHCPV4_OLV_MSG_REQ_LIST		2
79 
80 #define DHCPV4_OLV_END_SIZE		1
81 
82 #define DHCPV4_MESSAGE_SIZE		(sizeof(struct dhcp_msg) +	\
83 					 SIZE_OF_SNAME + SIZE_OF_FILE + \
84 					 SIZE_OF_MAGIC_COOKIE +		\
85 					 DHCPV4_OLV_MSG_TYPE_SIZE +	\
86 					 DHCPV4_OLV_END_SIZE)
87 
88 
89 /* Maximum number of REQUEST retransmits before reverting to DISCOVER. */
90 #define DHCPV4_MAX_NUMBER_OF_ATTEMPTS	3
91 
92 /* Initial message retry timeout (s).  This timeout increases
93  * exponentially on each retransmit.
94  * RFC2131 4.1
95  */
96 #define DHCPV4_INITIAL_RETRY_TIMEOUT 4
97 
98 /* Initial minimum delay in INIT state before sending the
99  * initial DISCOVER message. MAx value is defined with
100  * CONFIG_NET_DHCPV4_INITIAL_DELAY_MAX. Default max value
101  * should be 10.
102  * RFC2131 4.1.1
103  */
104 #define DHCPV4_INITIAL_DELAY_MIN 1
105 
106 /* Minimum retransmission timeout in RENEW and REBIND states (in seconds).
107  * RFC2131 4.4.5
108  */
109 #define DHCPV4_RENEW_REBIND_TIMEOUT_MIN 60
110 
111 #if defined(CONFIG_NET_DHCPV4)
112 
113 int net_dhcpv4_init(void);
114 
115 #else
116 
117 #define net_dhcpv4_init() 0
118 
119 #endif /* CONFIG_NET_DHCPV4 */
120 
121 #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_DHCPV4_ACCEPT_UNICAST)
122 
123 /**
124  * @brief Verify if the incoming packet should be accepted for the DHCPv4
125  *        module to process.
126  *
127  * In case server responds with an unicast IP packet, the IP stack needs to
128  * pass it through for the DHCPv4 module to process, before the actual
129  * destination IP address is configured on an interface.
130  * This function allows to determine whether there is an active DHCPv4 query on
131  * the interface and the packet is destined for the DHCPv4 module to process.
132  *
133  * @param pkt A packet to analyze
134  *
135  * @return true if the packet shall be accepted, false otherwise
136  */
137 bool net_dhcpv4_accept_unicast(struct net_pkt *pkt);
138 
139 #else
140 
net_dhcpv4_accept_unicast(struct net_pkt * pkt)141 static inline bool net_dhcpv4_accept_unicast(struct net_pkt *pkt)
142 {
143 	ARG_UNUSED(pkt);
144 
145 	return false;
146 }
147 
148 #endif /* CONFIG_NET_DHCPV4 && CONFIG_NET_DHCPV4_ACCEPT_UNICAST */
149 
150 #if defined(CONFIG_NET_DHCPV4_SERVER)
151 
152 void net_dhcpv4_server_init(void);
153 
154 #else
155 
156 #define net_dhcpv4_server_init()
157 
158 #endif /* CONFIG_NET_DHCPV4_SERVER */
159 
160 #endif /* __INTERNAL_DHCPV4_H */
161