]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/dhcp/dhcp-UseMulticast.patch
aarch64: Fix rootfile for Python
[ipfire-2.x.git] / src / patches / dhcp / dhcp-UseMulticast.patch
CommitLineData
c1e9ba67
MF
1diff -up dhcp-4.3.1b1/server/dhcpv6.c.UseMulticast dhcp-4.3.1b1/server/dhcpv6.c
2--- dhcp-4.3.1b1/server/dhcpv6.c.UseMulticast 2014-07-02 19:58:40.000000000 +0200
3+++ dhcp-4.3.1b1/server/dhcpv6.c 2014-07-10 18:20:03.066256219 +0200
4@@ -376,6 +376,48 @@ generate_new_server_duid(void) {
78ab9b04
MT
5 }
6
7 /*
8+ * Is the D6O_UNICAST option defined in dhcpd.conf ?
9+ */
10+static isc_boolean_t unicast_option_defined;
11+
12+/*
13+ * Did we already search dhcpd.conf for D6O_UNICAST option ?
14+ * We need to store it here to not parse dhcpd.conf repeatedly.
15+ */
16+static isc_boolean_t unicast_option_parsed = ISC_FALSE;
17+
18+
19+/*
20+ * Is the D6O_UNICAST option defined in dhcpd.conf ?
21+ */
22+isc_boolean_t
23+is_unicast_option_defined(void) {
24+ struct option_state *opt_state;
25+ struct option_cache *oc;
26+
27+ /*
28+ * If we are looking for the unicast option for the first time
29+ */
30+ if (unicast_option_parsed == ISC_FALSE) {
31+ unicast_option_parsed = ISC_TRUE;
32+ opt_state = NULL;
33+ if (!option_state_allocate(&opt_state, MDL)) {
34+ log_fatal("No memory for option state.");
35+ }
36+
37+ execute_statements_in_scope(NULL, NULL, NULL, NULL, NULL,
c1e9ba67 38+ opt_state, &global_scope, root_group, NULL, NULL);
78ab9b04
MT
39+
40+ oc = lookup_option(&dhcpv6_universe, opt_state, D6O_UNICAST);
41+ unicast_option_defined = (oc != NULL);
42+
43+ option_state_dereference(&opt_state, MDL);
44+ }
45+
46+ return (unicast_option_defined);
47+}
48+
49+/*
50 * Get the client identifier from the packet.
51 */
52 isc_result_t
c1e9ba67
MF
53@@ -706,6 +748,12 @@ static const int required_opts[] = {
54 D6O_PREFERENCE,
55 0
56 };
57+static const int required_opts_NAA[] = {
58+ D6O_CLIENTID,
59+ D6O_SERVERID,
60+ D6O_STATUS_CODE,
61+ 0
62+};
63 static const int required_opts_solicit[] = {
64 D6O_CLIENTID,
65 D6O_SERVERID,
66@@ -1587,6 +1635,56 @@ lease_to_client(struct data_string *repl
67 reply.shared->group, NULL);
78ab9b04
MT
68 }
69
70+ /* reject unicast message, unless we set unicast option */
71+ if ((packet->unicast == ISC_TRUE) && !is_unicast_option_defined())
72+ /*
73+ * RFC3315 section 18.2.1 (Request):
74+ *
75+ * When the server receives a Request message via unicast from a client
76+ * to which the server has not sent a unicast option, the server
77+ * discards the Request message and responds with a Reply message
78+ * containing a Status Code option with the value UseMulticast, a Server
79+ * Identifier option containing the server's DUID, the Client Identifier
80+ * option from the client message, and no other options.
81+ *
82+ * Section 18.2.3 (Renew):
83+ *
84+ * When the server receives a Renew message via unicast from a client to
85+ * which the server has not sent a unicast option, the server discards
86+ * the Renew message and responds with a Reply message containing a
87+ * Status Code option with the value UseMulticast, a Server Identifier
88+ * option containing the server's DUID, the Client Identifier option
89+ * from the client message, and no other options.
90+ */
91+ {
92+ /* Set the UseMulticast status code. */
93+ if (!set_status_code(STATUS_UseMulticast,
94+ "Unicast not allowed by server.",
95+ reply.opt_state)) {
96+ log_error("lease_to_client: Unable to set "
97+ "UseMulticast status code.");
98+ goto exit;
99+ }
100+
101+ /* Rewind the cursor to the start. */
102+ reply.cursor = REPLY_OPTIONS_INDEX;
103+
104+ /*
105+ * Produce an reply that includes only:
106+ *
107+ * Status code.
108+ * Server DUID.
109+ * Client DUID.
110+ */
111+ reply.cursor += store_options6((char *)reply.buf.data +
112+ reply.cursor,
113+ sizeof(reply.buf) -
114+ reply.cursor,
115+ reply.opt_state, reply.packet,
116+ required_opts_NAA,
117+ NULL);
c1e9ba67
MF
118+ }
119+
78ab9b04
MT
120 /*
121 * RFC3315 section 17.2.2 (Solicit):
122 *
c1e9ba67
MF
123@@ -1619,6 +1717,7 @@ lease_to_client(struct data_string *repl
124 * Having stored the client's IA's, store any options that
125 * will fit in the remaining space.
78ab9b04 126 */
c1e9ba67
MF
127+ else
128 reply.cursor += store_options6((char *)reply.buf.data + reply.cursor,
129 sizeof(reply.buf) - reply.cursor,
130 reply.opt_state, reply.packet,
131@@ -4748,7 +4847,6 @@ dhcpv6_solicit(struct data_string *reply
78ab9b04
MT
132 * Very similar to Solicit handling, except the server DUID is required.
133 */
134
135-/* TODO: reject unicast messages, unless we set unicast option */
136 static void
137 dhcpv6_request(struct data_string *reply_ret, struct packet *packet) {
138 struct data_string client_id;
c1e9ba67 139@@ -5078,7 +5176,6 @@ exit:
78ab9b04
MT
140 * except for the error code of when addresses don't match.
141 */
142
143-/* TODO: reject unicast messages, unless we set unicast option */
144 static void
145 dhcpv6_renew(struct data_string *reply, struct packet *packet) {
146 struct data_string client_id;
c1e9ba67 147@@ -5322,18 +5419,60 @@ iterate_over_ia_na(struct data_string *r
78ab9b04
MT
148 goto exit;
149 }
150
151- snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
152- if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
153- goto exit;
154- }
155+ /* reject unicast message, unless we set unicast option */
156+ if ((packet->unicast == ISC_TRUE) && !is_unicast_option_defined()) {
157+ /*
158+ * RFC3315 section 18.2.6 (Release):
159+ *
160+ * When the server receives a Release message via unicast from a client
161+ * to which the server has not sent a unicast option, the server
162+ * discards the Release message and responds with a Reply message
163+ * containing a Status Code option with value UseMulticast, a Server
164+ * Identifier option containing the server's DUID, the Client Identifier
165+ * option from the client message, and no other options.
166+ *
167+ * Section 18.2.7 (Decline):
168+ *
169+ * When the server receives a Decline message via unicast from a client
170+ * to which the server has not sent a unicast option, the server
171+ * discards the Decline message and responds with a Reply message
172+ * containing a Status Code option with the value UseMulticast, a Server
173+ * Identifier option containing the server's DUID, the Client Identifier
174+ * option from the client message, and no other options.
175+ */
176+ snprintf(status_msg, sizeof(status_msg),
177+ "%s received unicast.", packet_type);
178+ if (!set_status_code(STATUS_UseMulticast, status_msg, opt_state)) {
179+ goto exit;
180+ }
181
182- /*
183- * Add our options that are not associated with any IA_NA or IA_TA.
184- */
185- reply_ofs += store_options6(reply_data+reply_ofs,
186- sizeof(reply_data)-reply_ofs,
187+ /*
188+ * Produce an reply that includes only:
189+ *
190+ * Status code.
191+ * Server DUID.
192+ * Client DUID.
193+ */
194+ reply_ofs += store_options6(reply_data+reply_ofs,
195+ sizeof(reply_data)-reply_ofs,
196 opt_state, packet,
197- required_opts, NULL);
198+ required_opts_NAA, NULL);
199+
200+ goto return_reply;
201+ } else {
202+ snprintf(status_msg, sizeof(status_msg), "%s received.", packet_type);
203+ if (!set_status_code(STATUS_Success, status_msg, opt_state)) {
204+ goto exit;
205+ }
206+
207+ /*
208+ * Add our options that are not associated with any IA_NA or IA_TA.
209+ */
210+ reply_ofs += store_options6(reply_data+reply_ofs,
211+ sizeof(reply_data)-reply_ofs,
212+ opt_state, packet,
213+ required_opts, NULL);
214+ }
215
216 /*
217 * Loop through the IA_NA reported by the client, and deal with
c1e9ba67 218@@ -5471,6 +5610,7 @@ iterate_over_ia_na(struct data_string *r
78ab9b04
MT
219 /*
220 * Return our reply to the caller.
221 */
222+return_reply:
223 reply_ret->len = reply_ofs;
224 reply_ret->buffer = NULL;
225 if (!buffer_allocate(&reply_ret->buffer, reply_ofs, MDL)) {
c1e9ba67 226@@ -5516,7 +5656,6 @@ exit:
78ab9b04
MT
227 * we still need to be aware of this possibility.
228 */
229
230-/* TODO: reject unicast messages, unless we set unicast option */
231 /* TODO: IA_TA */
232 static void
233 dhcpv6_decline(struct data_string *reply, struct packet *packet) {
c1e9ba67 234@@ -5986,7 +6125,6 @@ exit:
78ab9b04
MT
235 * Release means a client is done with the leases.
236 */
237
238-/* TODO: reject unicast messages, unless we set unicast option */
239 static void
240 dhcpv6_release(struct data_string *reply, struct packet *packet) {
241 struct data_string client_id;