Branch data Line data Source code
1 : : /* SPDX-License-Identifier: LGPL-2.1+ */
2 : : /***
3 : : Copyright © 2014 Axis Communications AB. All rights reserved.
4 : : ***/
5 : :
6 : : #include <errno.h>
7 : : #include <netinet/if_ether.h>
8 : : #include <stdio.h>
9 : : #include <stdlib.h>
10 : : #include <sys/socket.h>
11 : : #include <sys/types.h>
12 : : #include <unistd.h>
13 : :
14 : : #include "sd-ipv4ll.h"
15 : :
16 : : #include "arp-util.h"
17 : : #include "fd-util.h"
18 : : #include "socket-util.h"
19 : : #include "tests.h"
20 : : #include "util.h"
21 : :
22 : : static bool verbose = false;
23 : : static bool extended = false;
24 : : static int test_fd[2];
25 : :
26 : : static int basic_request_handler_bind = 0;
27 : : static int basic_request_handler_stop = 0;
28 : : static void* basic_request_handler_userdata = (void*) 0xCABCAB;
29 : :
30 : 4 : static void basic_request_handler(sd_ipv4ll *ll, int event, void *userdata) {
31 [ - + ]: 4 : assert_se(userdata == basic_request_handler_userdata);
32 : :
33 [ + - - ]: 4 : switch(event) {
34 : 4 : case SD_IPV4LL_EVENT_STOP:
35 : 4 : basic_request_handler_stop = 1;
36 : 4 : break;
37 : 0 : case SD_IPV4LL_EVENT_BIND:
38 : 0 : basic_request_handler_bind = 1;
39 : 0 : break;
40 : 0 : default:
41 : 0 : assert_se(0);
42 : : break;
43 : : }
44 : 4 : }
45 : :
46 : 4 : static int arp_network_send_raw_socket(int fd, int ifindex,
47 : : const struct ether_arp *arp) {
48 [ - + ]: 4 : assert_se(arp);
49 [ - + ]: 4 : assert_se(ifindex > 0);
50 [ - + ]: 4 : assert_se(fd >= 0);
51 : :
52 [ - + ]: 4 : if (send(fd, arp, sizeof(struct ether_arp), 0) < 0)
53 : 0 : return -errno;
54 : :
55 : 4 : return 0;
56 : : }
57 : :
58 : 4 : int arp_send_probe(int fd, int ifindex,
59 : : be32_t pa, const struct ether_addr *ha) {
60 : 4 : struct ether_arp ea = {};
61 : :
62 [ - + ]: 4 : assert_se(fd >= 0);
63 [ - + ]: 4 : assert_se(ifindex > 0);
64 [ - + ]: 4 : assert_se(pa != 0);
65 [ - + ]: 4 : assert_se(ha);
66 : :
67 : 4 : return arp_network_send_raw_socket(fd, ifindex, &ea);
68 : : }
69 : :
70 : 0 : int arp_send_announcement(int fd, int ifindex,
71 : : be32_t pa, const struct ether_addr *ha) {
72 : 0 : struct ether_arp ea = {};
73 : :
74 [ # # ]: 0 : assert_se(fd >= 0);
75 [ # # ]: 0 : assert_se(ifindex > 0);
76 [ # # ]: 0 : assert_se(pa != 0);
77 [ # # ]: 0 : assert_se(ha);
78 : :
79 : 0 : return arp_network_send_raw_socket(fd, ifindex, &ea);
80 : : }
81 : :
82 : 4 : int arp_network_bind_raw_socket(int index, be32_t address, const struct ether_addr *eth_mac) {
83 [ - + ]: 4 : if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) < 0)
84 : 0 : return -errno;
85 : :
86 : 4 : return test_fd[0];
87 : : }
88 : :
89 : 4 : static void test_public_api_setters(sd_event *e) {
90 : 4 : struct in_addr address = {};
91 : 4 : uint64_t seed = 0;
92 : : sd_ipv4ll *ll;
93 : 4 : struct ether_addr mac_addr = {
94 : : .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
95 : :
96 [ - + ]: 4 : if (verbose)
97 : 0 : printf("* %s\n", __FUNCTION__);
98 : :
99 [ - + ]: 4 : assert_se(sd_ipv4ll_new(&ll) == 0);
100 [ - + ]: 4 : assert_se(ll);
101 : :
102 [ - + ]: 4 : assert_se(sd_ipv4ll_attach_event(NULL, NULL, 0) == -EINVAL);
103 [ - + ]: 4 : assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
104 [ - + ]: 4 : assert_se(sd_ipv4ll_attach_event(ll, e, 0) == -EBUSY);
105 : :
106 [ - + ]: 4 : assert_se(sd_ipv4ll_set_callback(NULL, NULL, NULL) == -EINVAL);
107 [ - + ]: 4 : assert_se(sd_ipv4ll_set_callback(ll, NULL, NULL) == 0);
108 : :
109 [ - + ]: 4 : assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);
110 : 4 : address.s_addr |= htobe32(169U << 24 | 254U << 16);
111 [ - + ]: 4 : assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);
112 : 4 : address.s_addr |= htobe32(0x00FF);
113 [ - + ]: 4 : assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);
114 : 4 : address.s_addr |= htobe32(0xF000);
115 [ - + ]: 4 : assert_se(sd_ipv4ll_set_address(ll, &address) == 0);
116 : 4 : address.s_addr |= htobe32(0x0F00);
117 [ - + ]: 4 : assert_se(sd_ipv4ll_set_address(ll, &address) == -EINVAL);
118 : :
119 [ - + ]: 4 : assert_se(sd_ipv4ll_set_address_seed(NULL, seed) == -EINVAL);
120 [ - + ]: 4 : assert_se(sd_ipv4ll_set_address_seed(ll, seed) == 0);
121 : :
122 [ - + ]: 4 : assert_se(sd_ipv4ll_set_mac(NULL, NULL) == -EINVAL);
123 [ - + ]: 4 : assert_se(sd_ipv4ll_set_mac(ll, NULL) == -EINVAL);
124 [ - + ]: 4 : assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
125 : :
126 [ - + ]: 4 : assert_se(sd_ipv4ll_set_ifindex(NULL, -1) == -EINVAL);
127 [ - + ]: 4 : assert_se(sd_ipv4ll_set_ifindex(ll, -1) == -EINVAL);
128 [ - + ]: 4 : assert_se(sd_ipv4ll_set_ifindex(ll, -99) == -EINVAL);
129 [ - + ]: 4 : assert_se(sd_ipv4ll_set_ifindex(ll, 1) == 0);
130 [ - + ]: 4 : assert_se(sd_ipv4ll_set_ifindex(ll, 99) == 0);
131 : :
132 [ - + ]: 4 : assert_se(sd_ipv4ll_ref(ll) == ll);
133 [ - + ]: 4 : assert_se(sd_ipv4ll_unref(ll) == NULL);
134 : :
135 : : /* Cleanup */
136 [ - + ]: 4 : assert_se(sd_ipv4ll_unref(ll) == NULL);
137 : 4 : }
138 : :
139 : 4 : static void test_basic_request(sd_event *e) {
140 : :
141 : : sd_ipv4ll *ll;
142 : : struct ether_arp arp;
143 : 4 : struct ether_addr mac_addr = {
144 : : .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
145 : :
146 [ - + ]: 4 : if (verbose)
147 : 0 : printf("* %s\n", __FUNCTION__);
148 : :
149 [ - + ]: 4 : assert_se(sd_ipv4ll_new(&ll) == 0);
150 [ - + ]: 4 : assert_se(sd_ipv4ll_start(ll) == -EINVAL);
151 : :
152 [ - + ]: 4 : assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
153 [ - + ]: 4 : assert_se(sd_ipv4ll_start(ll) == -EINVAL);
154 : :
155 [ - + ]: 4 : assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
156 [ - + ]: 4 : assert_se(sd_ipv4ll_start(ll) == -EINVAL);
157 : :
158 [ - + ]: 4 : assert_se(sd_ipv4ll_set_callback(ll, basic_request_handler,
159 : : basic_request_handler_userdata) == 0);
160 [ - + ]: 4 : assert_se(sd_ipv4ll_start(ll) == -EINVAL);
161 : :
162 [ - + ]: 4 : assert_se(sd_ipv4ll_set_ifindex(ll, 1) == 0);
163 [ - + ]: 4 : assert_se(sd_ipv4ll_start(ll) == 0);
164 : :
165 : 4 : sd_event_run(e, (uint64_t) -1);
166 [ - + ]: 4 : assert_se(sd_ipv4ll_start(ll) == -EBUSY);
167 : :
168 [ - + ]: 4 : assert_se(sd_ipv4ll_is_running(ll));
169 : :
170 : : /* PROBE */
171 : 4 : sd_event_run(e, (uint64_t) -1);
172 [ - + ]: 4 : assert_se(recv(test_fd[1], &arp, sizeof(struct ether_arp), 0) == sizeof(struct ether_arp));
173 : :
174 [ - + ]: 4 : if (extended) {
175 : : /* PROBE */
176 : 0 : sd_event_run(e, (uint64_t) -1);
177 [ # # ]: 0 : assert_se(recv(test_fd[1], &arp, sizeof(struct ether_arp), 0) == sizeof(struct ether_arp));
178 : :
179 : : /* PROBE */
180 : 0 : sd_event_run(e, (uint64_t) -1);
181 [ # # ]: 0 : assert_se(recv(test_fd[1], &arp, sizeof(struct ether_arp), 0) == sizeof(struct ether_arp));
182 : :
183 : 0 : sd_event_run(e, (uint64_t) -1);
184 [ # # ]: 0 : assert_se(basic_request_handler_bind == 1);
185 : : }
186 : :
187 : 4 : sd_ipv4ll_stop(ll);
188 [ - + ]: 4 : assert_se(basic_request_handler_stop == 1);
189 : :
190 : : /* Cleanup */
191 [ - + ]: 4 : assert_se(sd_ipv4ll_unref(ll) == NULL);
192 : 4 : safe_close(test_fd[1]);
193 : 4 : }
194 : :
195 : 4 : int main(int argc, char *argv[]) {
196 : 8 : _cleanup_(sd_event_unrefp) sd_event *e = NULL;
197 : :
198 : 4 : test_setup_logging(LOG_DEBUG);
199 : :
200 [ - + ]: 4 : assert_se(sd_event_new(&e) >= 0);
201 : :
202 : 4 : test_public_api_setters(e);
203 : 4 : test_basic_request(e);
204 : :
205 : 4 : return 0;
206 : : }
|