]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-network/test-dhcp-server.c
hwdb: Add accelerometer orientation quirk for the PoV TAB-P1006W-232-3G
[thirdparty/systemd.git] / src / libsystemd-network / test-dhcp-server.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
b44cd882 2/***
810adae9 3 Copyright © 2013 Intel Corporation. All rights reserved.
b44cd882
TG
4***/
5
b44cd882
TG
6#include <errno.h>
7
07630cea 8#include "sd-dhcp-server.h"
b44cd882 9#include "sd-event.h"
b44cd882 10
b44cd882 11#include "dhcp-server-internal.h"
317bb217 12#include "tests.h"
b44cd882 13
99634696 14static void test_pool(struct in_addr *address, unsigned size, int ret) {
4afd3348 15 _cleanup_(sd_dhcp_server_unrefp) sd_dhcp_server *server = NULL;
99634696
TG
16
17 assert_se(sd_dhcp_server_new(&server, 1) >= 0);
18
19 assert_se(sd_dhcp_server_configure_pool(server, address, 8, 0, size) == ret);
20}
21
6f08fb7b 22static int test_basic(sd_event *event) {
4afd3348 23 _cleanup_(sd_dhcp_server_unrefp) sd_dhcp_server *server = NULL;
20af7091
TG
24 struct in_addr address_lo = {
25 .s_addr = htonl(INADDR_LOOPBACK),
26 };
27 struct in_addr address_any = {
28 .s_addr = htonl(INADDR_ANY),
29 };
6f08fb7b 30 int r;
b44cd882 31
3a864fe4
TG
32 /* attach to loopback interface */
33 assert_se(sd_dhcp_server_new(&server, 1) >= 0);
b44cd882
TG
34 assert_se(server);
35
36 assert_se(sd_dhcp_server_attach_event(server, event, 0) >= 0);
37 assert_se(sd_dhcp_server_attach_event(server, event, 0) == -EBUSY);
38 assert_se(sd_dhcp_server_get_event(server) == event);
39 assert_se(sd_dhcp_server_detach_event(server) >= 0);
40 assert_se(!sd_dhcp_server_get_event(server));
41 assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0);
42 assert_se(sd_dhcp_server_attach_event(server, NULL, 0) == -EBUSY);
43
44 assert_se(sd_dhcp_server_ref(server) == server);
45 assert_se(!sd_dhcp_server_unref(server));
ff734080 46
20af7091 47 assert_se(sd_dhcp_server_start(server) == -EUNATCH);
20af7091 48
99634696
TG
49 assert_se(sd_dhcp_server_configure_pool(server, &address_any, 28, 0, 0) == -EINVAL);
50 assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 38, 0, 0) == -ERANGE);
51 assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
45a9eac9 52 assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
99634696
TG
53
54 test_pool(&address_any, 1, -EINVAL);
55 test_pool(&address_lo, 1, 0);
2dead812 56
6f08fb7b 57 r = sd_dhcp_server_start(server);
6f08fb7b 58 if (r == -EPERM)
08d541ca 59 return log_info_errno(r, "sd_dhcp_server_start failed: %m");
6f08fb7b
TG
60 assert_se(r >= 0);
61
ff734080
TG
62 assert_se(sd_dhcp_server_start(server) == -EBUSY);
63 assert_se(sd_dhcp_server_stop(server) >= 0);
64 assert_se(sd_dhcp_server_stop(server) >= 0);
65 assert_se(sd_dhcp_server_start(server) >= 0);
6f08fb7b
TG
66
67 return 0;
b44cd882
TG
68}
69
be077570 70static void test_message_handler(void) {
4afd3348 71 _cleanup_(sd_dhcp_server_unrefp) sd_dhcp_server *server = NULL;
be077570
TG
72 struct {
73 DHCPMessage message;
74 struct {
75 uint8_t code;
76 uint8_t length;
77 uint8_t type;
78 } _packed_ option_type;
2dead812
TG
79 struct {
80 uint8_t code;
81 uint8_t length;
82 be32_t address;
83 } _packed_ option_requested_ip;
84 struct {
85 uint8_t code;
86 uint8_t length;
87 be32_t address;
88 } _packed_ option_server_id;
87322b3a
TG
89 struct {
90 uint8_t code;
91 uint8_t length;
92 uint8_t id[7];
93 } _packed_ option_client_id;
be077570
TG
94 uint8_t end;
95 } _packed_ test = {
96 .message.op = BOOTREQUEST,
97 .message.htype = ARPHRD_ETHER,
98 .message.hlen = ETHER_ADDR_LEN,
2dead812
TG
99 .message.xid = htobe32(0x12345678),
100 .message.chaddr = { 'A', 'B', 'C', 'D', 'E', 'F' },
22805d92 101 .option_type.code = SD_DHCP_OPTION_MESSAGE_TYPE,
be077570
TG
102 .option_type.length = 1,
103 .option_type.type = DHCP_DISCOVER,
22805d92 104 .end = SD_DHCP_OPTION_END,
be077570 105 };
20af7091
TG
106 struct in_addr address_lo = {
107 .s_addr = htonl(INADDR_LOOPBACK),
108 };
be077570
TG
109
110 assert_se(sd_dhcp_server_new(&server, 1) >= 0);
99634696 111 assert_se(sd_dhcp_server_configure_pool(server, &address_lo, 8, 0, 0) >= 0);
20af7091
TG
112 assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0);
113 assert_se(sd_dhcp_server_start(server) >= 0);
be077570 114
4dc35568 115 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
be077570
TG
116
117 test.end = 0;
118 /* TODO, shouldn't this fail? */
4dc35568 119 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
22805d92 120 test.end = SD_DHCP_OPTION_END;
4dc35568 121 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
be077570
TG
122
123 test.option_type.code = 0;
124 test.option_type.length = 0;
125 test.option_type.type = 0;
126 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
22805d92 127 test.option_type.code = SD_DHCP_OPTION_MESSAGE_TYPE;
be077570
TG
128 test.option_type.length = 1;
129 test.option_type.type = DHCP_DISCOVER;
4dc35568 130 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
be077570
TG
131
132 test.message.op = 0;
133 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
134 test.message.op = BOOTREQUEST;
4dc35568 135 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
be077570
TG
136
137 test.message.htype = 0;
138 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
139 test.message.htype = ARPHRD_ETHER;
4dc35568 140 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
be077570
TG
141
142 test.message.hlen = 0;
143 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
144 test.message.hlen = ETHER_ADDR_LEN;
4dc35568 145 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
2dead812
TG
146
147 test.option_type.type = DHCP_REQUEST;
148 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
22805d92 149 test.option_requested_ip.code = SD_DHCP_OPTION_REQUESTED_IP_ADDRESS;
2dead812
TG
150 test.option_requested_ip.length = 4;
151 test.option_requested_ip.address = htobe32(0x12345678);
bd57b450 152 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_NAK);
22805d92 153 test.option_server_id.code = SD_DHCP_OPTION_SERVER_IDENTIFIER;
2dead812
TG
154 test.option_server_id.length = 4;
155 test.option_server_id.address = htobe32(INADDR_LOOPBACK);
156 test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
157 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);
87322b3a 158
2dead812
TG
159 test.option_server_id.address = htobe32(0x12345678);
160 test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
161 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
bd57b450 162 test.option_server_id.address = htobe32(INADDR_LOOPBACK);
87322b3a
TG
163 test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 4);
164 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
165 test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
166 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);
167
22805d92 168 test.option_client_id.code = SD_DHCP_OPTION_CLIENT_IDENTIFIER;
87322b3a
TG
169 test.option_client_id.length = 7;
170 test.option_client_id.id[0] = 0x01;
171 test.option_client_id.id[1] = 'A';
172 test.option_client_id.id[2] = 'B';
173 test.option_client_id.id[3] = 'C';
174 test.option_client_id.id[4] = 'D';
175 test.option_client_id.id[5] = 'E';
176 test.option_client_id.id[6] = 'F';
177 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);
178
bd57b450 179 test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 30);
2dead812 180 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
be077570
TG
181}
182
b826ab58
TG
183static uint64_t client_id_hash_helper(DHCPClientId *id, uint8_t key[HASH_KEY_SIZE]) {
184 struct siphash state;
185
0cb3c286 186 siphash24_init(&state, key);
b826ab58 187 client_id_hash_func(id, &state);
0cb3c286 188
933f9cae 189 return htole64(siphash24_finalize(&state));
b826ab58
TG
190}
191
87322b3a
TG
192static void test_client_id_hash(void) {
193 DHCPClientId a = {
194 .length = 4,
195 }, b = {
196 .length = 4,
197 };
198 uint8_t hash_key[HASH_KEY_SIZE] = {
199 '0', '1', '2', '3', '4', '5', '6', '7',
200 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
201 };
202
203 a.data = (uint8_t*)strdup("abcd");
204 b.data = (uint8_t*)strdup("abcd");
205
206 assert_se(client_id_compare_func(&a, &b) == 0);
b826ab58 207 assert_se(client_id_hash_helper(&a, hash_key) == client_id_hash_helper(&b, hash_key));
87322b3a
TG
208 a.length = 3;
209 assert_se(client_id_compare_func(&a, &b) != 0);
210 a.length = 4;
211 assert_se(client_id_compare_func(&a, &b) == 0);
b826ab58 212 assert_se(client_id_hash_helper(&a, hash_key) == client_id_hash_helper(&b, hash_key));
87322b3a
TG
213
214 b.length = 3;
215 assert_se(client_id_compare_func(&a, &b) != 0);
216 b.length = 4;
217 assert_se(client_id_compare_func(&a, &b) == 0);
b826ab58 218 assert_se(client_id_hash_helper(&a, hash_key) == client_id_hash_helper(&b, hash_key));
87322b3a
TG
219
220 free(b.data);
221 b.data = (uint8_t*)strdup("abce");
222 assert_se(client_id_compare_func(&a, &b) != 0);
223
224 free(a.data);
225 free(b.data);
226}
227
b44cd882 228int main(int argc, char *argv[]) {
4afd3348 229 _cleanup_(sd_event_unrefp) sd_event *e;
6f08fb7b 230 int r;
b44cd882 231
6d7c4033 232 test_setup_logging(LOG_DEBUG);
b44cd882
TG
233
234 assert_se(sd_event_new(&e) >= 0);
235
6f08fb7b 236 r = test_basic(e);
317bb217
ZJS
237 if (r != 0)
238 return log_tests_skipped("cannot start dhcp server");
6f08fb7b 239
be077570 240 test_message_handler();
87322b3a 241 test_client_id_hash();
b44cd882
TG
242
243 return 0;
244}