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_PAD		0
55 #define DHCPV4_OPTIONS_SUBNET_MASK	1
56 #define DHCPV4_OPTIONS_ROUTER		3
57 #define DHCPV4_OPTIONS_DNS_SERVER	6
58 #define DHCPV4_OPTIONS_LOG_SERVER	7
59 #define DHCPV4_OPTIONS_HOST_NAME	12
60 #define DHCPV4_OPTIONS_DOMAIN_NAME	15
61 #define DHCPV4_OPTIONS_BROADCAST	28
62 #define DHCPV4_OPTIONS_NTP_SERVER	42
63 #define DHCPV4_OPTIONS_VENDOR_SPECIFIC	43
64 #define DHCPV4_OPTIONS_REQ_IPADDR	50
65 #define DHCPV4_OPTIONS_LEASE_TIME	51
66 #define DHCPV4_OPTIONS_MSG_TYPE		53
67 #define DHCPV4_OPTIONS_SERVER_ID	54
68 #define DHCPV4_OPTIONS_REQ_LIST		55
69 #define DHCPV4_OPTIONS_RENEWAL		58
70 #define DHCPV4_OPTIONS_REBINDING	59
71 #define DHCPV4_OPTIONS_VENDOR_CLASS_ID	60
72 #define DHCPV4_OPTIONS_CLIENT_ID	61
73 #define DHCPV4_OPTIONS_END		255
74 
75 /* Useful size macros */
76 #define DHCPV4_OLV_MSG_HOST_NAME	2
77 #define DHCPV4_OLV_MSG_VENDOR_CLASS_ID	2
78 #define DHCPV4_OLV_MSG_REQ_IPADDR	6
79 #define DHCPV4_OLV_MSG_TYPE_SIZE	3
80 #define DHCPV4_OLV_MSG_SERVER_ID	6
81 #define DHCPV4_OLV_MSG_REQ_LIST		2
82 
83 #define DHCPV4_OLV_END_SIZE		1
84 
85 #define DHCPV4_MESSAGE_SIZE		(sizeof(struct dhcp_msg) +	\
86 					 SIZE_OF_SNAME + SIZE_OF_FILE + \
87 					 SIZE_OF_MAGIC_COOKIE +		\
88 					 DHCPV4_OLV_MSG_TYPE_SIZE +	\
89 					 DHCPV4_OLV_END_SIZE)
90 
91 
92 /* Maximum number of REQUEST retransmits before reverting to DISCOVER. */
93 #define DHCPV4_MAX_NUMBER_OF_ATTEMPTS	3
94 
95 /* Initial message retry timeout (s).  This timeout increases
96  * exponentially on each retransmit.
97  * RFC2131 4.1
98  */
99 #define DHCPV4_INITIAL_RETRY_TIMEOUT 4
100 
101 /* Initial minimum delay in INIT state before sending the
102  * initial DISCOVER message. MAx value is defined with
103  * CONFIG_NET_DHCPV4_INITIAL_DELAY_MAX. Default max value
104  * should be 10.
105  * RFC2131 4.1.1
106  */
107 #define DHCPV4_INITIAL_DELAY_MIN 1
108 
109 /* Minimum retransmission timeout in RENEW and REBIND states (in seconds).
110  * RFC2131 4.4.5
111  */
112 #define DHCPV4_RENEW_REBIND_TIMEOUT_MIN 60
113 
114 #if defined(CONFIG_NET_DHCPV4)
115 
116 int net_dhcpv4_init(void);
117 
118 #else
119 
120 #define net_dhcpv4_init() 0
121 
122 #endif /* CONFIG_NET_DHCPV4 */
123 
124 #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_DHCPV4_ACCEPT_UNICAST)
125 
126 /**
127  * @brief Verify if the incoming packet should be accepted for the DHCPv4
128  *        module to process.
129  *
130  * In case server responds with an unicast IP packet, the IP stack needs to
131  * pass it through for the DHCPv4 module to process, before the actual
132  * destination IP address is configured on an interface.
133  * This function allows to determine whether there is an active DHCPv4 query on
134  * the interface and the packet is destined for the DHCPv4 module to process.
135  *
136  * @param pkt A packet to analyze
137  *
138  * @return true if the packet shall be accepted, false otherwise
139  */
140 bool net_dhcpv4_accept_unicast(struct net_pkt *pkt);
141 
142 #else
143 
net_dhcpv4_accept_unicast(struct net_pkt * pkt)144 static inline bool net_dhcpv4_accept_unicast(struct net_pkt *pkt)
145 {
146 	ARG_UNUSED(pkt);
147 
148 	return false;
149 }
150 
151 #endif /* CONFIG_NET_DHCPV4 && CONFIG_NET_DHCPV4_ACCEPT_UNICAST */
152 
153 #if defined(CONFIG_NET_DHCPV4_SERVER)
154 
155 void net_dhcpv4_server_init(void);
156 
157 #else
158 
159 #define net_dhcpv4_server_init()
160 
161 #endif /* CONFIG_NET_DHCPV4_SERVER */
162 
163 #endif /* __INTERNAL_DHCPV4_H */
164