1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 Copyright © 2014 Axis Communications AB. All rights reserved.
6 #include <netinet/if_ether.h>
10 #include "sd-ipv4ll.h"
14 #include "in-addr-util.h"
17 static bool verbose
= false;
18 static bool extended
= false;
19 static int test_fd
[2];
21 static int basic_request_handler_bind
= 0;
22 static int basic_request_handler_stop
= 0;
23 static void* basic_request_handler_userdata
= (void*) 0xCABCAB;
25 static void basic_request_handler(sd_ipv4ll
*ll
, int event
, void *userdata
) {
26 assert_se(userdata
== basic_request_handler_userdata
);
29 case SD_IPV4LL_EVENT_STOP
:
30 basic_request_handler_stop
= 1;
32 case SD_IPV4LL_EVENT_BIND
:
33 basic_request_handler_bind
= 1;
43 const struct in_addr
*pa
,
44 const struct ether_addr
*ha
,
47 struct ether_arp ea
= {};
50 assert_se(ifindex
> 0);
54 if (send(fd
, &ea
, sizeof(struct ether_arp
), 0) < 0)
60 int arp_update_filter(int fd
, const struct in_addr
*a
, const struct ether_addr
*eth_mac
) {
64 int arp_network_bind_raw_socket(int ifindex
, const struct in_addr
*a
, const struct ether_addr
*eth_mac
) {
65 if (socketpair(AF_UNIX
, SOCK_DGRAM
| SOCK_CLOEXEC
| SOCK_NONBLOCK
, 0, test_fd
) < 0)
71 static void test_public_api_setters(sd_event
*e
) {
72 struct in_addr address
= {};
75 struct ether_addr mac_addr
= {
76 .ether_addr_octet
= {'A', 'B', 'C', '1', '2', '3'}};
79 printf("* %s\n", __func__
);
81 assert_se(sd_ipv4ll_new(&ll
) == 0);
84 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_attach_event(NULL
, NULL
, 0) == -EINVAL
);
85 assert_se(sd_ipv4ll_attach_event(ll
, e
, 0) == 0);
86 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_attach_event(ll
, e
, 0) == -EBUSY
);
88 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_set_callback(NULL
, NULL
, NULL
) == -EINVAL
);
89 assert_se(sd_ipv4ll_set_callback(ll
, NULL
, NULL
) == 0);
91 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_set_address(ll
, &address
) == -EINVAL
);
92 address
.s_addr
|= htobe32(169U << 24 | 254U << 16);
93 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_set_address(ll
, &address
) == -EINVAL
);
94 address
.s_addr
|= htobe32(0x00FF);
95 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_set_address(ll
, &address
) == -EINVAL
);
96 address
.s_addr
|= htobe32(0xF000);
97 assert_se(sd_ipv4ll_set_address(ll
, &address
) == 0);
98 address
.s_addr
|= htobe32(0x0F00);
99 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_set_address(ll
, &address
) == -EINVAL
);
101 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_set_address_seed(NULL
, seed
) == -EINVAL
);
102 assert_se(sd_ipv4ll_set_address_seed(ll
, seed
) == 0);
104 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_set_mac(NULL
, NULL
) == -EINVAL
);
106 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_set_mac(ll
, NULL
) == -EINVAL
);
107 assert_se(sd_ipv4ll_set_mac(ll
, &mac_addr
) == 0);
109 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_set_ifindex(NULL
, -1) == -EINVAL
);
110 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_set_ifindex(ll
, -1) == -EINVAL
);
111 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_set_ifindex(ll
, -99) == -EINVAL
);
112 assert_se(sd_ipv4ll_set_ifindex(ll
, 1) == 0);
114 assert_se(sd_ipv4ll_ref(ll
) == ll
);
115 assert_se(sd_ipv4ll_unref(ll
) == NULL
);
118 assert_se(sd_ipv4ll_unref(ll
) == NULL
);
121 static void test_basic_request(sd_event
*e
, const struct in_addr
*start_address
) {
124 struct ether_arp arp
;
125 struct ether_addr mac_addr
= {
126 .ether_addr_octet
= {'A', 'B', 'C', '1', '2', '3'}};
129 printf("* %s\n", __func__
);
131 assert_se(sd_ipv4ll_new(&ll
) == 0);
132 if (in4_addr_is_set(start_address
))
133 assert_se(sd_ipv4ll_set_address(ll
, start_address
) >= 0);
134 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_start(ll
) == -EINVAL
);
136 assert_se(sd_ipv4ll_attach_event(ll
, e
, 0) == 0);
137 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_start(ll
) == -EINVAL
);
139 assert_se(sd_ipv4ll_set_mac(ll
, &mac_addr
) == 0);
140 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_start(ll
) == -EINVAL
);
142 assert_se(sd_ipv4ll_set_callback(ll
, basic_request_handler
,
143 basic_request_handler_userdata
) == 0);
144 ASSERT_RETURN_EXPECTED_SE(sd_ipv4ll_start(ll
) == -EINVAL
);
146 assert_se(sd_ipv4ll_set_ifindex(ll
, 1) == 0);
147 assert_se(sd_ipv4ll_start(ll
) == 1);
149 sd_event_run(e
, UINT64_MAX
);
150 assert_se(sd_ipv4ll_start(ll
) == 0);
152 assert_se(sd_ipv4ll_is_running(ll
));
155 sd_event_run(e
, UINT64_MAX
);
156 assert_se(recv(test_fd
[1], &arp
, sizeof(struct ether_arp
), 0) == sizeof(struct ether_arp
));
160 sd_event_run(e
, UINT64_MAX
);
161 assert_se(recv(test_fd
[1], &arp
, sizeof(struct ether_arp
), 0) == sizeof(struct ether_arp
));
164 sd_event_run(e
, UINT64_MAX
);
165 assert_se(recv(test_fd
[1], &arp
, sizeof(struct ether_arp
), 0) == sizeof(struct ether_arp
));
167 sd_event_run(e
, UINT64_MAX
);
168 assert_se(basic_request_handler_bind
== 1);
170 if (in4_addr_is_set(start_address
)) {
171 struct in_addr address
;
173 assert_se(sd_ipv4ll_get_address(ll
, &address
) >= 0);
174 assert_se(start_address
->s_addr
== address
.s_addr
);
179 assert_se(basic_request_handler_stop
== 1);
182 assert_se(sd_ipv4ll_unref(ll
) == NULL
);
183 safe_close(test_fd
[1]);
186 int main(int argc
, char *argv
[]) {
187 struct in_addr start_address
= {};
188 _cleanup_(sd_event_unrefp
) sd_event
*e
= NULL
;
190 test_setup_logging(LOG_DEBUG
);
192 assert_se(sd_event_new(&e
) >= 0);
194 test_public_api_setters(e
);
195 test_basic_request(e
, &start_address
);
197 basic_request_handler_bind
= 0;
198 basic_request_handler_stop
= 0;
199 start_address
.s_addr
= htobe32(169U << 24 | 254U << 16 | 1U << 8 | 2U);
200 test_basic_request(e
, &start_address
);