2 This file is part of systemd.
4 Copyright (C) 2014 Axis Communications AB. All rights reserved.
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/socket.h>
24 #include <sys/types.h>
27 #include "sd-ipv4ll.h"
31 #include "socket-util.h"
34 static bool verbose
= false;
35 static bool extended
= false;
36 static int test_fd
[2];
38 static int basic_request_handler_bind
= 0;
39 static int basic_request_handler_stop
= 0;
40 static void* basic_request_handler_userdata
= (void*) 0xCABCAB;
42 static void basic_request_handler(sd_ipv4ll
*ll
, int event
, void *userdata
) {
43 assert_se(userdata
== basic_request_handler_userdata
);
46 case SD_IPV4LL_EVENT_STOP
:
47 basic_request_handler_stop
= 1;
49 case SD_IPV4LL_EVENT_BIND
:
50 basic_request_handler_bind
= 1;
58 static int arp_network_send_raw_socket(int fd
, int ifindex
,
59 const struct ether_arp
*arp
) {
61 assert_se(ifindex
> 0);
64 if (send(fd
, arp
, sizeof(struct ether_arp
), 0) < 0)
70 int arp_send_probe(int fd
, int ifindex
,
71 be32_t pa
, const struct ether_addr
*ha
) {
72 struct ether_arp ea
= {};
75 assert_se(ifindex
> 0);
79 return arp_network_send_raw_socket(fd
, ifindex
, &ea
);
82 int arp_send_announcement(int fd
, int ifindex
,
83 be32_t pa
, const struct ether_addr
*ha
) {
84 struct ether_arp ea
= {};
87 assert_se(ifindex
> 0);
91 return arp_network_send_raw_socket(fd
, ifindex
, &ea
);
94 int arp_network_bind_raw_socket(int index
, be32_t address
, const struct ether_addr
*eth_mac
) {
95 if (socketpair(AF_UNIX
, SOCK_DGRAM
| SOCK_NONBLOCK
, 0, test_fd
) < 0)
101 static void test_public_api_setters(sd_event
*e
) {
102 struct in_addr address
= {};
105 struct ether_addr mac_addr
= {
106 .ether_addr_octet
= {'A', 'B', 'C', '1', '2', '3'}};
109 printf("* %s\n", __FUNCTION__
);
111 assert_se(sd_ipv4ll_new(&ll
) == 0);
114 assert_se(sd_ipv4ll_attach_event(NULL
, NULL
, 0) == -EINVAL
);
115 assert_se(sd_ipv4ll_attach_event(ll
, e
, 0) == 0);
116 assert_se(sd_ipv4ll_attach_event(ll
, e
, 0) == -EBUSY
);
118 assert_se(sd_ipv4ll_set_callback(NULL
, NULL
, NULL
) == -EINVAL
);
119 assert_se(sd_ipv4ll_set_callback(ll
, NULL
, NULL
) == 0);
121 assert_se(sd_ipv4ll_set_address(ll
, &address
) == -EINVAL
);
122 address
.s_addr
|= htobe32(169U << 24 | 254U << 16);
123 assert_se(sd_ipv4ll_set_address(ll
, &address
) == -EINVAL
);
124 address
.s_addr
|= htobe32(0x00FF);
125 assert_se(sd_ipv4ll_set_address(ll
, &address
) == -EINVAL
);
126 address
.s_addr
|= htobe32(0xF000);
127 assert_se(sd_ipv4ll_set_address(ll
, &address
) == 0);
128 address
.s_addr
|= htobe32(0x0F00);
129 assert_se(sd_ipv4ll_set_address(ll
, &address
) == -EINVAL
);
131 assert_se(sd_ipv4ll_set_address_seed(NULL
, seed
) == -EINVAL
);
132 assert_se(sd_ipv4ll_set_address_seed(ll
, seed
) == 0);
134 assert_se(sd_ipv4ll_set_mac(NULL
, NULL
) == -EINVAL
);
135 assert_se(sd_ipv4ll_set_mac(ll
, NULL
) == -EINVAL
);
136 assert_se(sd_ipv4ll_set_mac(ll
, &mac_addr
) == 0);
138 assert_se(sd_ipv4ll_set_ifindex(NULL
, -1) == -EINVAL
);
139 assert_se(sd_ipv4ll_set_ifindex(ll
, -1) == -EINVAL
);
140 assert_se(sd_ipv4ll_set_ifindex(ll
, -99) == -EINVAL
);
141 assert_se(sd_ipv4ll_set_ifindex(ll
, 1) == 0);
142 assert_se(sd_ipv4ll_set_ifindex(ll
, 99) == 0);
144 assert_se(sd_ipv4ll_ref(ll
) == ll
);
145 assert_se(sd_ipv4ll_unref(ll
) == NULL
);
148 assert_se(sd_ipv4ll_unref(ll
) == NULL
);
151 static void test_basic_request(sd_event
*e
) {
154 struct ether_arp arp
;
155 struct ether_addr mac_addr
= {
156 .ether_addr_octet
= {'A', 'B', 'C', '1', '2', '3'}};
159 printf("* %s\n", __FUNCTION__
);
161 assert_se(sd_ipv4ll_new(&ll
) == 0);
162 assert_se(sd_ipv4ll_start(ll
) == -EINVAL
);
164 assert_se(sd_ipv4ll_attach_event(ll
, e
, 0) == 0);
165 assert_se(sd_ipv4ll_start(ll
) == -EINVAL
);
167 assert_se(sd_ipv4ll_set_mac(ll
, &mac_addr
) == 0);
168 assert_se(sd_ipv4ll_start(ll
) == -EINVAL
);
170 assert_se(sd_ipv4ll_set_callback(ll
, basic_request_handler
,
171 basic_request_handler_userdata
) == 0);
172 assert_se(sd_ipv4ll_start(ll
) == -EINVAL
);
174 assert_se(sd_ipv4ll_set_ifindex(ll
, 1) == 0);
175 assert_se(sd_ipv4ll_start(ll
) == 0);
177 sd_event_run(e
, (uint64_t) -1);
178 assert_se(sd_ipv4ll_start(ll
) == -EBUSY
);
180 assert_se(sd_ipv4ll_is_running(ll
));
183 sd_event_run(e
, (uint64_t) -1);
184 assert_se(recv(test_fd
[1], &arp
, sizeof(struct ether_arp
), 0) == sizeof(struct ether_arp
));
188 sd_event_run(e
, (uint64_t) -1);
189 assert_se(recv(test_fd
[1], &arp
, sizeof(struct ether_arp
), 0) == sizeof(struct ether_arp
));
192 sd_event_run(e
, (uint64_t) -1);
193 assert_se(recv(test_fd
[1], &arp
, sizeof(struct ether_arp
), 0) == sizeof(struct ether_arp
));
195 sd_event_run(e
, (uint64_t) -1);
196 assert_se(basic_request_handler_bind
== 1);
200 assert_se(basic_request_handler_stop
== 1);
203 assert_se(sd_ipv4ll_unref(ll
) == NULL
);
204 safe_close(test_fd
[1]);
207 int main(int argc
, char *argv
[]) {
208 _cleanup_(sd_event_unrefp
) sd_event
*e
= NULL
;
210 log_set_max_level(LOG_DEBUG
);
211 log_parse_environment();
214 assert_se(sd_event_new(&e
) >= 0);
216 test_public_api_setters(e
);
217 test_basic_request(e
);