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_HOST_NAME	12
58 #define DHCPV4_OPTIONS_REQ_IPADDR	50
59 #define DHCPV4_OPTIONS_LEASE_TIME	51
60 #define DHCPV4_OPTIONS_MSG_TYPE		53
61 #define DHCPV4_OPTIONS_SERVER_ID	54
62 #define DHCPV4_OPTIONS_REQ_LIST		55
63 #define DHCPV4_OPTIONS_RENEWAL		58
64 #define DHCPV4_OPTIONS_REBINDING	59
65 #define DHCPV4_OPTIONS_END		255
66 
67 /* Useful size macros */
68 #define DHCPV4_OLV_MSG_HOST_NAME	2
69 #define DHCPV4_OLV_MSG_REQ_IPADDR	6
70 #define DHCPV4_OLV_MSG_TYPE_SIZE	3
71 #define DHCPV4_OLV_MSG_SERVER_ID	6
72 #define DHCPV4_OLV_MSG_REQ_LIST		5
73 
74 #define DHCPV4_OLV_END_SIZE		1
75 
76 #define DHCPV4_MESSAGE_SIZE		(sizeof(struct dhcp_msg) +	\
77 					 SIZE_OF_SNAME + SIZE_OF_FILE + \
78 					 SIZE_OF_MAGIC_COOKIE +		\
79 					 DHCPV4_OLV_MSG_TYPE_SIZE +	\
80 					 DHCPV4_OLV_END_SIZE)
81 
82 
83 /* TODO:
84  * 1) Support T2(Rebind) timer.
85  */
86 
87 /* Maximum number of REQUEST or RENEWAL retransmits before reverting
88  * to DISCOVER.
89  */
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 #if defined(CONFIG_NET_DHCPV4)
107 
108 int net_dhcpv4_init(void);
109 
110 #else
111 
112 #define net_dhcpv4_init() 0
113 
114 #endif /* CONFIG_NET_DHCPV4 */
115 
116 #if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_DHCPV4_ACCEPT_UNICAST)
117 
118 /**
119  * @brief Verify if the incoming packet should be accepted for the DHCPv4
120  *        module to process.
121  *
122  * In case server responds with an unicast IP packet, the IP stack needs to
123  * pass it through for the DHCPv4 module to process, before the actual
124  * destination IP address is configured on an interface.
125  * This function allows to determine whether there is an active DHCPv4 query on
126  * the interface and the packet is destined for the DHCPv4 module to process.
127  *
128  * @param pkt A packet to analyze
129  *
130  * @return true if the packet shall be accepted, false otherwise
131  */
132 bool net_dhcpv4_accept_unicast(struct net_pkt *pkt);
133 
134 #else
135 
net_dhcpv4_accept_unicast(struct net_pkt * pkt)136 static inline bool net_dhcpv4_accept_unicast(struct net_pkt *pkt)
137 {
138 	ARG_UNUSED(pkt);
139 
140 	return false;
141 }
142 
143 #endif /* CONFIG_NET_DHCPV4 && CONFIG_NET_DHCPV4_ACCEPT_UNICAST */
144 
145 #endif /* __INTERNAL_DHCPV4_H */
146