1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright (C) 2013 Intel Corporation. All rights reserved.
7 Copyright (C) 2014 Tom Gundersen
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <netinet/if_ether.h>
28 #include "event-util.h"
30 #include "sd-dhcp-server.h"
31 #include "dhcp-server-internal.h"
33 static void test_basic(sd_event *event) {
34 _cleanup_dhcp_server_unref_ sd_dhcp_server *server = NULL;
35 struct in_addr address_lo = {
36 .s_addr = htonl(INADDR_LOOPBACK),
38 struct in_addr address_any = {
39 .s_addr = htonl(INADDR_ANY),
42 /* attach to loopback interface */
43 assert_se(sd_dhcp_server_new(&server, 1) >= 0);
46 assert_se(sd_dhcp_server_attach_event(server, event, 0) >= 0);
47 assert_se(sd_dhcp_server_attach_event(server, event, 0) == -EBUSY);
48 assert_se(sd_dhcp_server_get_event(server) == event);
49 assert_se(sd_dhcp_server_detach_event(server) >= 0);
50 assert_se(!sd_dhcp_server_get_event(server));
51 assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0);
52 assert_se(sd_dhcp_server_attach_event(server, NULL, 0) == -EBUSY);
54 assert_se(sd_dhcp_server_ref(server) == server);
55 assert_se(!sd_dhcp_server_unref(server));
57 assert_se(sd_dhcp_server_start(server) == -EUNATCH);
58 assert_se(sd_dhcp_server_set_address(server, &address_any) == -EINVAL);
59 assert_se(sd_dhcp_server_set_address(server, &address_lo) >= 0);
60 assert_se(sd_dhcp_server_set_address(server, &address_lo) == -EBUSY);
62 assert_se(sd_dhcp_server_set_lease_pool(server, &address_any, 1) == -EINVAL);
63 assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 0) == -EINVAL);
64 assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 1) >= 0);
65 assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 1) == -EBUSY);
67 assert_se(sd_dhcp_server_start(server) >= 0);
68 assert_se(sd_dhcp_server_start(server) == -EBUSY);
69 assert_se(sd_dhcp_server_stop(server) >= 0);
70 assert_se(sd_dhcp_server_stop(server) >= 0);
71 assert_se(sd_dhcp_server_start(server) >= 0);
74 static void test_message_handler(void) {
75 _cleanup_dhcp_server_unref_ sd_dhcp_server *server = NULL;
82 } _packed_ option_type;
87 } _packed_ option_requested_ip;
92 } _packed_ option_server_id;
95 .message.op = BOOTREQUEST,
96 .message.htype = ARPHRD_ETHER,
97 .message.hlen = ETHER_ADDR_LEN,
98 .message.xid = htobe32(0x12345678),
99 .message.chaddr = { 'A', 'B', 'C', 'D', 'E', 'F' },
100 .option_type.code = DHCP_OPTION_MESSAGE_TYPE,
101 .option_type.length = 1,
102 .option_type.type = DHCP_DISCOVER,
103 .end = DHCP_OPTION_END,
105 struct in_addr address_lo = {
106 .s_addr = htonl(INADDR_LOOPBACK),
109 assert_se(sd_dhcp_server_new(&server, 1) >= 0);
110 assert_se(sd_dhcp_server_set_address(server, &address_lo) >= 0);
111 assert_se(sd_dhcp_server_attach_event(server, NULL, 0) >= 0);
112 assert_se(sd_dhcp_server_start(server) >= 0);
114 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
115 assert_se(sd_dhcp_server_set_lease_pool(server, &address_lo, 10) >= 0);
116 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
119 /* TODO, shouldn't this fail? */
120 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
121 test.end = DHCP_OPTION_END;
122 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
124 test.option_type.code = 0;
125 test.option_type.length = 0;
126 test.option_type.type = 0;
127 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
128 test.option_type.code = DHCP_OPTION_MESSAGE_TYPE;
129 test.option_type.length = 1;
130 test.option_type.type = DHCP_DISCOVER;
131 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
134 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
135 test.message.op = BOOTREQUEST;
136 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
138 test.message.htype = 0;
139 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
140 test.message.htype = ARPHRD_ETHER;
141 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
143 test.message.hlen = 0;
144 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
145 test.message.hlen = ETHER_ADDR_LEN;
146 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_OFFER);
148 test.option_type.type = DHCP_REQUEST;
149 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
150 test.option_requested_ip.code = DHCP_OPTION_REQUESTED_IP_ADDRESS;
151 test.option_requested_ip.length = 4;
152 test.option_requested_ip.address = htobe32(0x12345678);
153 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_NAK);
154 test.option_server_id.code = DHCP_OPTION_SERVER_IDENTIFIER;
155 test.option_server_id.length = 4;
156 test.option_server_id.address = htobe32(INADDR_LOOPBACK);
157 test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 3);
158 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == DHCP_ACK);
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);
162 test.option_server_id.address = htobe32(INADDR_LOOPBACK);
163 test.option_requested_ip.address = htobe32(INADDR_LOOPBACK + 30);
164 assert_se(dhcp_server_handle_message(server, (DHCPMessage*)&test, sizeof(test)) == 0);
167 int main(int argc, char *argv[]) {
168 _cleanup_event_unref_ sd_event *e;
170 log_set_max_level(LOG_DEBUG);
171 log_parse_environment();
174 assert_se(sd_event_new(&e) >= 0);
177 test_message_handler();