]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-network/test-ipv4ll.c
sd-ipv4ll: simplify conflict handling
[thirdparty/systemd.git] / src / libsystemd-network / test-ipv4ll.c
CommitLineData
d9bf4f8c
UTL
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2/***
3 This file is part of systemd.
4
5 Copyright (C) 2014 Axis Communications AB. All rights reserved.
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
20
21#include <stdlib.h>
22#include <assert.h>
23#include <errno.h>
24#include <stdio.h>
25#include <sys/types.h>
26#include <sys/socket.h>
27#include <unistd.h>
28
29#include "util.h"
30#include "socket-util.h"
a64edefa 31#include "event-util.h"
d9bf4f8c
UTL
32
33#include "sd-ipv4ll.h"
996d1697 34#include "arp-util.h"
d9bf4f8c
UTL
35
36static bool verbose = false;
37static bool extended = false;
38static int test_fd[2];
39
40static int basic_request_handler_bind = 0;
41static int basic_request_handler_stop = 0;
89ca10c6 42static void* basic_request_handler_userdata = (void*)0xCABCAB;
d9bf4f8c 43static void basic_request_handler(sd_ipv4ll *ll, int event, void *userdata) {
89ca10c6 44 assert_se(userdata == basic_request_handler_userdata);
d9bf4f8c
UTL
45
46 switch(event) {
47 case IPV4LL_EVENT_STOP:
48 basic_request_handler_stop = 1;
49 break;
50 case IPV4LL_EVENT_BIND:
51 basic_request_handler_bind = 1;
52 break;
53 default:
54 assert_se(0);
55 break;
56 }
57}
58
996d1697
TG
59static int arp_network_send_raw_socket(int fd, int ifindex,
60 const struct ether_arp *arp) {
d9bf4f8c 61 assert_se(arp);
996d1697 62 assert_se(ifindex > 0);
d9bf4f8c
UTL
63 assert_se(fd >= 0);
64
65 if (send(fd, arp, sizeof(struct ether_arp), 0) < 0)
66 return -errno;
67
68 return 0;
69}
70
996d1697
TG
71int arp_send_probe(int fd, int ifindex,
72 be32_t pa, const struct ether_addr *ha) {
73 struct ether_arp ea = {};
d9bf4f8c 74
996d1697
TG
75 assert(fd >= 0);
76 assert(ifindex > 0);
77 assert(pa != 0);
78 assert(ha);
d9bf4f8c 79
996d1697 80 return arp_network_send_raw_socket(fd, ifindex, &ea);
d9bf4f8c
UTL
81}
82
996d1697
TG
83int arp_send_announcement(int fd, int ifindex,
84 be32_t pa, const struct ether_addr *ha) {
85 struct ether_arp ea = {};
d9bf4f8c 86
996d1697
TG
87 assert(fd >= 0);
88 assert(ifindex > 0);
89 assert(pa != 0);
90 assert(ha);
d9bf4f8c 91
996d1697 92 return arp_network_send_raw_socket(fd, ifindex, &ea);
d9bf4f8c
UTL
93}
94
996d1697
TG
95int arp_network_bind_raw_socket(int index, be32_t address, const struct ether_addr *eth_mac) {
96 if (socketpair(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0, test_fd) < 0)
97 return -errno;
d9bf4f8c 98
996d1697 99 return test_fd[0];
d9bf4f8c
UTL
100}
101
102static void test_public_api_setters(sd_event *e) {
103 uint8_t seed[8];
104 sd_ipv4ll *ll;
105 struct ether_addr mac_addr = {
106 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
107
108 if (verbose)
109 printf("* %s\n", __FUNCTION__);
110
111 assert_se(sd_ipv4ll_new(&ll) == 0);
112 assert_se(ll);
113
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);
117
118 assert_se(sd_ipv4ll_set_callback(NULL, NULL, NULL) == -EINVAL);
119 assert_se(sd_ipv4ll_set_callback(ll, NULL, NULL) == 0);
120
121 assert_se(sd_ipv4ll_set_address_seed(NULL, NULL) == -EINVAL);
122 assert_se(sd_ipv4ll_set_address_seed(ll, NULL) == -EINVAL);
123 assert_se(sd_ipv4ll_set_address_seed(ll, seed) == 0);
124
125 assert_se(sd_ipv4ll_set_mac(NULL, NULL) == -EINVAL);
126 assert_se(sd_ipv4ll_set_mac(ll, NULL) == -EINVAL);
127 assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
128
129 assert_se(sd_ipv4ll_set_index(NULL, -1) == -EINVAL);
130 assert_se(sd_ipv4ll_set_index(ll, -1) == -EINVAL);
131 assert_se(sd_ipv4ll_set_index(ll, -99) == -EINVAL);
132 assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
133 assert_se(sd_ipv4ll_set_index(ll, 99) == 0);
134
135 assert_se(sd_ipv4ll_ref(ll) == ll);
b45e4eb6 136 assert_se(sd_ipv4ll_unref(ll) == NULL);
d9bf4f8c
UTL
137
138 /* Cleanup */
139 assert_se(sd_ipv4ll_unref(ll) == NULL);
140}
141
142static void test_basic_request(sd_event *e) {
143
144 sd_ipv4ll *ll;
145 struct ether_arp arp;
146 struct ether_addr mac_addr = {
147 .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'}};
148
149 if (verbose)
150 printf("* %s\n", __FUNCTION__);
151
152 assert_se(sd_ipv4ll_new(&ll) == 0);
153 assert_se(sd_ipv4ll_start(ll) == -EINVAL);
154
155 assert_se(sd_ipv4ll_attach_event(ll, e, 0) == 0);
156 assert_se(sd_ipv4ll_start(ll) == -EINVAL);
157
158 assert_se(sd_ipv4ll_set_mac(ll, &mac_addr) == 0);
159 assert_se(sd_ipv4ll_start(ll) == -EINVAL);
160
161 assert_se(sd_ipv4ll_set_callback(ll, basic_request_handler,
89ca10c6 162 basic_request_handler_userdata) == 0);
d9bf4f8c
UTL
163 assert_se(sd_ipv4ll_start(ll) == -EINVAL);
164
165 assert_se(sd_ipv4ll_set_index(ll, 1) == 0);
166 assert_se(sd_ipv4ll_start(ll) == 0);
167
168 sd_event_run(e, (uint64_t) -1);
169 assert_se(sd_ipv4ll_start(ll) == -EBUSY);
170
171 /* PROBE */
172 sd_event_run(e, (uint64_t) -1);
173 assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
d9bf4f8c
UTL
174
175 if (extended) {
176 /* PROBE */
177 sd_event_run(e, (uint64_t) -1);
178 assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
d9bf4f8c
UTL
179
180 /* PROBE */
181 sd_event_run(e, (uint64_t) -1);
182 assert_se(read(test_fd[1], &arp, sizeof(struct ether_arp)) == sizeof(struct ether_arp));
d9bf4f8c
UTL
183
184 sd_event_run(e, (uint64_t) -1);
185 assert_se(basic_request_handler_bind == 1);
186 }
187
188 sd_ipv4ll_stop(ll);
189 assert_se(basic_request_handler_stop == 1);
190
191 /* Cleanup */
192 assert_se(sd_ipv4ll_unref(ll) == NULL);
193 safe_close(test_fd[1]);
194}
195
196int main(int argc, char *argv[]) {
a64edefa 197 _cleanup_event_unref_ sd_event *e = NULL;
d9bf4f8c
UTL
198
199 assert_se(sd_event_new(&e) >= 0);
200
201 test_public_api_setters(e);
d9bf4f8c
UTL
202 test_basic_request(e);
203
204 return 0;
205}