]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-dhcp/test-dhcp-client.c
libsystemd-dhcp: Add capability to print out test steps
[thirdparty/systemd.git] / src / libsystemd-dhcp / test-dhcp-client.c
CommitLineData
be391925
PF
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright (C) 2013 Intel Corporation. All rights reserved.
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include <stdlib.h>
23#include <assert.h>
24#include <errno.h>
39b7f596 25#include <stdio.h>
8c00042c
PF
26#include <sys/types.h>
27#include <sys/socket.h>
28#include <unistd.h>
be391925 29
290c7324 30#include "util.h"
8c00042c 31#include "socket-util.h"
290c7324 32
be391925 33#include "dhcp-protocol.h"
290c7324 34#include "dhcp-internal.h"
be391925
PF
35#include "sd-dhcp-client.h"
36
290c7324
PF
37static struct ether_addr mac_addr = {
38 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}
39};
40
ede286f9 41static bool verbose = false;
8c00042c
PF
42static int test_fd[2];
43
d3d8ac2f 44static void test_request_basic(sd_event *e)
be391925 45{
b25ef18b
TG
46 int r;
47
be391925
PF
48 sd_dhcp_client *client;
49
ede286f9
PF
50 if (verbose)
51 printf("* %s\n", __FUNCTION__);
52
b25ef18b 53 r = sd_dhcp_client_new(&client);
be391925 54
b25ef18b 55 assert(r >= 0);
be391925
PF
56 assert(client);
57
b25ef18b
TG
58 r = sd_dhcp_client_attach_event(client, e, 0);
59 assert(r >= 0);
60
be391925
PF
61 assert(sd_dhcp_client_set_request_option(NULL, 0) == -EINVAL);
62 assert(sd_dhcp_client_set_request_address(NULL, NULL) == -EINVAL);
63 assert(sd_dhcp_client_set_index(NULL, 0) == -EINVAL);
64
65 assert(sd_dhcp_client_set_index(client, 15) == 0);
66 assert(sd_dhcp_client_set_index(client, -42) == -EINVAL);
67 assert(sd_dhcp_client_set_index(client, -1) == 0);
68
69 assert(sd_dhcp_client_set_request_option(client,
70 DHCP_OPTION_SUBNET_MASK) == -EEXIST);
71 assert(sd_dhcp_client_set_request_option(client,
72 DHCP_OPTION_ROUTER) == -EEXIST);
73 assert(sd_dhcp_client_set_request_option(client,
74 DHCP_OPTION_HOST_NAME) == -EEXIST);
75 assert(sd_dhcp_client_set_request_option(client,
76 DHCP_OPTION_DOMAIN_NAME) == -EEXIST);
77 assert(sd_dhcp_client_set_request_option(client,
78 DHCP_OPTION_DOMAIN_NAME_SERVER)
79 == -EEXIST);
80 assert(sd_dhcp_client_set_request_option(client,
81 DHCP_OPTION_NTP_SERVER) == -EEXIST);
82
83 assert(sd_dhcp_client_set_request_option(client,
84 DHCP_OPTION_PAD) == -EINVAL);
85 assert(sd_dhcp_client_set_request_option(client,
86 DHCP_OPTION_END) == -EINVAL);
87 assert(sd_dhcp_client_set_request_option(client,
88 DHCP_OPTION_MESSAGE_TYPE) == -EINVAL);
89 assert(sd_dhcp_client_set_request_option(client,
90 DHCP_OPTION_OVERLOAD) == -EINVAL);
91 assert(sd_dhcp_client_set_request_option(client,
92 DHCP_OPTION_PARAMETER_REQUEST_LIST)
93 == -EINVAL);
94
95 assert(sd_dhcp_client_set_request_option(client, 33) == 0);
96 assert(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
97 assert(sd_dhcp_client_set_request_option(client, 44) == 0);
7a7c74ca 98 assert(sd_dhcp_client_set_request_option(client, 33) == -EEXIST);
be391925
PF
99}
100
39b7f596
PF
101static uint16_t client_checksum(void *buf, int len)
102{
103 uint32_t sum;
104 uint16_t *check;
105 int i;
106 uint8_t *odd;
107
108 sum = 0;
109 check = buf;
110
111 for (i = 0; i < len / 2 ; i++)
112 sum += check[i];
113
114 if (len & 0x01) {
115 odd = buf;
0c6a3c88 116 sum += odd[len - 1];
39b7f596
PF
117 }
118
0c6a3c88
PF
119 while (sum >> 16)
120 sum = (sum & 0xffff) + (sum >> 16);
121
122 return ~sum;
39b7f596
PF
123}
124
125static void test_checksum(void)
126{
127 uint8_t buf[20] = {
128 0x45, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x00,
129 0x40, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
130 0xff, 0xff, 0xff, 0xff
131 };
132
ede286f9
PF
133 if (verbose)
134 printf("* %s\n", __FUNCTION__);
135
2fba7b03 136 assert(client_checksum(&buf, 20) == be16toh(0x78ae));
39b7f596
PF
137}
138
290c7324
PF
139static int check_options(uint8_t code, uint8_t len, const uint8_t *option,
140 void *user_data)
141{
142 return 0;
143}
144
8c00042c
PF
145int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link,
146 const void *packet, size_t len)
290c7324
PF
147{
148 size_t size;
149 _cleanup_free_ DHCPPacket *discover;
150 uint16_t ip_check, udp_check;
151 int res;
152
8c00042c 153 assert(s >= 0);
290c7324
PF
154 assert(packet);
155
156 size = sizeof(DHCPPacket) + 4;
157 assert(len > size);
158
159 discover = memdup(packet, len);
160
161 assert(memcmp(discover->dhcp.chaddr,
162 &mac_addr.ether_addr_octet, 6) == 0);
163 assert(discover->ip.ttl == IPDEFTTL);
164 assert(discover->ip.protocol == IPPROTO_UDP);
165 assert(discover->ip.saddr == INADDR_ANY);
166 assert(discover->ip.daddr == INADDR_BROADCAST);
8c00042c
PF
167 assert(discover->udp.source == be16toh(DHCP_PORT_CLIENT));
168 assert(discover->udp.dest == be16toh(DHCP_PORT_SERVER));
290c7324
PF
169
170 ip_check = discover->ip.check;
171
172 discover->ip.ttl = 0;
173 discover->ip.check = discover->udp.len;
174
175 udp_check = ~client_checksum(&discover->ip.ttl, len - 8);
176 assert(udp_check == 0xffff);
177
178 discover->ip.ttl = IPDEFTTL;
179 discover->ip.check = ip_check;
180
181 ip_check = ~client_checksum(&discover->ip, sizeof(discover->ip));
182 assert(ip_check == 0xffff);
183
184 size = len - sizeof(struct iphdr) - sizeof(struct udphdr);
185
186 res = dhcp_option_parse(&discover->dhcp, size, check_options, NULL);
187 if (res < 0)
188 return res;
189
190 return 575;
191}
192
8c00042c
PF
193int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link)
194{
195 if (socketpair(AF_UNIX, SOCK_STREAM, 0, test_fd) < 0)
196 return -errno;
197
198 return test_fd[0];
199}
200
080ab276 201int dhcp_network_bind_udp_socket(int index, be32_t address, uint16_t port)
234fc2df
PF
202{
203 return 0;
204}
205
080ab276 206int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port,
234fc2df
PF
207 const void *packet, size_t len)
208{
209 return 0;
210}
211
d3d8ac2f 212static void test_discover_message(sd_event *e)
290c7324
PF
213{
214 sd_dhcp_client *client;
b25ef18b 215 int res, r;
290c7324 216
ede286f9
PF
217 if (verbose)
218 printf("* %s\n", __FUNCTION__);
219
b25ef18b
TG
220 r = sd_dhcp_client_new(&client);
221 assert(r >= 0);
290c7324
PF
222 assert(client);
223
b25ef18b
TG
224 r = sd_dhcp_client_attach_event(client, e, 0);
225 assert(r >= 0);
226
290c7324
PF
227 assert(sd_dhcp_client_set_index(client, 42) >= 0);
228 assert(sd_dhcp_client_set_mac(client, &mac_addr) >= 0);
229
230 assert(sd_dhcp_client_set_request_option(client, 248) >= 0);
231
232 res = sd_dhcp_client_start(client);
233
234 assert(res == 0 || res == -EINPROGRESS);
8c00042c
PF
235
236 close(test_fd[0]);
237 close(test_fd[1]);
290c7324
PF
238}
239
be391925
PF
240int main(int argc, char *argv[])
241{
d3d8ac2f
PF
242 sd_event *e;
243
244 assert(sd_event_new(&e) >= 0);
245
246 test_request_basic(e);
39b7f596 247 test_checksum();
be391925 248
d3d8ac2f
PF
249 test_discover_message(e);
250 sd_event_run(e, (uint64_t) -1);
290c7324 251
be391925
PF
252 return 0;
253}